aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChristian König <deathsimple@vodafone.de>2012-09-17 13:36:18 -0400
committerAlex Deucher <alexander.deucher@amd.com>2012-09-27 10:22:43 -0400
commitdce34bfd633d23ebddb196af8a4fa1c93c90ed07 (patch)
treecb081ac92a8b5beeb43b4d70a51e977102f9d870
parentaf026c5bd14cb57b230a63bdee6f73677a06f010 (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.c47
-rw-r--r--drivers/gpu/drm/radeon/radeon.h12
-rw-r--r--drivers/gpu/drm/radeon/radeon_asic.h6
-rw-r--r--drivers/gpu/drm/radeon/radeon_gart.c54
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)
1506uint32_t cayman_vm_page_flags(struct radeon_device *rdev, uint32_t flags) 1506uint32_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 */
1527void cayman_vm_set_page(struct radeon_device *rdev, struct radeon_vm *vm, 1531void 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,
1843void radeon_vm_fence(struct radeon_device *rdev, 1843void 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);
1846u64 radeon_vm_get_addr(struct radeon_device *rdev, 1846uint64_t radeon_vm_map_gart(struct radeon_device *rdev, uint64_t addr);
1847 struct ttm_mem_reg *mem,
1848 unsigned pfn);
1849int radeon_vm_bo_update_pte(struct radeon_device *rdev, 1847int 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);
444void cayman_vm_fini(struct radeon_device *rdev); 444void cayman_vm_fini(struct radeon_device *rdev);
445void cayman_vm_flush(struct radeon_device *rdev, struct radeon_ib *ib); 445void cayman_vm_flush(struct radeon_device *rdev, struct radeon_ib *ib);
446uint32_t cayman_vm_page_flags(struct radeon_device *rdev, uint32_t flags); 446uint32_t cayman_vm_page_flags(struct radeon_device *rdev, uint32_t flags);
447void cayman_vm_set_page(struct radeon_device *rdev, struct radeon_vm *vm, 447void 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);
450int evergreen_ib_parse(struct radeon_device *rdev, struct radeon_ib *ib); 450int 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 */
835u64 radeon_vm_get_addr(struct radeon_device *rdev, 834uint64_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);