aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/radeon/si.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/radeon/si.c')
-rw-r--r--drivers/gpu/drm/radeon/si.c54
1 files changed, 32 insertions, 22 deletions
diff --git a/drivers/gpu/drm/radeon/si.c b/drivers/gpu/drm/radeon/si.c
index f79633a036c..b0db712060f 100644
--- a/drivers/gpu/drm/radeon/si.c
+++ b/drivers/gpu/drm/radeon/si.c
@@ -2407,12 +2407,13 @@ static int si_pcie_gart_enable(struct radeon_device *rdev)
2407 WREG32(0x15DC, 0); 2407 WREG32(0x15DC, 0);
2408 2408
2409 /* empty context1-15 */ 2409 /* empty context1-15 */
2410 /* FIXME start with 4G, once using 2 level pt switch to full
2411 * vm size space
2412 */
2413 /* set vm size, must be a multiple of 4 */ 2410 /* set vm size, must be a multiple of 4 */
2414 WREG32(VM_CONTEXT1_PAGE_TABLE_START_ADDR, 0); 2411 WREG32(VM_CONTEXT1_PAGE_TABLE_START_ADDR, 0);
2415 WREG32(VM_CONTEXT1_PAGE_TABLE_END_ADDR, rdev->vm_manager.max_pfn); 2412 WREG32(VM_CONTEXT1_PAGE_TABLE_END_ADDR, rdev->vm_manager.max_pfn);
2413 /* Assign the pt base to something valid for now; the pts used for
2414 * the VMs are determined by the application and setup and assigned
2415 * on the fly in the vm part of radeon_gart.c
2416 */
2416 for (i = 1; i < 16; i++) { 2417 for (i = 1; i < 16; i++) {
2417 if (i < 8) 2418 if (i < 8)
2418 WREG32(VM_CONTEXT0_PAGE_TABLE_BASE_ADDR + (i << 2), 2419 WREG32(VM_CONTEXT0_PAGE_TABLE_BASE_ADDR + (i << 2),
@@ -2807,26 +2808,31 @@ void si_vm_set_page(struct radeon_device *rdev, uint64_t pe,
2807{ 2808{
2808 struct radeon_ring *ring = &rdev->ring[rdev->asic->vm.pt_ring_index]; 2809 struct radeon_ring *ring = &rdev->ring[rdev->asic->vm.pt_ring_index];
2809 uint32_t r600_flags = cayman_vm_page_flags(rdev, flags); 2810 uint32_t r600_flags = cayman_vm_page_flags(rdev, flags);
2810 int i;
2811 uint64_t value;
2812 2811
2813 radeon_ring_write(ring, PACKET3(PACKET3_WRITE_DATA, 2 + count * 2)); 2812 while (count) {
2814 radeon_ring_write(ring, (WRITE_DATA_ENGINE_SEL(0) | 2813 unsigned ndw = 2 + count * 2;
2815 WRITE_DATA_DST_SEL(1))); 2814 if (ndw > 0x3FFE)
2816 radeon_ring_write(ring, pe); 2815 ndw = 0x3FFE;
2817 radeon_ring_write(ring, upper_32_bits(pe)); 2816
2818 for (i = 0; i < count; ++i) { 2817 radeon_ring_write(ring, PACKET3(PACKET3_WRITE_DATA, ndw));
2819 if (flags & RADEON_VM_PAGE_SYSTEM) { 2818 radeon_ring_write(ring, (WRITE_DATA_ENGINE_SEL(0) |
2820 value = radeon_vm_map_gart(rdev, addr); 2819 WRITE_DATA_DST_SEL(1)));
2821 value &= 0xFFFFFFFFFFFFF000ULL; 2820 radeon_ring_write(ring, pe);
2822 } else if (flags & RADEON_VM_PAGE_VALID) 2821 radeon_ring_write(ring, upper_32_bits(pe));
2823 value = addr; 2822 for (; ndw > 2; ndw -= 2, --count, pe += 8) {
2824 else 2823 uint64_t value;
2825 value = 0; 2824 if (flags & RADEON_VM_PAGE_SYSTEM) {
2826 addr += incr; 2825 value = radeon_vm_map_gart(rdev, addr);
2827 value |= r600_flags; 2826 value &= 0xFFFFFFFFFFFFF000ULL;
2828 radeon_ring_write(ring, value); 2827 } else if (flags & RADEON_VM_PAGE_VALID)
2829 radeon_ring_write(ring, upper_32_bits(value)); 2828 value = addr;
2829 else
2830 value = 0;
2831 addr += incr;
2832 value |= r600_flags;
2833 radeon_ring_write(ring, value);
2834 radeon_ring_write(ring, upper_32_bits(value));
2835 }
2830 } 2836 }
2831} 2837}
2832 2838
@@ -2867,6 +2873,10 @@ void si_vm_flush(struct radeon_device *rdev, int ridx, struct radeon_vm *vm)
2867 radeon_ring_write(ring, VM_INVALIDATE_REQUEST >> 2); 2873 radeon_ring_write(ring, VM_INVALIDATE_REQUEST >> 2);
2868 radeon_ring_write(ring, 0); 2874 radeon_ring_write(ring, 0);
2869 radeon_ring_write(ring, 1 << vm->id); 2875 radeon_ring_write(ring, 1 << vm->id);
2876
2877 /* sync PFP to ME, otherwise we might get invalid PFP reads */
2878 radeon_ring_write(ring, PACKET3(PACKET3_PFP_SYNC_ME, 0));
2879 radeon_ring_write(ring, 0x0);
2870} 2880}
2871 2881
2872/* 2882/*