/* * Copyright 2009 Jerome Glisse. * All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including * without limitation the rights to use, copy, modify, merge, publish, * distribute, sub license, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE * USE OR OTHER DEALINGS IN THE SOFTWARE. * * The above copyright notice and this permission notice (including the * next paragraph) shall be included in all copies or substantial portions * of the Software. *
*/ /* * Authors: * Jerome Glisse <glisse@freedesktop.org> * Thomas Hellstrom <thomas-at-tungstengraphics-dot-com> * Dave Airlie
*/
/* Try evicting to the CPU inaccessible part of VRAM * first, but only set GTT as busy placement, so this * BO will be evicted to GTT rather than causing other * BOs to be evicted from VRAM
*/
radeon_ttm_placement_from_domain(rbo, RADEON_GEM_DOMAIN_VRAM |
RADEON_GEM_DOMAIN_GTT); for (i = 0; i < rbo->placement.num_placement; i++) { if (rbo->placements[i].mem_type == TTM_PL_VRAM) { if (rbo->placements[i].fpfn < fpfn)
rbo->placements[i].fpfn = fpfn;
rbo->placements[0].flags |= TTM_PL_FLAG_DESIRED;
}
}
} else
radeon_ttm_placement_from_domain(rbo, RADEON_GEM_DOMAIN_GTT); break; case TTM_PL_TT: default:
radeon_ttm_placement_from_domain(rbo, RADEON_GEM_DOMAIN_CPU);
}
*placement = rbo->placement;
}
switch (mem->mem_type) { case TTM_PL_SYSTEM: /* system memory */ return 0; case TTM_PL_TT: #if IS_ENABLED(CONFIG_AGP) if (rdev->flags & RADEON_IS_AGP) { /* RADEON_IS_AGP is set only if AGP is active */
mem->bus.offset = (mem->start << PAGE_SHIFT) +
rdev->mc.agp_base;
mem->bus.is_iomem = !rdev->agp->cant_use_aperture;
mem->bus.caching = ttm_write_combined;
} #endif break; case TTM_PL_VRAM:
mem->bus.offset = mem->start << PAGE_SHIFT; /* check if it's visible */ if ((mem->bus.offset + bus_size) > rdev->mc.visible_vram_size) return -EINVAL;
mem->bus.offset += rdev->mc.aper_base;
mem->bus.is_iomem = true;
mem->bus.caching = ttm_write_combined; #ifdef __alpha__ /* * Alpha: use bus.addr to hold the ioremap() return, * so we can modify bus.base below.
*/
mem->bus.addr = ioremap_wc(mem->bus.offset, bus_size); if (!mem->bus.addr) return -ENOMEM;
/* * Alpha: Use just the bus offset plus * the hose/domain memory base for bus.base. * It then can be used to build PTEs for VRAM * access, as done in ttm_bo_vm_fault().
*/
mem->bus.offset = (mem->bus.offset & 0x0ffffffffUL) +
rdev->hose->dense_mem_base; #endif break; default: return -EINVAL;
} return 0;
}
int radeon_ttm_init(struct radeon_device *rdev)
{ int r;
/* No others user of address space so set it to 0 */
r = ttm_device_init(&rdev->mman.bdev, &radeon_bo_driver, rdev->dev,
rdev_to_drm(rdev)->anon_inode->i_mapping,
rdev_to_drm(rdev)->vma_offset_manager,
rdev->need_swiotlb,
dma_addressing_limited(&rdev->pdev->dev)); if (r) {
DRM_ERROR("failed initializing buffer object driver(%d).\n", r); return r;
}
rdev->mman.initialized = true;
r = radeon_ttm_init_vram(rdev); if (r) {
DRM_ERROR("Failed initializing VRAM heap.\n"); return r;
} /* Change the size here instead of the init above so only lpfn is affected */
radeon_ttm_set_active_vram_size(rdev, rdev->mc.visible_vram_size);
r = radeon_bo_create(rdev, 256 * 1024, PAGE_SIZE, true,
RADEON_GEM_DOMAIN_VRAM, 0, NULL,
NULL, &rdev->stolen_vga_memory); if (r) { return r;
}
r = radeon_bo_reserve(rdev->stolen_vga_memory, false); if (r) return r;
r = radeon_bo_pin(rdev->stolen_vga_memory, RADEON_GEM_DOMAIN_VRAM, NULL);
radeon_bo_unreserve(rdev->stolen_vga_memory); if (r) {
radeon_bo_unref(&rdev->stolen_vga_memory); return r;
}
DRM_INFO("radeon: %uM of VRAM memory ready\n",
(unsigned) (rdev->mc.real_vram_size / (1024 * 1024)));
r = radeon_ttm_init_gtt(rdev); if (r) {
DRM_ERROR("Failed initializing GTT heap.\n"); return r;
}
DRM_INFO("radeon: %uM of GTT memory ready.\n",
(unsigned)(rdev->mc.gtt_size / (1024 * 1024)));
radeon_ttm_debugfs_init(rdev);
return 0;
}
void radeon_ttm_fini(struct radeon_device *rdev)
{ int r;
if (!rdev->mman.initialized) return;
if (rdev->stolen_vga_memory) {
r = radeon_bo_reserve(rdev->stolen_vga_memory, false); if (r == 0) {
radeon_bo_unpin(rdev->stolen_vga_memory);
radeon_bo_unreserve(rdev->stolen_vga_memory);
}
radeon_bo_unref(&rdev->stolen_vga_memory);
}
ttm_range_man_fini(&rdev->mman.bdev, TTM_PL_VRAM);
ttm_range_man_fini(&rdev->mman.bdev, TTM_PL_TT);
ttm_device_fini(&rdev->mman.bdev);
radeon_gart_fini(rdev);
rdev->mman.initialized = false;
DRM_INFO("radeon: ttm finalized\n");
}
/* this should only be called at bootup or when userspace
* isn't running */ void radeon_ttm_set_active_vram_size(struct radeon_device *rdev, u64 size)
{ struct ttm_resource_manager *man;
if (!rdev->mman.initialized) return;
man = ttm_manager_type(&rdev->mman.bdev, TTM_PL_VRAM); /* this just adjusts TTM size idea, which sets lpfn to the correct value */
man->size = size >> PAGE_SHIFT;
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.