aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/radeon/ni.c
diff options
context:
space:
mode:
authorAlex Deucher <alexander.deucher@amd.com>2013-02-01 11:32:42 -0500
committerAlex Deucher <alexander.deucher@amd.com>2013-02-01 13:57:10 -0500
commit43f1214aa094e46efdfc0255d9601be0e5ea0f62 (patch)
treef68b6472afdc8d460b73f67958aad4b21e06ee85 /drivers/gpu/drm/radeon/ni.c
parent24178ec42b0985d485886bc43b97e54ff173627e (diff)
drm/radeon: use IBs for VM page table updates v2
For very large page table updates, we can exceed the size of the ring. To avoid this, use an IB to perform the page table update. v2(ck): cleanup the IB infrastructure and the use it instead of filling the struct ourself. Signed-off-by: Alex Deucher <alexander.deucher@amd.com> Signed-off-by: Christian König <christian.koenig@amd.com>
Diffstat (limited to 'drivers/gpu/drm/radeon/ni.c')
-rw-r--r--drivers/gpu/drm/radeon/ni.c30
1 files changed, 17 insertions, 13 deletions
diff --git a/drivers/gpu/drm/radeon/ni.c b/drivers/gpu/drm/radeon/ni.c
index 170bd03d4dd8..7cead763be9e 100644
--- a/drivers/gpu/drm/radeon/ni.c
+++ b/drivers/gpu/drm/radeon/ni.c
@@ -1946,19 +1946,21 @@ uint32_t cayman_vm_page_flags(struct radeon_device *rdev, uint32_t flags)
1946 * cayman_vm_set_page - update the page tables using the CP 1946 * cayman_vm_set_page - update the page tables using the CP
1947 * 1947 *
1948 * @rdev: radeon_device pointer 1948 * @rdev: radeon_device pointer
1949 * @ib: indirect buffer to fill with commands
1949 * @pe: addr of the page entry 1950 * @pe: addr of the page entry
1950 * @addr: dst addr to write into pe 1951 * @addr: dst addr to write into pe
1951 * @count: number of page entries to update 1952 * @count: number of page entries to update
1952 * @incr: increase next addr by incr bytes 1953 * @incr: increase next addr by incr bytes
1953 * @flags: access flags 1954 * @flags: access flags
1954 * 1955 *
1955 * Update the page tables using the CP (cayman-si). 1956 * Update the page tables using the CP (cayman/TN).
1956 */ 1957 */
1957void cayman_vm_set_page(struct radeon_device *rdev, uint64_t pe, 1958void cayman_vm_set_page(struct radeon_device *rdev,
1959 struct radeon_ib *ib,
1960 uint64_t pe,
1958 uint64_t addr, unsigned count, 1961 uint64_t addr, unsigned count,
1959 uint32_t incr, uint32_t flags) 1962 uint32_t incr, uint32_t flags)
1960{ 1963{
1961 struct radeon_ring *ring = &rdev->ring[rdev->asic->vm.pt_ring_index];
1962 uint32_t r600_flags = cayman_vm_page_flags(rdev, flags); 1964 uint32_t r600_flags = cayman_vm_page_flags(rdev, flags);
1963 uint64_t value; 1965 uint64_t value;
1964 unsigned ndw; 1966 unsigned ndw;
@@ -1969,9 +1971,9 @@ void cayman_vm_set_page(struct radeon_device *rdev, uint64_t pe,
1969 if (ndw > 0x3FFF) 1971 if (ndw > 0x3FFF)
1970 ndw = 0x3FFF; 1972 ndw = 0x3FFF;
1971 1973
1972 radeon_ring_write(ring, PACKET3(PACKET3_ME_WRITE, ndw)); 1974 ib->ptr[ib->length_dw++] = PACKET3(PACKET3_ME_WRITE, ndw);
1973 radeon_ring_write(ring, pe); 1975 ib->ptr[ib->length_dw++] = pe;
1974 radeon_ring_write(ring, upper_32_bits(pe) & 0xff); 1976 ib->ptr[ib->length_dw++] = upper_32_bits(pe) & 0xff;
1975 for (; ndw > 1; ndw -= 2, --count, pe += 8) { 1977 for (; ndw > 1; ndw -= 2, --count, pe += 8) {
1976 if (flags & RADEON_VM_PAGE_SYSTEM) { 1978 if (flags & RADEON_VM_PAGE_SYSTEM) {
1977 value = radeon_vm_map_gart(rdev, addr); 1979 value = radeon_vm_map_gart(rdev, addr);
@@ -1983,8 +1985,8 @@ void cayman_vm_set_page(struct radeon_device *rdev, uint64_t pe,
1983 } 1985 }
1984 addr += incr; 1986 addr += incr;
1985 value |= r600_flags; 1987 value |= r600_flags;
1986 radeon_ring_write(ring, value); 1988 ib->ptr[ib->length_dw++] = value;
1987 radeon_ring_write(ring, upper_32_bits(value)); 1989 ib->ptr[ib->length_dw++] = upper_32_bits(value);
1988 } 1990 }
1989 } 1991 }
1990 } else { 1992 } else {
@@ -1994,9 +1996,9 @@ void cayman_vm_set_page(struct radeon_device *rdev, uint64_t pe,
1994 ndw = 0xFFFFE; 1996 ndw = 0xFFFFE;
1995 1997
1996 /* for non-physically contiguous pages (system) */ 1998 /* for non-physically contiguous pages (system) */
1997 radeon_ring_write(ring, DMA_PACKET(DMA_PACKET_WRITE, 0, 0, ndw)); 1999 ib->ptr[ib->length_dw++] = DMA_PACKET(DMA_PACKET_WRITE, 0, 0, ndw);
1998 radeon_ring_write(ring, pe); 2000 ib->ptr[ib->length_dw++] = pe;
1999 radeon_ring_write(ring, upper_32_bits(pe) & 0xff); 2001 ib->ptr[ib->length_dw++] = upper_32_bits(pe) & 0xff;
2000 for (; ndw > 0; ndw -= 2, --count, pe += 8) { 2002 for (; ndw > 0; ndw -= 2, --count, pe += 8) {
2001 if (flags & RADEON_VM_PAGE_SYSTEM) { 2003 if (flags & RADEON_VM_PAGE_SYSTEM) {
2002 value = radeon_vm_map_gart(rdev, addr); 2004 value = radeon_vm_map_gart(rdev, addr);
@@ -2008,10 +2010,12 @@ void cayman_vm_set_page(struct radeon_device *rdev, uint64_t pe,
2008 } 2010 }
2009 addr += incr; 2011 addr += incr;
2010 value |= r600_flags; 2012 value |= r600_flags;
2011 radeon_ring_write(ring, value); 2013 ib->ptr[ib->length_dw++] = value;
2012 radeon_ring_write(ring, upper_32_bits(value)); 2014 ib->ptr[ib->length_dw++] = upper_32_bits(value);
2013 } 2015 }
2014 } 2016 }
2017 while (ib->length_dw & 0x7)
2018 ib->ptr[ib->length_dw++] = DMA_PACKET(DMA_PACKET_NOP, 0, 0, 0);
2015 } 2019 }
2016} 2020}
2017 2021