aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/radeon/si_dma.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/radeon/si_dma.c')
-rw-r--r--drivers/gpu/drm/radeon/si_dma.c172
1 files changed, 106 insertions, 66 deletions
diff --git a/drivers/gpu/drm/radeon/si_dma.c b/drivers/gpu/drm/radeon/si_dma.c
index e24c94b6d14d..716505129450 100644
--- a/drivers/gpu/drm/radeon/si_dma.c
+++ b/drivers/gpu/drm/radeon/si_dma.c
@@ -56,7 +56,41 @@ bool si_dma_is_lockup(struct radeon_device *rdev, struct radeon_ring *ring)
56} 56}
57 57
58/** 58/**
59 * si_dma_vm_set_page - update the page tables using the DMA 59 * si_dma_vm_copy_pages - update PTEs by copying them from the GART
60 *
61 * @rdev: radeon_device pointer
62 * @ib: indirect buffer to fill with commands
63 * @pe: addr of the page entry
64 * @src: src addr where to copy from
65 * @count: number of page entries to update
66 *
67 * Update PTEs by copying them from the GART using the DMA (SI).
68 */
69void si_dma_vm_copy_pages(struct radeon_device *rdev,
70 struct radeon_ib *ib,
71 uint64_t pe, uint64_t src,
72 unsigned count)
73{
74 while (count) {
75 unsigned bytes = count * 8;
76 if (bytes > 0xFFFF8)
77 bytes = 0xFFFF8;
78
79 ib->ptr[ib->length_dw++] = DMA_PACKET(DMA_PACKET_COPY,
80 1, 0, 0, bytes);
81 ib->ptr[ib->length_dw++] = lower_32_bits(pe);
82 ib->ptr[ib->length_dw++] = lower_32_bits(src);
83 ib->ptr[ib->length_dw++] = upper_32_bits(pe) & 0xff;
84 ib->ptr[ib->length_dw++] = upper_32_bits(src) & 0xff;
85
86 pe += bytes;
87 src += bytes;
88 count -= bytes / 8;
89 }
90}
91
92/**
93 * si_dma_vm_write_pages - update PTEs by writing them manually
60 * 94 *
61 * @rdev: radeon_device pointer 95 * @rdev: radeon_device pointer
62 * @ib: indirect buffer to fill with commands 96 * @ib: indirect buffer to fill with commands
@@ -66,83 +100,89 @@ bool si_dma_is_lockup(struct radeon_device *rdev, struct radeon_ring *ring)
66 * @incr: increase next addr by incr bytes 100 * @incr: increase next addr by incr bytes
67 * @flags: access flags 101 * @flags: access flags
68 * 102 *
69 * Update the page tables using the DMA (SI). 103 * Update PTEs by writing them manually using the DMA (SI).
70 */ 104 */
71void si_dma_vm_set_page(struct radeon_device *rdev, 105void si_dma_vm_write_pages(struct radeon_device *rdev,
72 struct radeon_ib *ib, 106 struct radeon_ib *ib,
73 uint64_t pe, 107 uint64_t pe,
74 uint64_t addr, unsigned count, 108 uint64_t addr, unsigned count,
75 uint32_t incr, uint32_t flags) 109 uint32_t incr, uint32_t flags)
76{ 110{
77 uint64_t value; 111 uint64_t value;
78 unsigned ndw; 112 unsigned ndw;
79 113
80 trace_radeon_vm_set_page(pe, addr, count, incr, flags); 114 while (count) {
81 115 ndw = count * 2;
82 if (flags == R600_PTE_GART) { 116 if (ndw > 0xFFFFE)
83 uint64_t src = rdev->gart.table_addr + (addr >> 12) * 8; 117 ndw = 0xFFFFE;
84 while (count) { 118
85 unsigned bytes = count * 8; 119 /* for non-physically contiguous pages (system) */
86 if (bytes > 0xFFFF8) 120 ib->ptr[ib->length_dw++] = DMA_PACKET(DMA_PACKET_WRITE, 0, 0, 0, ndw);
87 bytes = 0xFFFF8; 121 ib->ptr[ib->length_dw++] = pe;
88 122 ib->ptr[ib->length_dw++] = upper_32_bits(pe) & 0xff;
89 ib->ptr[ib->length_dw++] = DMA_PACKET(DMA_PACKET_COPY, 123 for (; ndw > 0; ndw -= 2, --count, pe += 8) {
90 1, 0, 0, bytes); 124 if (flags & R600_PTE_SYSTEM) {
91 ib->ptr[ib->length_dw++] = lower_32_bits(pe);
92 ib->ptr[ib->length_dw++] = lower_32_bits(src);
93 ib->ptr[ib->length_dw++] = upper_32_bits(pe) & 0xff;
94 ib->ptr[ib->length_dw++] = upper_32_bits(src) & 0xff;
95
96 pe += bytes;
97 src += bytes;
98 count -= bytes / 8;
99 }
100 } else if (flags & R600_PTE_SYSTEM) {
101 while (count) {
102 ndw = count * 2;
103 if (ndw > 0xFFFFE)
104 ndw = 0xFFFFE;
105
106 /* for non-physically contiguous pages (system) */
107 ib->ptr[ib->length_dw++] = DMA_PACKET(DMA_PACKET_WRITE, 0, 0, 0, ndw);
108 ib->ptr[ib->length_dw++] = pe;
109 ib->ptr[ib->length_dw++] = upper_32_bits(pe) & 0xff;
110 for (; ndw > 0; ndw -= 2, --count, pe += 8) {
111 value = radeon_vm_map_gart(rdev, addr); 125 value = radeon_vm_map_gart(rdev, addr);
112 value &= 0xFFFFFFFFFFFFF000ULL; 126 value &= 0xFFFFFFFFFFFFF000ULL;
113 addr += incr; 127 } else if (flags & R600_PTE_VALID) {
114 value |= flags;
115 ib->ptr[ib->length_dw++] = value;
116 ib->ptr[ib->length_dw++] = upper_32_bits(value);
117 }
118 }
119 } else {
120 while (count) {
121 ndw = count * 2;
122 if (ndw > 0xFFFFE)
123 ndw = 0xFFFFE;
124
125 if (flags & R600_PTE_VALID)
126 value = addr; 128 value = addr;
127 else 129 } else {
128 value = 0; 130 value = 0;
129 /* for physically contiguous pages (vram) */ 131 }
130 ib->ptr[ib->length_dw++] = DMA_PTE_PDE_PACKET(ndw); 132 addr += incr;
131 ib->ptr[ib->length_dw++] = pe; /* dst addr */ 133 value |= flags;
132 ib->ptr[ib->length_dw++] = upper_32_bits(pe) & 0xff; 134 ib->ptr[ib->length_dw++] = value;
133 ib->ptr[ib->length_dw++] = flags; /* mask */
134 ib->ptr[ib->length_dw++] = 0;
135 ib->ptr[ib->length_dw++] = value; /* value */
136 ib->ptr[ib->length_dw++] = upper_32_bits(value); 135 ib->ptr[ib->length_dw++] = upper_32_bits(value);
137 ib->ptr[ib->length_dw++] = incr; /* increment size */
138 ib->ptr[ib->length_dw++] = 0;
139 pe += ndw * 4;
140 addr += (ndw / 2) * incr;
141 count -= ndw / 2;
142 } 136 }
143 } 137 }
144 while (ib->length_dw & 0x7) 138}
145 ib->ptr[ib->length_dw++] = DMA_PACKET(DMA_PACKET_NOP, 0, 0, 0, 0); 139
140/**
141 * si_dma_vm_set_pages - update the page tables using the DMA
142 *
143 * @rdev: radeon_device pointer
144 * @ib: indirect buffer to fill with commands
145 * @pe: addr of the page entry
146 * @addr: dst addr to write into pe
147 * @count: number of page entries to update
148 * @incr: increase next addr by incr bytes
149 * @flags: access flags
150 *
151 * Update the page tables using the DMA (SI).
152 */
153void si_dma_vm_set_pages(struct radeon_device *rdev,
154 struct radeon_ib *ib,
155 uint64_t pe,
156 uint64_t addr, unsigned count,
157 uint32_t incr, uint32_t flags)
158{
159 uint64_t value;
160 unsigned ndw;
161
162 while (count) {
163 ndw = count * 2;
164 if (ndw > 0xFFFFE)
165 ndw = 0xFFFFE;
166
167 if (flags & R600_PTE_VALID)
168 value = addr;
169 else
170 value = 0;
171
172 /* for physically contiguous pages (vram) */
173 ib->ptr[ib->length_dw++] = DMA_PTE_PDE_PACKET(ndw);
174 ib->ptr[ib->length_dw++] = pe; /* dst addr */
175 ib->ptr[ib->length_dw++] = upper_32_bits(pe) & 0xff;
176 ib->ptr[ib->length_dw++] = flags; /* mask */
177 ib->ptr[ib->length_dw++] = 0;
178 ib->ptr[ib->length_dw++] = value; /* value */
179 ib->ptr[ib->length_dw++] = upper_32_bits(value);
180 ib->ptr[ib->length_dw++] = incr; /* increment size */
181 ib->ptr[ib->length_dw++] = 0;
182 pe += ndw * 4;
183 addr += (ndw / 2) * incr;
184 count -= ndw / 2;
185 }
146} 186}
147 187
148void si_dma_vm_flush(struct radeon_device *rdev, int ridx, struct radeon_vm *vm) 188void si_dma_vm_flush(struct radeon_device *rdev, int ridx, struct radeon_vm *vm)