aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/radeon/ni.c
diff options
context:
space:
mode:
authorAlex Deucher <alexander.deucher@amd.com>2013-04-16 10:42:15 -0400
committerAlex Deucher <alexander.deucher@amd.com>2013-04-16 16:15:27 -0400
commit2ab91adae722c63d1a4c9a6e414636e34804d792 (patch)
tree0e8c4ee18ea895f4eb2a978bc3ebcbc4c5c19ccd /drivers/gpu/drm/radeon/ni.c
parent0cd9cb76ae26a19df21abc6f94f5fff141e689c7 (diff)
drm/radeon: re-enable PTE/PDE packet for set_page on cayman/TN
PTE/PDE doesn't support a single update (count = 1). We had previously disabled it since it we were hitting that case which let to hangs. The PTE/PDE packet is much more efficient for VM updates where it can be used. Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
Diffstat (limited to 'drivers/gpu/drm/radeon/ni.c')
-rw-r--r--drivers/gpu/drm/radeon/ni.c65
1 files changed, 47 insertions, 18 deletions
diff --git a/drivers/gpu/drm/radeon/ni.c b/drivers/gpu/drm/radeon/ni.c
index 78aead0ada7b..fd03f318cc1c 100644
--- a/drivers/gpu/drm/radeon/ni.c
+++ b/drivers/gpu/drm/radeon/ni.c
@@ -2079,28 +2079,57 @@ void cayman_vm_set_page(struct radeon_device *rdev,
2079 } 2079 }
2080 } 2080 }
2081 } else { 2081 } else {
2082 while (count) { 2082 if ((flags & RADEON_VM_PAGE_SYSTEM) ||
2083 ndw = count * 2; 2083 (count == 1)) {
2084 if (ndw > 0xFFFFE) 2084 while (count) {
2085 ndw = 0xFFFFE; 2085 ndw = count * 2;
2086 if (ndw > 0xFFFFE)
2087 ndw = 0xFFFFE;
2088
2089 /* for non-physically contiguous pages (system) */
2090 ib->ptr[ib->length_dw++] = DMA_PACKET(DMA_PACKET_WRITE, 0, 0, ndw);
2091 ib->ptr[ib->length_dw++] = pe;
2092 ib->ptr[ib->length_dw++] = upper_32_bits(pe) & 0xff;
2093 for (; ndw > 0; ndw -= 2, --count, pe += 8) {
2094 if (flags & RADEON_VM_PAGE_SYSTEM) {
2095 value = radeon_vm_map_gart(rdev, addr);
2096 value &= 0xFFFFFFFFFFFFF000ULL;
2097 } else if (flags & RADEON_VM_PAGE_VALID) {
2098 value = addr;
2099 } else {
2100 value = 0;
2101 }
2102 addr += incr;
2103 value |= r600_flags;
2104 ib->ptr[ib->length_dw++] = value;
2105 ib->ptr[ib->length_dw++] = upper_32_bits(value);
2106 }
2107 }
2108 while (ib->length_dw & 0x7)
2109 ib->ptr[ib->length_dw++] = DMA_PACKET(DMA_PACKET_NOP, 0, 0, 0);
2110 } else {
2111 while (count) {
2112 ndw = count * 2;
2113 if (ndw > 0xFFFFE)
2114 ndw = 0xFFFFE;
2086 2115
2087 /* for non-physically contiguous pages (system) */ 2116 if (flags & RADEON_VM_PAGE_VALID)
2088 ib->ptr[ib->length_dw++] = DMA_PACKET(DMA_PACKET_WRITE, 0, 0, ndw);
2089 ib->ptr[ib->length_dw++] = pe;
2090 ib->ptr[ib->length_dw++] = upper_32_bits(pe) & 0xff;
2091 for (; ndw > 0; ndw -= 2, --count, pe += 8) {
2092 if (flags & RADEON_VM_PAGE_SYSTEM) {
2093 value = radeon_vm_map_gart(rdev, addr);
2094 value &= 0xFFFFFFFFFFFFF000ULL;
2095 } else if (flags & RADEON_VM_PAGE_VALID) {
2096 value = addr; 2117 value = addr;
2097 } else { 2118 else
2098 value = 0; 2119 value = 0;
2099 } 2120 /* for physically contiguous pages (vram) */
2100 addr += incr; 2121 ib->ptr[ib->length_dw++] = DMA_PTE_PDE_PACKET(ndw);
2101 value |= r600_flags; 2122 ib->ptr[ib->length_dw++] = pe; /* dst addr */
2102 ib->ptr[ib->length_dw++] = value; 2123 ib->ptr[ib->length_dw++] = upper_32_bits(pe) & 0xff;
2124 ib->ptr[ib->length_dw++] = r600_flags; /* mask */
2125 ib->ptr[ib->length_dw++] = 0;
2126 ib->ptr[ib->length_dw++] = value; /* value */
2103 ib->ptr[ib->length_dw++] = upper_32_bits(value); 2127 ib->ptr[ib->length_dw++] = upper_32_bits(value);
2128 ib->ptr[ib->length_dw++] = incr; /* increment size */
2129 ib->ptr[ib->length_dw++] = 0;
2130 pe += ndw * 4;
2131 addr += (ndw / 2) * incr;
2132 count -= ndw / 2;
2104 } 2133 }
2105 } 2134 }
2106 while (ib->length_dw & 0x7) 2135 while (ib->length_dw & 0x7)