aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/radeon
diff options
context:
space:
mode:
authorAlex Deucher <alexander.deucher@amd.com>2012-06-28 17:53:07 -0400
committerDave Airlie <airlied@redhat.com>2012-06-29 10:13:07 -0400
commitc21b328ea8c7c71cd2daf50557db440bbaa7ef55 (patch)
tree3213564dfdc84546c4bc772e9d9865f8bdfefbee /drivers/gpu/drm/radeon
parent9acc7bde23ebb19a704395f76490685e1513e422 (diff)
drm/radeon: fix VM page table setup on SI
Cayman and trinity allow for variable sized VM page tables, but SI requires that all page tables be the same size. The current code assumes variablely sized VM page tables so SI may end up with part of each page table overlapping with other memory which could end up being interpreted by the VM hw as garbage. Change the code to better accomodate SI. Allocate enough space for at least 2 full page tables and always set last_pfn to max_pfn on SI so each VM is backed by a full page table. This limits us to only 2 VMs active at any given time on SI. This will be rectified and the code can be reunified once we move to two level page tables. Signed-off-by: Alex Deucher <alexander.deucher@amd.com> Reviewed-by: Jerome Glisse <jglisse@redhat.com> Cc: stable@vger.kernel.org Signed-off-by: Dave Airlie <airlied@redhat.com>
Diffstat (limited to 'drivers/gpu/drm/radeon')
-rw-r--r--drivers/gpu/drm/radeon/radeon_gart.c13
-rw-r--r--drivers/gpu/drm/radeon/si.c4
2 files changed, 13 insertions, 4 deletions
diff --git a/drivers/gpu/drm/radeon/radeon_gart.c b/drivers/gpu/drm/radeon/radeon_gart.c
index 59d44937dd9f..84b648a7ddd8 100644
--- a/drivers/gpu/drm/radeon/radeon_gart.c
+++ b/drivers/gpu/drm/radeon/radeon_gart.c
@@ -289,8 +289,9 @@ int radeon_vm_manager_init(struct radeon_device *rdev)
289 rdev->vm_manager.enabled = false; 289 rdev->vm_manager.enabled = false;
290 290
291 /* mark first vm as always in use, it's the system one */ 291 /* mark first vm as always in use, it's the system one */
292 /* allocate enough for 2 full VM pts */
292 r = radeon_sa_bo_manager_init(rdev, &rdev->vm_manager.sa_manager, 293 r = radeon_sa_bo_manager_init(rdev, &rdev->vm_manager.sa_manager,
293 rdev->vm_manager.max_pfn * 8, 294 rdev->vm_manager.max_pfn * 8 * 2,
294 RADEON_GEM_DOMAIN_VRAM); 295 RADEON_GEM_DOMAIN_VRAM);
295 if (r) { 296 if (r) {
296 dev_err(rdev->dev, "failed to allocate vm bo (%dKB)\n", 297 dev_err(rdev->dev, "failed to allocate vm bo (%dKB)\n",
@@ -633,7 +634,15 @@ int radeon_vm_init(struct radeon_device *rdev, struct radeon_vm *vm)
633 mutex_init(&vm->mutex); 634 mutex_init(&vm->mutex);
634 INIT_LIST_HEAD(&vm->list); 635 INIT_LIST_HEAD(&vm->list);
635 INIT_LIST_HEAD(&vm->va); 636 INIT_LIST_HEAD(&vm->va);
636 vm->last_pfn = 0; 637 /* SI requires equal sized PTs for all VMs, so always set
638 * last_pfn to max_pfn. cayman allows variable sized
639 * pts so we can grow then as needed. Once we switch
640 * to two level pts we can unify this again.
641 */
642 if (rdev->family >= CHIP_TAHITI)
643 vm->last_pfn = rdev->vm_manager.max_pfn;
644 else
645 vm->last_pfn = 0;
637 /* map the ib pool buffer at 0 in virtual address space, set 646 /* map the ib pool buffer at 0 in virtual address space, set
638 * read only 647 * read only
639 */ 648 */
diff --git a/drivers/gpu/drm/radeon/si.c b/drivers/gpu/drm/radeon/si.c
index c7b61f16ecfd..0b0279291a73 100644
--- a/drivers/gpu/drm/radeon/si.c
+++ b/drivers/gpu/drm/radeon/si.c
@@ -2365,12 +2365,12 @@ int si_pcie_gart_enable(struct radeon_device *rdev)
2365 WREG32(0x15DC, 0); 2365 WREG32(0x15DC, 0);
2366 2366
2367 /* empty context1-15 */ 2367 /* empty context1-15 */
2368 /* FIXME start with 1G, once using 2 level pt switch to full 2368 /* FIXME start with 4G, once using 2 level pt switch to full
2369 * vm size space 2369 * vm size space
2370 */ 2370 */
2371 /* set vm size, must be a multiple of 4 */ 2371 /* set vm size, must be a multiple of 4 */
2372 WREG32(VM_CONTEXT1_PAGE_TABLE_START_ADDR, 0); 2372 WREG32(VM_CONTEXT1_PAGE_TABLE_START_ADDR, 0);
2373 WREG32(VM_CONTEXT1_PAGE_TABLE_END_ADDR, (1 << 30) / RADEON_GPU_PAGE_SIZE); 2373 WREG32(VM_CONTEXT1_PAGE_TABLE_END_ADDR, rdev->vm_manager.max_pfn);
2374 for (i = 1; i < 16; i++) { 2374 for (i = 1; i < 16; i++) {
2375 if (i < 8) 2375 if (i < 8)
2376 WREG32(VM_CONTEXT0_PAGE_TABLE_BASE_ADDR + (i << 2), 2376 WREG32(VM_CONTEXT0_PAGE_TABLE_BASE_ADDR + (i << 2),