diff options
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/gpu/drm/radeon/radeon.h | 35 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/radeon_asic.c | 50 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/radeon_gart.c | 16 |
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 | ||
644 | struct 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 | |||
658 | struct radeon_vm_manager { | 644 | struct 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 | ||
1361 | static 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 | |||
1371 | static struct radeon_asic cayman_asic = { | 1361 | static 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 | ||
1561 | static 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 | |||
1571 | static struct radeon_asic si_asic = { | 1569 | static 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 | ||