diff options
author | Christian König <deathsimple@vodafone.de> | 2012-09-17 13:36:18 -0400 |
---|---|---|
committer | Alex Deucher <alexander.deucher@amd.com> | 2012-09-27 10:22:43 -0400 |
commit | dce34bfd633d23ebddb196af8a4fa1c93c90ed07 (patch) | |
tree | cb081ac92a8b5beeb43b4d70a51e977102f9d870 | |
parent | af026c5bd14cb57b230a63bdee6f73677a06f010 (diff) |
drm/radeon: refactor set_page chipset interface v5
Cleanup the interface in preparation for hierarchical page tables.
v2: add incr parameter to set_page for simple scattered PTs uptates
added PDE-specific flags to r600_flags and radeon_drm.h
removed superfluous value masking with 0xffffffff
v3: removed superfluous bo_va->valid checking
changed R600_PTE_VALID to R600_ENTRY_VALID to handle PDE too
v4 (ck): fix indention style, rework and fix typos in commit message,
add documentation for incr parameter, also use incr
parameter for system pages
v5 (agd5f): use upper_32_bits() and minor white space fixes
Signed-off-by: Christian König <deathsimple@vodafone.de>
Signed-off-by: Dmitry Cherkassov <Dmitrii.Cherkasov@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
-rw-r--r-- | drivers/gpu/drm/radeon/ni.c | 47 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/radeon.h | 12 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/radeon_asic.h | 6 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/radeon_gart.c | 54 |
4 files changed, 56 insertions, 63 deletions
diff --git a/drivers/gpu/drm/radeon/ni.c b/drivers/gpu/drm/radeon/ni.c index b23821674a95..b0a08330ed32 100644 --- a/drivers/gpu/drm/radeon/ni.c +++ b/drivers/gpu/drm/radeon/ni.c | |||
@@ -1497,7 +1497,7 @@ void cayman_vm_fini(struct radeon_device *rdev) | |||
1497 | { | 1497 | { |
1498 | } | 1498 | } |
1499 | 1499 | ||
1500 | #define R600_PTE_VALID (1 << 0) | 1500 | #define R600_ENTRY_VALID (1 << 0) |
1501 | #define R600_PTE_SYSTEM (1 << 1) | 1501 | #define R600_PTE_SYSTEM (1 << 1) |
1502 | #define R600_PTE_SNOOPED (1 << 2) | 1502 | #define R600_PTE_SNOOPED (1 << 2) |
1503 | #define R600_PTE_READABLE (1 << 5) | 1503 | #define R600_PTE_READABLE (1 << 5) |
@@ -1506,8 +1506,7 @@ void cayman_vm_fini(struct radeon_device *rdev) | |||
1506 | uint32_t cayman_vm_page_flags(struct radeon_device *rdev, uint32_t flags) | 1506 | uint32_t cayman_vm_page_flags(struct radeon_device *rdev, uint32_t flags) |
1507 | { | 1507 | { |
1508 | uint32_t r600_flags = 0; | 1508 | uint32_t r600_flags = 0; |
1509 | 1509 | r600_flags |= (flags & RADEON_VM_PAGE_VALID) ? R600_ENTRY_VALID : 0; | |
1510 | r600_flags |= (flags & RADEON_VM_PAGE_VALID) ? R600_PTE_VALID : 0; | ||
1511 | r600_flags |= (flags & RADEON_VM_PAGE_READABLE) ? R600_PTE_READABLE : 0; | 1510 | r600_flags |= (flags & RADEON_VM_PAGE_READABLE) ? R600_PTE_READABLE : 0; |
1512 | r600_flags |= (flags & RADEON_VM_PAGE_WRITEABLE) ? R600_PTE_WRITEABLE : 0; | 1511 | r600_flags |= (flags & RADEON_VM_PAGE_WRITEABLE) ? R600_PTE_WRITEABLE : 0; |
1513 | if (flags & RADEON_VM_PAGE_SYSTEM) { | 1512 | if (flags & RADEON_VM_PAGE_SYSTEM) { |
@@ -1521,30 +1520,40 @@ uint32_t cayman_vm_page_flags(struct radeon_device *rdev, uint32_t flags) | |||
1521 | * cayman_vm_set_page - update the page tables using the CP | 1520 | * cayman_vm_set_page - update the page tables using the CP |
1522 | * | 1521 | * |
1523 | * @rdev: radeon_device pointer | 1522 | * @rdev: radeon_device pointer |
1523 | * @pe: addr of the page entry | ||
1524 | * @addr: dst addr to write into pe | ||
1525 | * @count: number of page entries to update | ||
1526 | * @incr: increase next addr by incr bytes | ||
1527 | * @flags: access flags | ||
1524 | * | 1528 | * |
1525 | * Update the page tables using the CP (cayman-si). | 1529 | * Update the page tables using the CP (cayman-si). |
1526 | */ | 1530 | */ |
1527 | void cayman_vm_set_page(struct radeon_device *rdev, struct radeon_vm *vm, | 1531 | void cayman_vm_set_page(struct radeon_device *rdev, uint64_t pe, |
1528 | unsigned pfn, struct ttm_mem_reg *mem, | 1532 | uint64_t addr, unsigned count, |
1529 | unsigned npages, uint32_t flags) | 1533 | uint32_t incr, uint32_t flags) |
1530 | { | 1534 | { |
1531 | struct radeon_ring *ring = &rdev->ring[rdev->asic->vm.pt_ring_index]; | 1535 | struct radeon_ring *ring = &rdev->ring[rdev->asic->vm.pt_ring_index]; |
1532 | uint64_t addr, pt = vm->pt_gpu_addr + pfn * 8; | 1536 | uint32_t r600_flags = cayman_vm_page_flags(rdev, flags); |
1533 | int i; | 1537 | int i; |
1534 | 1538 | ||
1535 | addr = flags = cayman_vm_page_flags(rdev, flags); | 1539 | radeon_ring_write(ring, PACKET3(PACKET3_ME_WRITE, 1 + count * 2)); |
1536 | 1540 | radeon_ring_write(ring, pe); | |
1537 | radeon_ring_write(ring, PACKET3(PACKET3_ME_WRITE, 1 + npages * 2)); | 1541 | radeon_ring_write(ring, upper_32_bits(pe) & 0xff); |
1538 | radeon_ring_write(ring, pt & 0xffffffff); | 1542 | for (i = 0; i < count; ++i) { |
1539 | radeon_ring_write(ring, (pt >> 32) & 0xff); | 1543 | uint64_t value = 0; |
1540 | for (i = 0; i < npages; ++i) { | 1544 | if (flags & RADEON_VM_PAGE_SYSTEM) { |
1541 | if (mem) { | 1545 | value = radeon_vm_map_gart(rdev, addr); |
1542 | addr = radeon_vm_get_addr(rdev, mem, i); | 1546 | value &= 0xFFFFFFFFFFFFF000ULL; |
1543 | addr = addr & 0xFFFFFFFFFFFFF000ULL; | 1547 | addr += incr; |
1544 | addr |= flags; | 1548 | |
1549 | } else if (flags & RADEON_VM_PAGE_VALID) { | ||
1550 | value = addr; | ||
1551 | addr += incr; | ||
1545 | } | 1552 | } |
1546 | radeon_ring_write(ring, addr & 0xffffffff); | 1553 | |
1547 | radeon_ring_write(ring, (addr >> 32) & 0xffffffff); | 1554 | value |= r600_flags; |
1555 | radeon_ring_write(ring, value); | ||
1556 | radeon_ring_write(ring, upper_32_bits(value)); | ||
1548 | } | 1557 | } |
1549 | } | 1558 | } |
1550 | 1559 | ||
diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h index de86b8e259ce..d0d414df29f3 100644 --- a/drivers/gpu/drm/radeon/radeon.h +++ b/drivers/gpu/drm/radeon/radeon.h | |||
@@ -1141,9 +1141,9 @@ struct radeon_asic { | |||
1141 | void (*fini)(struct radeon_device *rdev); | 1141 | void (*fini)(struct radeon_device *rdev); |
1142 | 1142 | ||
1143 | u32 pt_ring_index; | 1143 | u32 pt_ring_index; |
1144 | void (*set_page)(struct radeon_device *rdev, struct radeon_vm *vm, | 1144 | void (*set_page)(struct radeon_device *rdev, uint64_t pe, |
1145 | unsigned pfn, struct ttm_mem_reg *mem, | 1145 | uint64_t addr, unsigned count, |
1146 | unsigned npages, uint32_t flags); | 1146 | uint32_t incr, uint32_t flags); |
1147 | } vm; | 1147 | } vm; |
1148 | /* ring specific callbacks */ | 1148 | /* ring specific callbacks */ |
1149 | struct { | 1149 | struct { |
@@ -1757,7 +1757,7 @@ void radeon_ring_write(struct radeon_ring *ring, uint32_t v); | |||
1757 | #define radeon_gart_set_page(rdev, i, p) (rdev)->asic->gart.set_page((rdev), (i), (p)) | 1757 | #define radeon_gart_set_page(rdev, i, p) (rdev)->asic->gart.set_page((rdev), (i), (p)) |
1758 | #define radeon_asic_vm_init(rdev) (rdev)->asic->vm.init((rdev)) | 1758 | #define radeon_asic_vm_init(rdev) (rdev)->asic->vm.init((rdev)) |
1759 | #define radeon_asic_vm_fini(rdev) (rdev)->asic->vm.fini((rdev)) | 1759 | #define radeon_asic_vm_fini(rdev) (rdev)->asic->vm.fini((rdev)) |
1760 | #define radeon_asic_vm_set_page(rdev, v, pfn, mem, npages, flags) (rdev)->asic->vm.set_page((rdev), (v), (pfn), (mem), (npages), (flags)) | 1760 | #define radeon_asic_vm_set_page(rdev, pe, addr, count, incr, flags) ((rdev)->asic->vm.set_page((rdev), (pe), (addr), (count), (incr), (flags))) |
1761 | #define radeon_ring_start(rdev, r, cp) (rdev)->asic->ring[(r)].ring_start((rdev), (cp)) | 1761 | #define radeon_ring_start(rdev, r, cp) (rdev)->asic->ring[(r)].ring_start((rdev), (cp)) |
1762 | #define radeon_ring_test(rdev, r, cp) (rdev)->asic->ring[(r)].ring_test((rdev), (cp)) | 1762 | #define radeon_ring_test(rdev, r, cp) (rdev)->asic->ring[(r)].ring_test((rdev), (cp)) |
1763 | #define radeon_ib_test(rdev, r, cp) (rdev)->asic->ring[(r)].ib_test((rdev), (cp)) | 1763 | #define radeon_ib_test(rdev, r, cp) (rdev)->asic->ring[(r)].ib_test((rdev), (cp)) |
@@ -1843,9 +1843,7 @@ struct radeon_fence *radeon_vm_grab_id(struct radeon_device *rdev, | |||
1843 | void radeon_vm_fence(struct radeon_device *rdev, | 1843 | void radeon_vm_fence(struct radeon_device *rdev, |
1844 | struct radeon_vm *vm, | 1844 | struct radeon_vm *vm, |
1845 | struct radeon_fence *fence); | 1845 | struct radeon_fence *fence); |
1846 | u64 radeon_vm_get_addr(struct radeon_device *rdev, | 1846 | uint64_t radeon_vm_map_gart(struct radeon_device *rdev, uint64_t addr); |
1847 | struct ttm_mem_reg *mem, | ||
1848 | unsigned pfn); | ||
1849 | int radeon_vm_bo_update_pte(struct radeon_device *rdev, | 1847 | int radeon_vm_bo_update_pte(struct radeon_device *rdev, |
1850 | struct radeon_vm *vm, | 1848 | struct radeon_vm *vm, |
1851 | struct radeon_bo *bo, | 1849 | struct radeon_bo *bo, |
diff --git a/drivers/gpu/drm/radeon/radeon_asic.h b/drivers/gpu/drm/radeon/radeon_asic.h index 8251b44550b7..9a71f445c36b 100644 --- a/drivers/gpu/drm/radeon/radeon_asic.h +++ b/drivers/gpu/drm/radeon/radeon_asic.h | |||
@@ -444,9 +444,9 @@ int cayman_vm_init(struct radeon_device *rdev); | |||
444 | void cayman_vm_fini(struct radeon_device *rdev); | 444 | void cayman_vm_fini(struct radeon_device *rdev); |
445 | void cayman_vm_flush(struct radeon_device *rdev, struct radeon_ib *ib); | 445 | void cayman_vm_flush(struct radeon_device *rdev, struct radeon_ib *ib); |
446 | uint32_t cayman_vm_page_flags(struct radeon_device *rdev, uint32_t flags); | 446 | uint32_t cayman_vm_page_flags(struct radeon_device *rdev, uint32_t flags); |
447 | void cayman_vm_set_page(struct radeon_device *rdev, struct radeon_vm *vm, | 447 | void cayman_vm_set_page(struct radeon_device *rdev, uint64_t pe, |
448 | unsigned pfn, struct ttm_mem_reg *mem, | 448 | uint64_t addr, unsigned count, |
449 | unsigned npages, uint32_t flags); | 449 | uint32_t incr, uint32_t flags); |
450 | int evergreen_ib_parse(struct radeon_device *rdev, struct radeon_ib *ib); | 450 | int evergreen_ib_parse(struct radeon_device *rdev, struct radeon_ib *ib); |
451 | 451 | ||
452 | /* DCE6 - SI */ | 452 | /* DCE6 - SI */ |
diff --git a/drivers/gpu/drm/radeon/radeon_gart.c b/drivers/gpu/drm/radeon/radeon_gart.c index 2f28ff34c085..bb9fc594779c 100644 --- a/drivers/gpu/drm/radeon/radeon_gart.c +++ b/drivers/gpu/drm/radeon/radeon_gart.c | |||
@@ -822,42 +822,26 @@ int radeon_vm_bo_set_addr(struct radeon_device *rdev, | |||
822 | } | 822 | } |
823 | 823 | ||
824 | /** | 824 | /** |
825 | * radeon_vm_get_addr - get the physical address of the page | 825 | * radeon_vm_map_gart - get the physical address of a gart page |
826 | * | 826 | * |
827 | * @rdev: radeon_device pointer | 827 | * @rdev: radeon_device pointer |
828 | * @mem: ttm mem | 828 | * @addr: the unmapped addr |
829 | * @pfn: pfn | ||
830 | * | 829 | * |
831 | * Look up the physical address of the page that the pte resolves | 830 | * Look up the physical address of the page that the pte resolves |
832 | * to (cayman+). | 831 | * to (cayman+). |
833 | * Returns the physical address of the page. | 832 | * Returns the physical address of the page. |
834 | */ | 833 | */ |
835 | u64 radeon_vm_get_addr(struct radeon_device *rdev, | 834 | uint64_t radeon_vm_map_gart(struct radeon_device *rdev, uint64_t addr) |
836 | struct ttm_mem_reg *mem, | ||
837 | unsigned pfn) | ||
838 | { | 835 | { |
839 | u64 addr = 0; | 836 | uint64_t result; |
840 | 837 | ||
841 | switch (mem->mem_type) { | 838 | /* page table offset */ |
842 | case TTM_PL_VRAM: | 839 | result = rdev->gart.pages_addr[addr >> PAGE_SHIFT]; |
843 | addr = (mem->start << PAGE_SHIFT); | 840 | |
844 | addr += pfn * RADEON_GPU_PAGE_SIZE; | 841 | /* in case cpu page size != gpu page size*/ |
845 | addr += rdev->vm_manager.vram_base_offset; | 842 | result |= addr & (~PAGE_MASK); |
846 | break; | 843 | |
847 | case TTM_PL_TT: | 844 | return result; |
848 | /* offset inside page table */ | ||
849 | addr = mem->start << PAGE_SHIFT; | ||
850 | addr += pfn * RADEON_GPU_PAGE_SIZE; | ||
851 | addr = addr >> PAGE_SHIFT; | ||
852 | /* page table offset */ | ||
853 | addr = rdev->gart.pages_addr[addr]; | ||
854 | /* in case cpu page size != gpu page size*/ | ||
855 | addr += (pfn * RADEON_GPU_PAGE_SIZE) & (~PAGE_MASK); | ||
856 | break; | ||
857 | default: | ||
858 | break; | ||
859 | } | ||
860 | return addr; | ||
861 | } | 845 | } |
862 | 846 | ||
863 | /** | 847 | /** |
@@ -883,7 +867,7 @@ int radeon_vm_bo_update_pte(struct radeon_device *rdev, | |||
883 | struct radeon_semaphore *sem = NULL; | 867 | struct radeon_semaphore *sem = NULL; |
884 | struct radeon_bo_va *bo_va; | 868 | struct radeon_bo_va *bo_va; |
885 | unsigned ngpu_pages, ndw; | 869 | unsigned ngpu_pages, ndw; |
886 | uint64_t pfn; | 870 | uint64_t pfn, addr; |
887 | int r; | 871 | int r; |
888 | 872 | ||
889 | /* nothing to do if vm isn't bound */ | 873 | /* nothing to do if vm isn't bound */ |
@@ -908,21 +892,22 @@ int radeon_vm_bo_update_pte(struct radeon_device *rdev, | |||
908 | ngpu_pages = radeon_bo_ngpu_pages(bo); | 892 | ngpu_pages = radeon_bo_ngpu_pages(bo); |
909 | bo_va->flags &= ~RADEON_VM_PAGE_VALID; | 893 | bo_va->flags &= ~RADEON_VM_PAGE_VALID; |
910 | bo_va->flags &= ~RADEON_VM_PAGE_SYSTEM; | 894 | bo_va->flags &= ~RADEON_VM_PAGE_SYSTEM; |
895 | pfn = bo_va->soffset / RADEON_GPU_PAGE_SIZE; | ||
911 | if (mem) { | 896 | if (mem) { |
897 | addr = mem->start << PAGE_SHIFT; | ||
912 | if (mem->mem_type != TTM_PL_SYSTEM) { | 898 | if (mem->mem_type != TTM_PL_SYSTEM) { |
913 | bo_va->flags |= RADEON_VM_PAGE_VALID; | 899 | bo_va->flags |= RADEON_VM_PAGE_VALID; |
914 | bo_va->valid = true; | 900 | bo_va->valid = true; |
915 | } | 901 | } |
916 | if (mem->mem_type == TTM_PL_TT) { | 902 | if (mem->mem_type == TTM_PL_TT) { |
917 | bo_va->flags |= RADEON_VM_PAGE_SYSTEM; | 903 | bo_va->flags |= RADEON_VM_PAGE_SYSTEM; |
918 | } | 904 | } else { |
919 | if (!bo_va->valid) { | 905 | addr += rdev->vm_manager.vram_base_offset; |
920 | mem = NULL; | ||
921 | } | 906 | } |
922 | } else { | 907 | } else { |
908 | addr = 0; | ||
923 | bo_va->valid = false; | 909 | bo_va->valid = false; |
924 | } | 910 | } |
925 | pfn = bo_va->soffset / RADEON_GPU_PAGE_SIZE; | ||
926 | 911 | ||
927 | if (vm->fence && radeon_fence_signaled(vm->fence)) { | 912 | if (vm->fence && radeon_fence_signaled(vm->fence)) { |
928 | radeon_fence_unref(&vm->fence); | 913 | radeon_fence_unref(&vm->fence); |
@@ -950,7 +935,8 @@ int radeon_vm_bo_update_pte(struct radeon_device *rdev, | |||
950 | radeon_fence_note_sync(vm->fence, ridx); | 935 | radeon_fence_note_sync(vm->fence, ridx); |
951 | } | 936 | } |
952 | 937 | ||
953 | radeon_asic_vm_set_page(rdev, vm, pfn, mem, ngpu_pages, bo_va->flags); | 938 | radeon_asic_vm_set_page(rdev, vm->pt_gpu_addr + pfn * 8, addr, |
939 | ngpu_pages, RADEON_GPU_PAGE_SIZE, bo_va->flags); | ||
954 | 940 | ||
955 | radeon_fence_unref(&vm->fence); | 941 | radeon_fence_unref(&vm->fence); |
956 | r = radeon_fence_emit(rdev, &vm->fence, ridx); | 942 | r = radeon_fence_emit(rdev, &vm->fence, ridx); |