aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/gpu/drm/radeon/radeon.h35
-rw-r--r--drivers/gpu/drm/radeon/radeon_asic.c50
-rw-r--r--drivers/gpu/drm/radeon/radeon_gart.c16
3 files changed, 54 insertions, 47 deletions
diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h
index a5470e793043..5f54b87b181a 100644
--- a/drivers/gpu/drm/radeon/radeon.h
+++ b/drivers/gpu/drm/radeon/radeon.h
@@ -641,28 +641,12 @@ struct radeon_vm {
641 struct radeon_fence *fence; 641 struct radeon_fence *fence;
642}; 642};
643 643
644struct radeon_vm_funcs {
645 int (*init)(struct radeon_device *rdev);
646 void (*fini)(struct radeon_device *rdev);
647 /* cs mutex must be lock for schedule_ib */
648 int (*bind)(struct radeon_device *rdev, struct radeon_vm *vm, int id);
649 void (*unbind)(struct radeon_device *rdev, struct radeon_vm *vm);
650 void (*tlb_flush)(struct radeon_device *rdev, struct radeon_vm *vm);
651 uint32_t (*page_flags)(struct radeon_device *rdev,
652 struct radeon_vm *vm,
653 uint32_t flags);
654 void (*set_page)(struct radeon_device *rdev, struct radeon_vm *vm,
655 unsigned pfn, uint64_t addr, uint32_t flags);
656};
657
658struct radeon_vm_manager { 644struct radeon_vm_manager {
659 struct mutex lock; 645 struct mutex lock;
660 struct list_head lru_vm; 646 struct list_head lru_vm;
661 uint32_t use_bitmap; 647 uint32_t use_bitmap;
662 struct radeon_sa_manager sa_manager; 648 struct radeon_sa_manager sa_manager;
663 uint32_t max_pfn; 649 uint32_t max_pfn;
664 /* fields constant after init */
665 const struct radeon_vm_funcs *funcs;
666 /* number of VMIDs */ 650 /* number of VMIDs */
667 unsigned nvm; 651 unsigned nvm;
668 /* vram base address for page table entry */ 652 /* vram base address for page table entry */
@@ -1128,6 +1112,18 @@ struct radeon_asic {
1128 void (*tlb_flush)(struct radeon_device *rdev); 1112 void (*tlb_flush)(struct radeon_device *rdev);
1129 int (*set_page)(struct radeon_device *rdev, int i, uint64_t addr); 1113 int (*set_page)(struct radeon_device *rdev, int i, uint64_t addr);
1130 } gart; 1114 } gart;
1115 struct {
1116 int (*init)(struct radeon_device *rdev);
1117 void (*fini)(struct radeon_device *rdev);
1118 int (*bind)(struct radeon_device *rdev, struct radeon_vm *vm, int id);
1119 void (*unbind)(struct radeon_device *rdev, struct radeon_vm *vm);
1120 void (*tlb_flush)(struct radeon_device *rdev, struct radeon_vm *vm);
1121 uint32_t (*page_flags)(struct radeon_device *rdev,
1122 struct radeon_vm *vm,
1123 uint32_t flags);
1124 void (*set_page)(struct radeon_device *rdev, struct radeon_vm *vm,
1125 unsigned pfn, uint64_t addr, uint32_t flags);
1126 } vm;
1131 /* ring specific callbacks */ 1127 /* ring specific callbacks */
1132 struct { 1128 struct {
1133 void (*ib_execute)(struct radeon_device *rdev, struct radeon_ib *ib); 1129 void (*ib_execute)(struct radeon_device *rdev, struct radeon_ib *ib);
@@ -1735,6 +1731,13 @@ void radeon_ring_write(struct radeon_ring *ring, uint32_t v);
1735#define radeon_asic_reset(rdev) (rdev)->asic->asic_reset((rdev)) 1731#define radeon_asic_reset(rdev) (rdev)->asic->asic_reset((rdev))
1736#define radeon_gart_tlb_flush(rdev) (rdev)->asic->gart.tlb_flush((rdev)) 1732#define radeon_gart_tlb_flush(rdev) (rdev)->asic->gart.tlb_flush((rdev))
1737#define radeon_gart_set_page(rdev, i, p) (rdev)->asic->gart.set_page((rdev), (i), (p)) 1733#define radeon_gart_set_page(rdev, i, p) (rdev)->asic->gart.set_page((rdev), (i), (p))
1734#define radeon_asic_vm_init(rdev) (rdev)->asic->vm.init((rdev))
1735#define radeon_asic_vm_fini(rdev) (rdev)->asic->vm.fini((rdev))
1736#define radeon_asic_vm_bind(rdev, v, id) (rdev)->asic->vm.bind((rdev), (v), (id))
1737#define radeon_asic_vm_unbind(rdev, v) (rdev)->asic->vm.unbind((rdev), (v))
1738#define radeon_asic_vm_tlb_flush(rdev, v) (rdev)->asic->vm.tlb_flush((rdev), (v))
1739#define radeon_asic_vm_page_flags(rdev, v, flags) (rdev)->asic->vm.page_flags((rdev), (v), (flags))
1740#define radeon_asic_vm_set_page(rdev, v, pfn, addr, flags) (rdev)->asic->vm.set_page((rdev), (v), (pfn), (addr), (flags))
1738#define radeon_ring_start(rdev, r, cp) (rdev)->asic->ring[(r)].ring_start((rdev), (cp)) 1741#define radeon_ring_start(rdev, r, cp) (rdev)->asic->ring[(r)].ring_start((rdev), (cp))
1739#define radeon_ring_test(rdev, r, cp) (rdev)->asic->ring[(r)].ring_test((rdev), (cp)) 1742#define radeon_ring_test(rdev, r, cp) (rdev)->asic->ring[(r)].ring_test((rdev), (cp))
1740#define radeon_ib_test(rdev, r, cp) (rdev)->asic->ring[(r)].ib_test((rdev), (cp)) 1743#define radeon_ib_test(rdev, r, cp) (rdev)->asic->ring[(r)].ib_test((rdev), (cp))
diff --git a/drivers/gpu/drm/radeon/radeon_asic.c b/drivers/gpu/drm/radeon/radeon_asic.c
index 29834a2be3ea..951194c1d0a8 100644
--- a/drivers/gpu/drm/radeon/radeon_asic.c
+++ b/drivers/gpu/drm/radeon/radeon_asic.c
@@ -1358,16 +1358,6 @@ static struct radeon_asic btc_asic = {
1358 }, 1358 },
1359}; 1359};
1360 1360
1361static const struct radeon_vm_funcs cayman_vm_funcs = {
1362 .init = &cayman_vm_init,
1363 .fini = &cayman_vm_fini,
1364 .bind = &cayman_vm_bind,
1365 .unbind = &cayman_vm_unbind,
1366 .tlb_flush = &cayman_vm_tlb_flush,
1367 .page_flags = &cayman_vm_page_flags,
1368 .set_page = &cayman_vm_set_page,
1369};
1370
1371static struct radeon_asic cayman_asic = { 1361static struct radeon_asic cayman_asic = {
1372 .init = &cayman_init, 1362 .init = &cayman_init,
1373 .fini = &cayman_fini, 1363 .fini = &cayman_fini,
@@ -1382,6 +1372,15 @@ static struct radeon_asic cayman_asic = {
1382 .tlb_flush = &cayman_pcie_gart_tlb_flush, 1372 .tlb_flush = &cayman_pcie_gart_tlb_flush,
1383 .set_page = &rs600_gart_set_page, 1373 .set_page = &rs600_gart_set_page,
1384 }, 1374 },
1375 .vm = {
1376 .init = &cayman_vm_init,
1377 .fini = &cayman_vm_fini,
1378 .bind = &cayman_vm_bind,
1379 .unbind = &cayman_vm_unbind,
1380 .tlb_flush = &cayman_vm_tlb_flush,
1381 .page_flags = &cayman_vm_page_flags,
1382 .set_page = &cayman_vm_set_page,
1383 },
1385 .ring = { 1384 .ring = {
1386 [RADEON_RING_TYPE_GFX_INDEX] = { 1385 [RADEON_RING_TYPE_GFX_INDEX] = {
1387 .ib_execute = &cayman_ring_ib_execute, 1386 .ib_execute = &cayman_ring_ib_execute,
@@ -1477,6 +1476,15 @@ static struct radeon_asic trinity_asic = {
1477 .tlb_flush = &cayman_pcie_gart_tlb_flush, 1476 .tlb_flush = &cayman_pcie_gart_tlb_flush,
1478 .set_page = &rs600_gart_set_page, 1477 .set_page = &rs600_gart_set_page,
1479 }, 1478 },
1479 .vm = {
1480 .init = &cayman_vm_init,
1481 .fini = &cayman_vm_fini,
1482 .bind = &cayman_vm_bind,
1483 .unbind = &cayman_vm_unbind,
1484 .tlb_flush = &cayman_vm_tlb_flush,
1485 .page_flags = &cayman_vm_page_flags,
1486 .set_page = &cayman_vm_set_page,
1487 },
1480 .ring = { 1488 .ring = {
1481 [RADEON_RING_TYPE_GFX_INDEX] = { 1489 [RADEON_RING_TYPE_GFX_INDEX] = {
1482 .ib_execute = &cayman_ring_ib_execute, 1490 .ib_execute = &cayman_ring_ib_execute,
@@ -1558,16 +1566,6 @@ static struct radeon_asic trinity_asic = {
1558 }, 1566 },
1559}; 1567};
1560 1568
1561static const struct radeon_vm_funcs si_vm_funcs = {
1562 .init = &si_vm_init,
1563 .fini = &si_vm_fini,
1564 .bind = &si_vm_bind,
1565 .unbind = &si_vm_unbind,
1566 .tlb_flush = &si_vm_tlb_flush,
1567 .page_flags = &cayman_vm_page_flags,
1568 .set_page = &cayman_vm_set_page,
1569};
1570
1571static struct radeon_asic si_asic = { 1569static struct radeon_asic si_asic = {
1572 .init = &si_init, 1570 .init = &si_init,
1573 .fini = &si_fini, 1571 .fini = &si_fini,
@@ -1582,6 +1580,15 @@ static struct radeon_asic si_asic = {
1582 .tlb_flush = &si_pcie_gart_tlb_flush, 1580 .tlb_flush = &si_pcie_gart_tlb_flush,
1583 .set_page = &rs600_gart_set_page, 1581 .set_page = &rs600_gart_set_page,
1584 }, 1582 },
1583 .vm = {
1584 .init = &si_vm_init,
1585 .fini = &si_vm_fini,
1586 .bind = &si_vm_bind,
1587 .unbind = &si_vm_unbind,
1588 .tlb_flush = &si_vm_tlb_flush,
1589 .page_flags = &cayman_vm_page_flags,
1590 .set_page = &cayman_vm_set_page,
1591 },
1585 .ring = { 1592 .ring = {
1586 [RADEON_RING_TYPE_GFX_INDEX] = { 1593 [RADEON_RING_TYPE_GFX_INDEX] = {
1587 .ib_execute = &si_ring_ib_execute, 1594 .ib_execute = &si_ring_ib_execute,
@@ -1789,13 +1796,11 @@ int radeon_asic_init(struct radeon_device *rdev)
1789 rdev->asic = &cayman_asic; 1796 rdev->asic = &cayman_asic;
1790 /* set num crtcs */ 1797 /* set num crtcs */
1791 rdev->num_crtc = 6; 1798 rdev->num_crtc = 6;
1792 rdev->vm_manager.funcs = &cayman_vm_funcs;
1793 break; 1799 break;
1794 case CHIP_ARUBA: 1800 case CHIP_ARUBA:
1795 rdev->asic = &trinity_asic; 1801 rdev->asic = &trinity_asic;
1796 /* set num crtcs */ 1802 /* set num crtcs */
1797 rdev->num_crtc = 4; 1803 rdev->num_crtc = 4;
1798 rdev->vm_manager.funcs = &cayman_vm_funcs;
1799 break; 1804 break;
1800 case CHIP_TAHITI: 1805 case CHIP_TAHITI:
1801 case CHIP_PITCAIRN: 1806 case CHIP_PITCAIRN:
@@ -1803,7 +1808,6 @@ int radeon_asic_init(struct radeon_device *rdev)
1803 rdev->asic = &si_asic; 1808 rdev->asic = &si_asic;
1804 /* set num crtcs */ 1809 /* set num crtcs */
1805 rdev->num_crtc = 6; 1810 rdev->num_crtc = 6;
1806 rdev->vm_manager.funcs = &si_vm_funcs;
1807 break; 1811 break;
1808 default: 1812 default:
1809 /* FIXME: not supported yet */ 1813 /* FIXME: not supported yet */
diff --git a/drivers/gpu/drm/radeon/radeon_gart.c b/drivers/gpu/drm/radeon/radeon_gart.c
index bb3b7fe05ccd..b01c6435cb10 100644
--- a/drivers/gpu/drm/radeon/radeon_gart.c
+++ b/drivers/gpu/drm/radeon/radeon_gart.c
@@ -448,7 +448,7 @@ int radeon_vm_manager_init(struct radeon_device *rdev)
448 return r; 448 return r;
449 } 449 }
450 450
451 r = rdev->vm_manager.funcs->init(rdev); 451 r = radeon_asic_vm_init(rdev);
452 if (r) 452 if (r)
453 return r; 453 return r;
454 454
@@ -476,7 +476,7 @@ int radeon_vm_manager_init(struct radeon_device *rdev)
476 } 476 }
477 } 477 }
478 478
479 r = rdev->vm_manager.funcs->bind(rdev, vm, vm->id); 479 r = radeon_asic_vm_bind(rdev, vm, vm->id);
480 if (r) { 480 if (r) {
481 DRM_ERROR("Failed to bind vm %d!\n", vm->id); 481 DRM_ERROR("Failed to bind vm %d!\n", vm->id);
482 } 482 }
@@ -522,7 +522,7 @@ static void radeon_vm_unbind_locked(struct radeon_device *rdev,
522 radeon_fence_unref(&vm->fence); 522 radeon_fence_unref(&vm->fence);
523 523
524 /* hw unbind */ 524 /* hw unbind */
525 rdev->vm_manager.funcs->unbind(rdev, vm); 525 radeon_asic_vm_unbind(rdev, vm);
526 rdev->vm_manager.use_bitmap &= ~(1 << vm->id); 526 rdev->vm_manager.use_bitmap &= ~(1 << vm->id);
527 list_del_init(&vm->list); 527 list_del_init(&vm->list);
528 vm->id = -1; 528 vm->id = -1;
@@ -553,7 +553,7 @@ void radeon_vm_manager_fini(struct radeon_device *rdev)
553 list_for_each_entry_safe(vm, tmp, &rdev->vm_manager.lru_vm, list) { 553 list_for_each_entry_safe(vm, tmp, &rdev->vm_manager.lru_vm, list) {
554 radeon_vm_unbind_locked(rdev, vm); 554 radeon_vm_unbind_locked(rdev, vm);
555 } 555 }
556 rdev->vm_manager.funcs->fini(rdev); 556 radeon_asic_vm_fini(rdev);
557 mutex_unlock(&rdev->vm_manager.lock); 557 mutex_unlock(&rdev->vm_manager.lock);
558 558
559 radeon_sa_bo_manager_suspend(rdev, &rdev->vm_manager.sa_manager); 559 radeon_sa_bo_manager_suspend(rdev, &rdev->vm_manager.sa_manager);
@@ -639,7 +639,7 @@ retry_id:
639 } 639 }
640 640
641 /* do hw bind */ 641 /* do hw bind */
642 r = rdev->vm_manager.funcs->bind(rdev, vm, id); 642 r = radeon_asic_vm_bind(rdev, vm, id);
643 if (r) { 643 if (r) {
644 radeon_sa_bo_free(rdev, &vm->sa_bo, NULL); 644 radeon_sa_bo_free(rdev, &vm->sa_bo, NULL);
645 return r; 645 return r;
@@ -830,14 +830,14 @@ int radeon_vm_bo_update_pte(struct radeon_device *rdev,
830 } 830 }
831 } 831 }
832 pfn = bo_va->soffset / RADEON_GPU_PAGE_SIZE; 832 pfn = bo_va->soffset / RADEON_GPU_PAGE_SIZE;
833 flags = rdev->vm_manager.funcs->page_flags(rdev, bo_va->vm, bo_va->flags); 833 flags = radeon_asic_vm_page_flags(rdev, bo_va->vm, bo_va->flags);
834 for (i = 0, addr = 0; i < ngpu_pages; i++) { 834 for (i = 0, addr = 0; i < ngpu_pages; i++) {
835 if (mem && bo_va->valid) { 835 if (mem && bo_va->valid) {
836 addr = radeon_vm_get_addr(rdev, mem, i); 836 addr = radeon_vm_get_addr(rdev, mem, i);
837 } 837 }
838 rdev->vm_manager.funcs->set_page(rdev, bo_va->vm, i + pfn, addr, flags); 838 radeon_asic_vm_set_page(rdev, bo_va->vm, i + pfn, addr, flags);
839 } 839 }
840 rdev->vm_manager.funcs->tlb_flush(rdev, bo_va->vm); 840 radeon_asic_vm_tlb_flush(rdev, bo_va->vm);
841 return 0; 841 return 0;
842} 842}
843 843