Rev 2005 | Rev 3120 | Go to most recent revision | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 2005 | Rev 2997 | ||
---|---|---|---|
Line 25... | Line 25... | ||
25 | * Alex Deucher |
25 | * Alex Deucher |
26 | * Jerome Glisse |
26 | * Jerome Glisse |
27 | */ |
27 | */ |
28 | #include |
28 | #include |
29 | #include |
29 | #include |
30 | #include "drmP.h" |
30 | #include |
31 | #include "drm.h" |
- | |
32 | #include "radeon_drm.h" |
31 | #include |
33 | #include "radeon_reg.h" |
32 | #include "radeon_reg.h" |
34 | #include "radeon.h" |
33 | #include "radeon.h" |
35 | #include "radeon_asic.h" |
34 | #include "radeon_asic.h" |
36 | #include "r100d.h" |
35 | #include "r100d.h" |
37 | #include "rs100d.h" |
36 | #include "rs100d.h" |
38 | #include "rv200d.h" |
37 | #include "rv200d.h" |
39 | #include "rv250d.h" |
38 | #include "rv250d.h" |
40 | #include "atom.h" |
39 | #include "atom.h" |
Line 41... | Line 40... | ||
41 | 40 | ||
- | 41 | #include |
|
Line 42... | Line 42... | ||
42 | #include |
42 | #include |
43 | 43 | ||
Line 44... | Line 44... | ||
44 | #include "r100_reg_safe.h" |
44 | #include "r100_reg_safe.h" |
Line 62... | Line 62... | ||
62 | MODULE_FIRMWARE(FIRMWARE_R520); |
62 | MODULE_FIRMWARE(FIRMWARE_R520); |
Line 63... | Line 63... | ||
63 | 63 | ||
64 | 64 | ||
- | 65 | /* This files gather functions specifics to: |
|
65 | /* This files gather functions specifics to: |
66 | * r100,rv100,rs100,rv200,rs200,r200,rv250,rs300,rv280 |
Line -... | Line 67... | ||
- | 67 | * and others in some cases. |
|
- | 68 | */ |
|
- | 69 | ||
- | 70 | /** |
|
- | 71 | * r100_wait_for_vblank - vblank wait asic callback. |
|
- | 72 | * |
|
- | 73 | * @rdev: radeon_device pointer |
|
- | 74 | * @crtc: crtc to wait for vblank on |
|
- | 75 | * |
|
- | 76 | * Wait for vblank on the requested crtc (r1xx-r4xx). |
|
- | 77 | */ |
|
- | 78 | void r100_wait_for_vblank(struct radeon_device *rdev, int crtc) |
|
- | 79 | { |
|
- | 80 | int i; |
|
- | 81 | ||
- | 82 | if (crtc >= rdev->num_crtc) |
|
- | 83 | return; |
|
- | 84 | ||
- | 85 | if (crtc == 0) { |
|
- | 86 | if (RREG32(RADEON_CRTC_GEN_CNTL) & RADEON_CRTC_EN) { |
|
- | 87 | for (i = 0; i < rdev->usec_timeout; i++) { |
|
- | 88 | if (!(RREG32(RADEON_CRTC_STATUS) & RADEON_CRTC_VBLANK_CUR)) |
|
- | 89 | break; |
|
- | 90 | udelay(1); |
|
- | 91 | } |
|
- | 92 | for (i = 0; i < rdev->usec_timeout; i++) { |
|
- | 93 | if (RREG32(RADEON_CRTC_STATUS) & RADEON_CRTC_VBLANK_CUR) |
|
- | 94 | break; |
|
- | 95 | udelay(1); |
|
- | 96 | } |
|
- | 97 | } |
|
- | 98 | } else { |
|
- | 99 | if (RREG32(RADEON_CRTC2_GEN_CNTL) & RADEON_CRTC2_EN) { |
|
- | 100 | for (i = 0; i < rdev->usec_timeout; i++) { |
|
- | 101 | if (!(RREG32(RADEON_CRTC2_STATUS) & RADEON_CRTC2_VBLANK_CUR)) |
|
- | 102 | break; |
|
- | 103 | udelay(1); |
|
- | 104 | } |
|
- | 105 | for (i = 0; i < rdev->usec_timeout; i++) { |
|
- | 106 | if (RREG32(RADEON_CRTC2_STATUS) & RADEON_CRTC2_VBLANK_CUR) |
|
- | 107 | break; |
|
- | 108 | udelay(1); |
|
- | 109 | } |
|
66 | * r100,rv100,rs100,rv200,rs200,r200,rv250,rs300,rv280 |
110 | } |
67 | */ |
111 | } |
68 | 112 | } |
|
69 | u32 r100_page_flip(struct radeon_device *rdev, int crtc_id, u64 crtc_base) |
113 | u32 r100_page_flip(struct radeon_device *rdev, int crtc_id, u64 crtc_base) |
- | 114 | { |
|
Line 70... | Line 115... | ||
70 | { |
115 | struct radeon_crtc *radeon_crtc = rdev->mode_info.crtcs[crtc_id]; |
71 | struct radeon_crtc *radeon_crtc = rdev->mode_info.crtcs[crtc_id]; |
116 | u32 tmp = ((u32)crtc_base) | RADEON_CRTC_OFFSET__OFFSET_LOCK; |
72 | u32 tmp = ((u32)crtc_base) | RADEON_CRTC_OFFSET__OFFSET_LOCK; |
117 | int i; |
Line 73... | Line 118... | ||
73 | 118 | ||
- | 119 | /* Lock the graphics update lock */ |
|
74 | /* Lock the graphics update lock */ |
120 | /* update the scanout addresses */ |
- | 121 | WREG32(RADEON_CRTC_OFFSET + radeon_crtc->crtc_offset, tmp); |
|
- | 122 | ||
- | 123 | /* Wait for update_pending to go high. */ |
|
75 | /* update the scanout addresses */ |
124 | for (i = 0; i < rdev->usec_timeout; i++) { |
Line 76... | Line 125... | ||
76 | WREG32(RADEON_CRTC_OFFSET + radeon_crtc->crtc_offset, tmp); |
125 | if (RREG32(RADEON_CRTC_OFFSET + radeon_crtc->crtc_offset) & RADEON_CRTC_OFFSET__GUI_TRIG_OFFSET) |
77 | 126 | break; |
|
78 | /* Wait for update_pending to go high. */ |
127 | udelay(1); |
Line 93... | Line 142... | ||
93 | else |
142 | else |
94 | return true; |
143 | return true; |
95 | } |
144 | } |
Line 96... | Line 145... | ||
96 | 145 | ||
- | 146 | /* hpd for digital panel detect/disconnect */ |
|
- | 147 | /** |
|
- | 148 | * r100_hpd_sense - hpd sense callback. |
|
- | 149 | * |
|
- | 150 | * @rdev: radeon_device pointer |
|
- | 151 | * @hpd: hpd (hotplug detect) pin |
|
- | 152 | * |
|
- | 153 | * Checks if a digital monitor is connected (r1xx-r4xx). |
|
- | 154 | * Returns true if connected, false if not connected. |
|
97 | /* hpd for digital panel detect/disconnect */ |
155 | */ |
98 | bool r100_hpd_sense(struct radeon_device *rdev, enum radeon_hpd_id hpd) |
156 | bool r100_hpd_sense(struct radeon_device *rdev, enum radeon_hpd_id hpd) |
99 | { |
157 | { |
Line 100... | Line 158... | ||
100 | bool connected = false; |
158 | bool connected = false; |
Line 112... | Line 170... | ||
112 | break; |
170 | break; |
113 | } |
171 | } |
114 | return connected; |
172 | return connected; |
115 | } |
173 | } |
Line -... | Line 174... | ||
- | 174 | ||
- | 175 | /** |
|
- | 176 | * r100_hpd_set_polarity - hpd set polarity callback. |
|
- | 177 | * |
|
- | 178 | * @rdev: radeon_device pointer |
|
- | 179 | * @hpd: hpd (hotplug detect) pin |
|
- | 180 | * |
|
- | 181 | * Set the polarity of the hpd pin (r1xx-r4xx). |
|
116 | 182 | */ |
|
117 | void r100_hpd_set_polarity(struct radeon_device *rdev, |
183 | void r100_hpd_set_polarity(struct radeon_device *rdev, |
118 | enum radeon_hpd_id hpd) |
184 | enum radeon_hpd_id hpd) |
119 | { |
185 | { |
120 | u32 tmp; |
186 | u32 tmp; |
Line 140... | Line 206... | ||
140 | default: |
206 | default: |
141 | break; |
207 | break; |
142 | } |
208 | } |
143 | } |
209 | } |
Line -... | Line 210... | ||
- | 210 | ||
- | 211 | /** |
|
- | 212 | * r100_hpd_init - hpd setup callback. |
|
- | 213 | * |
|
- | 214 | * @rdev: radeon_device pointer |
|
- | 215 | * |
|
- | 216 | * Setup the hpd pins used by the card (r1xx-r4xx). |
|
- | 217 | * Set the polarity, and enable the hpd interrupts. |
|
144 | 218 | */ |
|
145 | void r100_hpd_init(struct radeon_device *rdev) |
219 | void r100_hpd_init(struct radeon_device *rdev) |
146 | { |
220 | { |
147 | struct drm_device *dev = rdev->ddev; |
221 | struct drm_device *dev = rdev->ddev; |
- | 222 | struct drm_connector *connector; |
|
Line 148... | Line 223... | ||
148 | struct drm_connector *connector; |
223 | unsigned enable = 0; |
149 | 224 | ||
150 | list_for_each_entry(connector, &dev->mode_config.connector_list, head) { |
225 | list_for_each_entry(connector, &dev->mode_config.connector_list, head) { |
151 | struct radeon_connector *radeon_connector = to_radeon_connector(connector); |
- | |
152 | switch (radeon_connector->hpd.hpd) { |
- | |
153 | case RADEON_HPD_1: |
- | |
154 | rdev->irq.hpd[0] = true; |
- | |
155 | break; |
226 | struct radeon_connector *radeon_connector = to_radeon_connector(connector); |
156 | case RADEON_HPD_2: |
- | |
157 | rdev->irq.hpd[1] = true; |
- | |
158 | break; |
- | |
159 | default: |
- | |
160 | break; |
227 | enable |= 1 << radeon_connector->hpd.hpd; |
161 | } |
- | |
162 | } |
228 | radeon_hpd_set_polarity(rdev, radeon_connector->hpd.hpd); |
163 | if (rdev->irq.installed) |
229 | } |
Line -... | Line 230... | ||
- | 230 | // radeon_irq_kms_enable_hpd(rdev, enable); |
|
- | 231 | } |
|
- | 232 | ||
- | 233 | /** |
|
- | 234 | * r100_hpd_fini - hpd tear down callback. |
|
- | 235 | * |
|
- | 236 | * @rdev: radeon_device pointer |
|
- | 237 | * |
|
164 | r100_irq_set(rdev); |
238 | * Tear down the hpd pins used by the card (r1xx-r4xx). |
165 | } |
239 | * Disable the hpd interrupts. |
166 | 240 | */ |
|
167 | void r100_hpd_fini(struct radeon_device *rdev) |
241 | void r100_hpd_fini(struct radeon_device *rdev) |
- | 242 | { |
|
Line 168... | Line 243... | ||
168 | { |
243 | struct drm_device *dev = rdev->ddev; |
169 | struct drm_device *dev = rdev->ddev; |
244 | struct drm_connector *connector; |
170 | struct drm_connector *connector; |
245 | unsigned disable = 0; |
171 | - | ||
172 | list_for_each_entry(connector, &dev->mode_config.connector_list, head) { |
- | |
173 | struct radeon_connector *radeon_connector = to_radeon_connector(connector); |
- | |
174 | switch (radeon_connector->hpd.hpd) { |
- | |
175 | case RADEON_HPD_1: |
- | |
176 | rdev->irq.hpd[0] = false; |
- | |
177 | break; |
- | |
178 | case RADEON_HPD_2: |
- | |
179 | rdev->irq.hpd[1] = false; |
- | |
180 | break; |
246 | |
- | 247 | list_for_each_entry(connector, &dev->mode_config.connector_list, head) { |
|
181 | default: |
248 | struct radeon_connector *radeon_connector = to_radeon_connector(connector); |
Line 182... | Line 249... | ||
182 | break; |
249 | disable |= 1 << radeon_connector->hpd.hpd; |
183 | } |
250 | } |
184 | } |
251 | // radeon_irq_kms_disable_hpd(rdev, disable); |
Line 197... | Line 264... | ||
197 | 264 | ||
198 | int r100_pci_gart_init(struct radeon_device *rdev) |
265 | int r100_pci_gart_init(struct radeon_device *rdev) |
199 | { |
266 | { |
Line 200... | Line 267... | ||
200 | int r; |
267 | int r; |
201 | 268 | ||
202 | if (rdev->gart.table.ram.ptr) { |
269 | if (rdev->gart.ptr) { |
203 | WARN(1, "R100 PCI GART already initialized\n"); |
270 | WARN(1, "R100 PCI GART already initialized\n"); |
204 | return 0; |
271 | return 0; |
205 | } |
272 | } |
206 | /* Initialize common gart structure */ |
273 | /* Initialize common gart structure */ |
207 | r = radeon_gart_init(rdev); |
274 | r = radeon_gart_init(rdev); |
208 | if (r) |
275 | if (r) |
209 | return r; |
276 | return r; |
210 | rdev->gart.table_size = rdev->gart.num_gpu_pages * 4; |
277 | rdev->gart.table_size = rdev->gart.num_gpu_pages * 4; |
211 | rdev->asic->gart_tlb_flush = &r100_pci_gart_tlb_flush; |
278 | rdev->asic->gart.tlb_flush = &r100_pci_gart_tlb_flush; |
212 | rdev->asic->gart_set_page = &r100_pci_gart_set_page; |
279 | rdev->asic->gart.set_page = &r100_pci_gart_set_page; |
Line 213... | Line -... | ||
213 | return radeon_gart_table_ram_alloc(rdev); |
- | |
214 | } |
- | |
215 | - | ||
216 | /* required on r1xx, r2xx, r300, r(v)350, r420/r481, rs400/rs480 */ |
- | |
217 | void r100_enable_bm(struct radeon_device *rdev) |
- | |
218 | { |
- | |
219 | uint32_t tmp; |
- | |
220 | /* Enable bus mastering */ |
- | |
221 | tmp = RREG32(RADEON_BUS_CNTL) & ~RADEON_BUS_MASTER_DIS; |
- | |
222 | WREG32(RADEON_BUS_CNTL, tmp); |
280 | return radeon_gart_table_ram_alloc(rdev); |
223 | } |
281 | } |
224 | 282 | ||
Line 225... | Line 283... | ||
225 | int r100_pci_gart_enable(struct radeon_device *rdev) |
283 | int r100_pci_gart_enable(struct radeon_device *rdev) |
Line 236... | Line 294... | ||
236 | /* set PCI GART page-table base address */ |
294 | /* set PCI GART page-table base address */ |
237 | WREG32(RADEON_AIC_PT_BASE, rdev->gart.table_addr); |
295 | WREG32(RADEON_AIC_PT_BASE, rdev->gart.table_addr); |
238 | tmp = RREG32(RADEON_AIC_CNTL) | RADEON_PCIGART_TRANSLATE_EN; |
296 | tmp = RREG32(RADEON_AIC_CNTL) | RADEON_PCIGART_TRANSLATE_EN; |
239 | WREG32(RADEON_AIC_CNTL, tmp); |
297 | WREG32(RADEON_AIC_CNTL, tmp); |
240 | r100_pci_gart_tlb_flush(rdev); |
298 | r100_pci_gart_tlb_flush(rdev); |
- | 299 | DRM_INFO("PCI GART of %uM enabled (table at 0x%016llX).\n", |
|
- | 300 | (unsigned)(rdev->mc.gtt_size >> 20), |
|
- | 301 | (unsigned long long)rdev->gart.table_addr); |
|
241 | rdev->gart.ready = true; |
302 | rdev->gart.ready = true; |
242 | return 0; |
303 | return 0; |
243 | } |
304 | } |
Line 244... | Line 305... | ||
244 | 305 | ||
Line 253... | Line 314... | ||
253 | WREG32(RADEON_AIC_HI_ADDR, 0); |
314 | WREG32(RADEON_AIC_HI_ADDR, 0); |
254 | } |
315 | } |
Line 255... | Line 316... | ||
255 | 316 | ||
256 | int r100_pci_gart_set_page(struct radeon_device *rdev, int i, uint64_t addr) |
317 | int r100_pci_gart_set_page(struct radeon_device *rdev, int i, uint64_t addr) |
- | 318 | { |
|
- | 319 | u32 *gtt = rdev->gart.ptr; |
|
257 | { |
320 | |
258 | if (i < 0 || i > rdev->gart.num_gpu_pages) { |
321 | if (i < 0 || i > rdev->gart.num_gpu_pages) { |
259 | return -EINVAL; |
322 | return -EINVAL; |
260 | } |
323 | } |
261 | rdev->gart.table.ram.ptr[i] = cpu_to_le32(lower_32_bits(addr)); |
324 | gtt[i] = cpu_to_le32(lower_32_bits(addr)); |
262 | return 0; |
325 | return 0; |
Line 263... | Line 326... | ||
263 | } |
326 | } |
264 | 327 | ||
Line 276... | Line 339... | ||
276 | if (!rdev->irq.installed) { |
339 | if (!rdev->irq.installed) { |
277 | WARN(1, "Can't enable IRQ/MSI because no handler is installed\n"); |
340 | WARN(1, "Can't enable IRQ/MSI because no handler is installed\n"); |
278 | WREG32(R_000040_GEN_INT_CNTL, 0); |
341 | WREG32(R_000040_GEN_INT_CNTL, 0); |
279 | return -EINVAL; |
342 | return -EINVAL; |
280 | } |
343 | } |
281 | if (rdev->irq.sw_int) { |
344 | if (atomic_read(&rdev->irq.ring_int[RADEON_RING_TYPE_GFX_INDEX])) { |
282 | tmp |= RADEON_SW_INT_ENABLE; |
345 | tmp |= RADEON_SW_INT_ENABLE; |
283 | } |
346 | } |
284 | if (rdev->irq.gui_idle) { |
- | |
285 | tmp |= RADEON_GUI_IDLE_MASK; |
- | |
286 | } |
- | |
287 | if (rdev->irq.crtc_vblank_int[0] || |
347 | if (rdev->irq.crtc_vblank_int[0] || |
288 | rdev->irq.pflip[0]) { |
348 | atomic_read(&rdev->irq.pflip[0])) { |
289 | tmp |= RADEON_CRTC_VBLANK_MASK; |
349 | tmp |= RADEON_CRTC_VBLANK_MASK; |
290 | } |
350 | } |
291 | if (rdev->irq.crtc_vblank_int[1] || |
351 | if (rdev->irq.crtc_vblank_int[1] || |
292 | rdev->irq.pflip[1]) { |
352 | atomic_read(&rdev->irq.pflip[1])) { |
293 | tmp |= RADEON_CRTC2_VBLANK_MASK; |
353 | tmp |= RADEON_CRTC2_VBLANK_MASK; |
294 | } |
354 | } |
295 | if (rdev->irq.hpd[0]) { |
355 | if (rdev->irq.hpd[0]) { |
296 | tmp |= RADEON_FP_DETECT_MASK; |
356 | tmp |= RADEON_FP_DETECT_MASK; |
297 | } |
357 | } |
Line 311... | Line 371... | ||
311 | mdelay(1); |
371 | mdelay(1); |
312 | tmp = RREG32(R_000044_GEN_INT_STATUS); |
372 | tmp = RREG32(R_000044_GEN_INT_STATUS); |
313 | WREG32(R_000044_GEN_INT_STATUS, tmp); |
373 | WREG32(R_000044_GEN_INT_STATUS, tmp); |
314 | } |
374 | } |
Line 315... | Line 375... | ||
315 | 375 | ||
316 | static inline uint32_t r100_irq_ack(struct radeon_device *rdev) |
376 | static uint32_t r100_irq_ack(struct radeon_device *rdev) |
317 | { |
377 | { |
318 | uint32_t irqs = RREG32(RADEON_GEN_INT_STATUS); |
378 | uint32_t irqs = RREG32(RADEON_GEN_INT_STATUS); |
319 | uint32_t irq_mask = RADEON_SW_INT_TEST | |
379 | uint32_t irq_mask = RADEON_SW_INT_TEST | |
320 | RADEON_CRTC_VBLANK_STAT | RADEON_CRTC2_VBLANK_STAT | |
380 | RADEON_CRTC_VBLANK_STAT | RADEON_CRTC2_VBLANK_STAT | |
Line 321... | Line -... | ||
321 | RADEON_FP_DETECT_STAT | RADEON_FP2_DETECT_STAT; |
- | |
322 | - | ||
323 | /* the interrupt works, but the status bit is permanently asserted */ |
- | |
324 | if (rdev->irq.gui_idle && radeon_gui_idle(rdev)) { |
- | |
325 | if (!rdev->irq.gui_idle_acked) |
- | |
326 | irq_mask |= RADEON_GUI_IDLE_STAT; |
- | |
327 | } |
381 | RADEON_FP_DETECT_STAT | RADEON_FP2_DETECT_STAT; |
328 | 382 | ||
329 | if (irqs) { |
383 | if (irqs) { |
330 | WREG32(RADEON_GEN_INT_STATUS, irqs); |
384 | WREG32(RADEON_GEN_INT_STATUS, irqs); |
331 | } |
385 | } |
Line 335... | Line 389... | ||
335 | int r100_irq_process(struct radeon_device *rdev) |
389 | int r100_irq_process(struct radeon_device *rdev) |
336 | { |
390 | { |
337 | uint32_t status, msi_rearm; |
391 | uint32_t status, msi_rearm; |
338 | bool queue_hotplug = false; |
392 | bool queue_hotplug = false; |
Line 339... | Line -... | ||
339 | - | ||
340 | /* reset gui idle ack. the status bit is broken */ |
- | |
341 | rdev->irq.gui_idle_acked = false; |
- | |
342 | 393 | ||
343 | status = r100_irq_ack(rdev); |
394 | status = r100_irq_ack(rdev); |
344 | if (!status) { |
395 | if (!status) { |
345 | return IRQ_NONE; |
396 | return IRQ_NONE; |
346 | } |
397 | } |
347 | if (rdev->shutdown) { |
398 | if (rdev->shutdown) { |
348 | return IRQ_NONE; |
399 | return IRQ_NONE; |
349 | } |
400 | } |
350 | while (status) { |
401 | while (status) { |
351 | /* SW interrupt */ |
402 | /* SW interrupt */ |
352 | if (status & RADEON_SW_INT_TEST) { |
403 | if (status & RADEON_SW_INT_TEST) { |
353 | radeon_fence_process(rdev); |
- | |
354 | } |
- | |
355 | /* gui idle interrupt */ |
- | |
356 | if (status & RADEON_GUI_IDLE_STAT) { |
- | |
357 | rdev->irq.gui_idle_acked = true; |
- | |
358 | rdev->pm.gui_idle = true; |
- | |
359 | // wake_up(&rdev->irq.idle_queue); |
404 | radeon_fence_process(rdev, RADEON_RING_TYPE_GFX_INDEX); |
360 | } |
405 | } |
361 | /* Vertical blank interrupts */ |
406 | /* Vertical blank interrupts */ |
362 | if (status & RADEON_CRTC_VBLANK_STAT) { |
407 | if (status & RADEON_CRTC_VBLANK_STAT) { |
363 | if (rdev->irq.crtc_vblank_int[0]) { |
408 | if (rdev->irq.crtc_vblank_int[0]) { |
Line 385... | Line 430... | ||
385 | queue_hotplug = true; |
430 | queue_hotplug = true; |
386 | DRM_DEBUG("HPD2\n"); |
431 | DRM_DEBUG("HPD2\n"); |
387 | } |
432 | } |
388 | status = r100_irq_ack(rdev); |
433 | status = r100_irq_ack(rdev); |
389 | } |
434 | } |
390 | /* reset gui idle ack. the status bit is broken */ |
- | |
391 | rdev->irq.gui_idle_acked = false; |
- | |
392 | // if (queue_hotplug) |
435 | // if (queue_hotplug) |
393 | // schedule_work(&rdev->hotplug_work); |
436 | // schedule_work(&rdev->hotplug_work); |
394 | if (rdev->msi_enabled) { |
437 | if (rdev->msi_enabled) { |
395 | switch (rdev->family) { |
438 | switch (rdev->family) { |
396 | case CHIP_RS400: |
439 | case CHIP_RS400: |
Line 398... | Line 441... | ||
398 | msi_rearm = RREG32(RADEON_AIC_CNTL) & ~RS400_MSI_REARM; |
441 | msi_rearm = RREG32(RADEON_AIC_CNTL) & ~RS400_MSI_REARM; |
399 | WREG32(RADEON_AIC_CNTL, msi_rearm); |
442 | WREG32(RADEON_AIC_CNTL, msi_rearm); |
400 | WREG32(RADEON_AIC_CNTL, msi_rearm | RS400_MSI_REARM); |
443 | WREG32(RADEON_AIC_CNTL, msi_rearm | RS400_MSI_REARM); |
401 | break; |
444 | break; |
402 | default: |
445 | default: |
403 | msi_rearm = RREG32(RADEON_MSI_REARM_EN) & ~RV370_MSI_REARM_EN; |
- | |
404 | WREG32(RADEON_MSI_REARM_EN, msi_rearm); |
- | |
405 | WREG32(RADEON_MSI_REARM_EN, msi_rearm | RV370_MSI_REARM_EN); |
446 | WREG32(RADEON_MSI_REARM_EN, RV370_MSI_REARM_EN); |
406 | break; |
447 | break; |
407 | } |
448 | } |
408 | } |
449 | } |
409 | return IRQ_HANDLED; |
450 | return IRQ_HANDLED; |
410 | } |
451 | } |
Line 420... | Line 461... | ||
420 | /* Who ever call radeon_fence_emit should call ring_lock and ask |
461 | /* Who ever call radeon_fence_emit should call ring_lock and ask |
421 | * for enough space (today caller are ib schedule and buffer move) */ |
462 | * for enough space (today caller are ib schedule and buffer move) */ |
422 | void r100_fence_ring_emit(struct radeon_device *rdev, |
463 | void r100_fence_ring_emit(struct radeon_device *rdev, |
423 | struct radeon_fence *fence) |
464 | struct radeon_fence *fence) |
424 | { |
465 | { |
- | 466 | struct radeon_ring *ring = &rdev->ring[fence->ring]; |
|
- | 467 | ||
425 | /* We have to make sure that caches are flushed before |
468 | /* We have to make sure that caches are flushed before |
426 | * CPU might read something from VRAM. */ |
469 | * CPU might read something from VRAM. */ |
427 | radeon_ring_write(rdev, PACKET0(RADEON_RB3D_DSTCACHE_CTLSTAT, 0)); |
470 | radeon_ring_write(ring, PACKET0(RADEON_RB3D_DSTCACHE_CTLSTAT, 0)); |
428 | radeon_ring_write(rdev, RADEON_RB3D_DC_FLUSH_ALL); |
471 | radeon_ring_write(ring, RADEON_RB3D_DC_FLUSH_ALL); |
429 | radeon_ring_write(rdev, PACKET0(RADEON_RB3D_ZCACHE_CTLSTAT, 0)); |
472 | radeon_ring_write(ring, PACKET0(RADEON_RB3D_ZCACHE_CTLSTAT, 0)); |
430 | radeon_ring_write(rdev, RADEON_RB3D_ZC_FLUSH_ALL); |
473 | radeon_ring_write(ring, RADEON_RB3D_ZC_FLUSH_ALL); |
431 | /* Wait until IDLE & CLEAN */ |
474 | /* Wait until IDLE & CLEAN */ |
432 | radeon_ring_write(rdev, PACKET0(RADEON_WAIT_UNTIL, 0)); |
475 | radeon_ring_write(ring, PACKET0(RADEON_WAIT_UNTIL, 0)); |
433 | radeon_ring_write(rdev, RADEON_WAIT_2D_IDLECLEAN | RADEON_WAIT_3D_IDLECLEAN); |
476 | radeon_ring_write(ring, RADEON_WAIT_2D_IDLECLEAN | RADEON_WAIT_3D_IDLECLEAN); |
434 | radeon_ring_write(rdev, PACKET0(RADEON_HOST_PATH_CNTL, 0)); |
477 | radeon_ring_write(ring, PACKET0(RADEON_HOST_PATH_CNTL, 0)); |
435 | radeon_ring_write(rdev, rdev->config.r100.hdp_cntl | |
478 | radeon_ring_write(ring, rdev->config.r100.hdp_cntl | |
436 | RADEON_HDP_READ_BUFFER_INVALIDATE); |
479 | RADEON_HDP_READ_BUFFER_INVALIDATE); |
437 | radeon_ring_write(rdev, PACKET0(RADEON_HOST_PATH_CNTL, 0)); |
480 | radeon_ring_write(ring, PACKET0(RADEON_HOST_PATH_CNTL, 0)); |
438 | radeon_ring_write(rdev, rdev->config.r100.hdp_cntl); |
481 | radeon_ring_write(ring, rdev->config.r100.hdp_cntl); |
439 | /* Emit fence sequence & fire IRQ */ |
482 | /* Emit fence sequence & fire IRQ */ |
440 | radeon_ring_write(rdev, PACKET0(rdev->fence_drv.scratch_reg, 0)); |
483 | radeon_ring_write(ring, PACKET0(rdev->fence_drv[fence->ring].scratch_reg, 0)); |
441 | radeon_ring_write(rdev, fence->seq); |
484 | radeon_ring_write(ring, fence->seq); |
442 | radeon_ring_write(rdev, PACKET0(RADEON_GEN_INT_STATUS, 0)); |
485 | radeon_ring_write(ring, PACKET0(RADEON_GEN_INT_STATUS, 0)); |
443 | radeon_ring_write(rdev, RADEON_SW_INT_FIRE); |
486 | radeon_ring_write(ring, RADEON_SW_INT_FIRE); |
- | 487 | } |
|
- | 488 | ||
- | 489 | void r100_semaphore_ring_emit(struct radeon_device *rdev, |
|
- | 490 | struct radeon_ring *ring, |
|
- | 491 | struct radeon_semaphore *semaphore, |
|
- | 492 | bool emit_wait) |
|
- | 493 | { |
|
- | 494 | /* Unused on older asics, since we don't have semaphores or multiple rings */ |
|
- | 495 | BUG(); |
|
444 | } |
496 | } |
Line 445... | Line 497... | ||
445 | 497 | ||
446 | int r100_copy_blit(struct radeon_device *rdev, |
498 | int r100_copy_blit(struct radeon_device *rdev, |
447 | uint64_t src_offset, |
499 | uint64_t src_offset, |
448 | uint64_t dst_offset, |
500 | uint64_t dst_offset, |
449 | unsigned num_pages, |
501 | unsigned num_gpu_pages, |
450 | struct radeon_fence *fence) |
502 | struct radeon_fence **fence) |
- | 503 | { |
|
451 | { |
504 | struct radeon_ring *ring = &rdev->ring[RADEON_RING_TYPE_GFX_INDEX]; |
452 | uint32_t cur_pages; |
505 | uint32_t cur_pages; |
453 | uint32_t stride_bytes = PAGE_SIZE; |
506 | uint32_t stride_bytes = RADEON_GPU_PAGE_SIZE; |
454 | uint32_t pitch; |
507 | uint32_t pitch; |
455 | uint32_t stride_pixels; |
508 | uint32_t stride_pixels; |
456 | unsigned ndw; |
509 | unsigned ndw; |
457 | int num_loops; |
510 | int num_loops; |
Line 460... | Line 513... | ||
460 | /* radeon limited to 16k stride */ |
513 | /* radeon limited to 16k stride */ |
461 | stride_bytes &= 0x3fff; |
514 | stride_bytes &= 0x3fff; |
462 | /* radeon pitch is /64 */ |
515 | /* radeon pitch is /64 */ |
463 | pitch = stride_bytes / 64; |
516 | pitch = stride_bytes / 64; |
464 | stride_pixels = stride_bytes / 4; |
517 | stride_pixels = stride_bytes / 4; |
465 | num_loops = DIV_ROUND_UP(num_pages, 8191); |
518 | num_loops = DIV_ROUND_UP(num_gpu_pages, 8191); |
Line 466... | Line 519... | ||
466 | 519 | ||
467 | /* Ask for enough room for blit + flush + fence */ |
520 | /* Ask for enough room for blit + flush + fence */ |
468 | ndw = 64 + (10 * num_loops); |
521 | ndw = 64 + (10 * num_loops); |
469 | r = radeon_ring_lock(rdev, ndw); |
522 | r = radeon_ring_lock(rdev, ring, ndw); |
470 | if (r) { |
523 | if (r) { |
471 | DRM_ERROR("radeon: moving bo (%d) asking for %u dw.\n", r, ndw); |
524 | DRM_ERROR("radeon: moving bo (%d) asking for %u dw.\n", r, ndw); |
472 | return -EINVAL; |
525 | return -EINVAL; |
473 | } |
526 | } |
474 | while (num_pages > 0) { |
527 | while (num_gpu_pages > 0) { |
475 | cur_pages = num_pages; |
528 | cur_pages = num_gpu_pages; |
476 | if (cur_pages > 8191) { |
529 | if (cur_pages > 8191) { |
477 | cur_pages = 8191; |
530 | cur_pages = 8191; |
478 | } |
531 | } |
Line 479... | Line 532... | ||
479 | num_pages -= cur_pages; |
532 | num_gpu_pages -= cur_pages; |
480 | 533 | ||
481 | /* pages are in Y direction - height |
534 | /* pages are in Y direction - height |
482 | page width in X direction - width */ |
535 | page width in X direction - width */ |
483 | radeon_ring_write(rdev, PACKET3(PACKET3_BITBLT_MULTI, 8)); |
536 | radeon_ring_write(ring, PACKET3(PACKET3_BITBLT_MULTI, 8)); |
484 | radeon_ring_write(rdev, |
537 | radeon_ring_write(ring, |
485 | RADEON_GMC_SRC_PITCH_OFFSET_CNTL | |
538 | RADEON_GMC_SRC_PITCH_OFFSET_CNTL | |
486 | RADEON_GMC_DST_PITCH_OFFSET_CNTL | |
539 | RADEON_GMC_DST_PITCH_OFFSET_CNTL | |
487 | RADEON_GMC_SRC_CLIPPING | |
540 | RADEON_GMC_SRC_CLIPPING | |
Line 491... | Line 544... | ||
491 | RADEON_GMC_SRC_DATATYPE_COLOR | |
544 | RADEON_GMC_SRC_DATATYPE_COLOR | |
492 | RADEON_ROP3_S | |
545 | RADEON_ROP3_S | |
493 | RADEON_DP_SRC_SOURCE_MEMORY | |
546 | RADEON_DP_SRC_SOURCE_MEMORY | |
494 | RADEON_GMC_CLR_CMP_CNTL_DIS | |
547 | RADEON_GMC_CLR_CMP_CNTL_DIS | |
495 | RADEON_GMC_WR_MSK_DIS); |
548 | RADEON_GMC_WR_MSK_DIS); |
496 | radeon_ring_write(rdev, (pitch << 22) | (src_offset >> 10)); |
549 | radeon_ring_write(ring, (pitch << 22) | (src_offset >> 10)); |
497 | radeon_ring_write(rdev, (pitch << 22) | (dst_offset >> 10)); |
550 | radeon_ring_write(ring, (pitch << 22) | (dst_offset >> 10)); |
498 | radeon_ring_write(rdev, (0x1fff) | (0x1fff << 16)); |
551 | radeon_ring_write(ring, (0x1fff) | (0x1fff << 16)); |
499 | radeon_ring_write(rdev, 0); |
552 | radeon_ring_write(ring, 0); |
500 | radeon_ring_write(rdev, (0x1fff) | (0x1fff << 16)); |
553 | radeon_ring_write(ring, (0x1fff) | (0x1fff << 16)); |
501 | radeon_ring_write(rdev, num_pages); |
554 | radeon_ring_write(ring, num_gpu_pages); |
502 | radeon_ring_write(rdev, num_pages); |
555 | radeon_ring_write(ring, num_gpu_pages); |
503 | radeon_ring_write(rdev, cur_pages | (stride_pixels << 16)); |
556 | radeon_ring_write(ring, cur_pages | (stride_pixels << 16)); |
504 | } |
557 | } |
505 | radeon_ring_write(rdev, PACKET0(RADEON_DSTCACHE_CTLSTAT, 0)); |
558 | radeon_ring_write(ring, PACKET0(RADEON_DSTCACHE_CTLSTAT, 0)); |
506 | radeon_ring_write(rdev, RADEON_RB2D_DC_FLUSH_ALL); |
559 | radeon_ring_write(ring, RADEON_RB2D_DC_FLUSH_ALL); |
507 | radeon_ring_write(rdev, PACKET0(RADEON_WAIT_UNTIL, 0)); |
560 | radeon_ring_write(ring, PACKET0(RADEON_WAIT_UNTIL, 0)); |
508 | radeon_ring_write(rdev, |
561 | radeon_ring_write(ring, |
509 | RADEON_WAIT_2D_IDLECLEAN | |
562 | RADEON_WAIT_2D_IDLECLEAN | |
510 | RADEON_WAIT_HOST_IDLECLEAN | |
563 | RADEON_WAIT_HOST_IDLECLEAN | |
511 | RADEON_WAIT_DMA_GUI_IDLE); |
564 | RADEON_WAIT_DMA_GUI_IDLE); |
512 | if (fence) { |
565 | if (fence) { |
513 | r = radeon_fence_emit(rdev, fence); |
566 | r = radeon_fence_emit(rdev, fence, RADEON_RING_TYPE_GFX_INDEX); |
514 | } |
567 | } |
515 | radeon_ring_unlock_commit(rdev); |
568 | radeon_ring_unlock_commit(rdev, ring); |
516 | return r; |
569 | return r; |
517 | } |
570 | } |
Line 518... | Line 571... | ||
518 | 571 | ||
519 | static int r100_cp_wait_for_idle(struct radeon_device *rdev) |
572 | static int r100_cp_wait_for_idle(struct radeon_device *rdev) |
Line 529... | Line 582... | ||
529 | udelay(1); |
582 | udelay(1); |
530 | } |
583 | } |
531 | return -1; |
584 | return -1; |
532 | } |
585 | } |
Line 533... | Line 586... | ||
533 | 586 | ||
534 | void r100_ring_start(struct radeon_device *rdev) |
587 | void r100_ring_start(struct radeon_device *rdev, struct radeon_ring *ring) |
535 | { |
588 | { |
Line 536... | Line 589... | ||
536 | int r; |
589 | int r; |
537 | 590 | ||
538 | r = radeon_ring_lock(rdev, 2); |
591 | r = radeon_ring_lock(rdev, ring, 2); |
539 | if (r) { |
592 | if (r) { |
540 | return; |
593 | return; |
541 | } |
594 | } |
542 | radeon_ring_write(rdev, PACKET0(RADEON_ISYNC_CNTL, 0)); |
595 | radeon_ring_write(ring, PACKET0(RADEON_ISYNC_CNTL, 0)); |
543 | radeon_ring_write(rdev, |
596 | radeon_ring_write(ring, |
544 | RADEON_ISYNC_ANY2D_IDLE3D | |
597 | RADEON_ISYNC_ANY2D_IDLE3D | |
545 | RADEON_ISYNC_ANY3D_IDLE2D | |
598 | RADEON_ISYNC_ANY3D_IDLE2D | |
546 | RADEON_ISYNC_WAIT_IDLEGUI | |
599 | RADEON_ISYNC_WAIT_IDLEGUI | |
547 | RADEON_ISYNC_CPSCRATCH_IDLEGUI); |
600 | RADEON_ISYNC_CPSCRATCH_IDLEGUI); |
Line 548... | Line 601... | ||
548 | radeon_ring_unlock_commit(rdev); |
601 | radeon_ring_unlock_commit(rdev, ring); |
549 | } |
602 | } |
Line 644... | Line 697... | ||
644 | } |
697 | } |
645 | } |
698 | } |
Line 646... | Line 699... | ||
646 | 699 | ||
647 | int r100_cp_init(struct radeon_device *rdev, unsigned ring_size) |
700 | int r100_cp_init(struct radeon_device *rdev, unsigned ring_size) |
- | 701 | { |
|
648 | { |
702 | struct radeon_ring *ring = &rdev->ring[RADEON_RING_TYPE_GFX_INDEX]; |
649 | unsigned rb_bufsz; |
703 | unsigned rb_bufsz; |
650 | unsigned rb_blksz; |
704 | unsigned rb_blksz; |
651 | unsigned max_fetch; |
705 | unsigned max_fetch; |
652 | unsigned pre_write_timer; |
706 | unsigned pre_write_timer; |
Line 669... | Line 723... | ||
669 | 723 | ||
670 | /* Align ring size */ |
724 | /* Align ring size */ |
671 | rb_bufsz = drm_order(ring_size / 8); |
725 | rb_bufsz = drm_order(ring_size / 8); |
672 | ring_size = (1 << (rb_bufsz + 1)) * 4; |
726 | ring_size = (1 << (rb_bufsz + 1)) * 4; |
673 | r100_cp_load_microcode(rdev); |
727 | r100_cp_load_microcode(rdev); |
- | 728 | r = radeon_ring_init(rdev, ring, ring_size, RADEON_WB_CP_RPTR_OFFSET, |
|
- | 729 | RADEON_CP_RB_RPTR, RADEON_CP_RB_WPTR, |
|
674 | r = radeon_ring_init(rdev, ring_size); |
730 | 0, 0x7fffff, RADEON_CP_PACKET2); |
675 | if (r) { |
731 | if (r) { |
676 | return r; |
732 | return r; |
677 | } |
733 | } |
678 | /* Each time the cp read 1024 bytes (16 dword/quadword) update |
734 | /* Each time the cp read 1024 bytes (16 dword/quadword) update |
679 | * the rptr copy in system ram */ |
735 | * the rptr copy in system ram */ |
680 | rb_blksz = 9; |
736 | rb_blksz = 9; |
681 | /* cp will read 128bytes at a time (4 dwords) */ |
737 | /* cp will read 128bytes at a time (4 dwords) */ |
682 | max_fetch = 1; |
738 | max_fetch = 1; |
683 | rdev->cp.align_mask = 16 - 1; |
739 | ring->align_mask = 16 - 1; |
684 | /* Write to CP_RB_WPTR will be delayed for pre_write_timer clocks */ |
740 | /* Write to CP_RB_WPTR will be delayed for pre_write_timer clocks */ |
685 | pre_write_timer = 64; |
741 | pre_write_timer = 64; |
686 | /* Force CP_RB_WPTR write if written more than one time before the |
742 | /* Force CP_RB_WPTR write if written more than one time before the |
687 | * delay expire |
743 | * delay expire |
Line 708... | Line 764... | ||
708 | tmp |= RADEON_BUF_SWAP_32BIT; |
764 | tmp |= RADEON_BUF_SWAP_32BIT; |
709 | #endif |
765 | #endif |
710 | WREG32(RADEON_CP_RB_CNTL, tmp | RADEON_RB_NO_UPDATE); |
766 | WREG32(RADEON_CP_RB_CNTL, tmp | RADEON_RB_NO_UPDATE); |
Line 711... | Line 767... | ||
711 | 767 | ||
712 | /* Set ring address */ |
768 | /* Set ring address */ |
713 | DRM_INFO("radeon: ring at 0x%016lX\n", (unsigned long)rdev->cp.gpu_addr); |
769 | DRM_INFO("radeon: ring at 0x%016lX\n", (unsigned long)ring->gpu_addr); |
714 | WREG32(RADEON_CP_RB_BASE, rdev->cp.gpu_addr); |
770 | WREG32(RADEON_CP_RB_BASE, ring->gpu_addr); |
715 | /* Force read & write ptr to 0 */ |
771 | /* Force read & write ptr to 0 */ |
716 | WREG32(RADEON_CP_RB_CNTL, tmp | RADEON_RB_RPTR_WR_ENA | RADEON_RB_NO_UPDATE); |
772 | WREG32(RADEON_CP_RB_CNTL, tmp | RADEON_RB_RPTR_WR_ENA | RADEON_RB_NO_UPDATE); |
- | 773 | WREG32(RADEON_CP_RB_RPTR_WR, 0); |
|
717 | WREG32(RADEON_CP_RB_RPTR_WR, 0); |
774 | ring->wptr = 0; |
Line 718... | Line 775... | ||
718 | WREG32(RADEON_CP_RB_WPTR, 0); |
775 | WREG32(RADEON_CP_RB_WPTR, ring->wptr); |
719 | 776 | ||
720 | /* set the wb address whether it's enabled or not */ |
777 | /* set the wb address whether it's enabled or not */ |
721 | WREG32(R_00070C_CP_RB_RPTR_ADDR, |
778 | WREG32(R_00070C_CP_RB_RPTR_ADDR, |
Line 729... | Line 786... | ||
729 | WREG32(R_000770_SCRATCH_UMSK, 0); |
786 | WREG32(R_000770_SCRATCH_UMSK, 0); |
730 | } |
787 | } |
Line 731... | Line 788... | ||
731 | 788 | ||
732 | WREG32(RADEON_CP_RB_CNTL, tmp); |
789 | WREG32(RADEON_CP_RB_CNTL, tmp); |
733 | udelay(10); |
790 | udelay(10); |
734 | rdev->cp.rptr = RREG32(RADEON_CP_RB_RPTR); |
- | |
735 | rdev->cp.wptr = RREG32(RADEON_CP_RB_WPTR); |
- | |
736 | /* protect against crazy HW on resume */ |
- | |
737 | rdev->cp.wptr &= rdev->cp.ptr_mask; |
791 | ring->rptr = RREG32(RADEON_CP_RB_RPTR); |
738 | /* Set cp mode to bus mastering & enable cp*/ |
792 | /* Set cp mode to bus mastering & enable cp*/ |
739 | WREG32(RADEON_CP_CSQ_MODE, |
793 | WREG32(RADEON_CP_CSQ_MODE, |
740 | REG_SET(RADEON_INDIRECT2_START, indirect2_start) | |
794 | REG_SET(RADEON_INDIRECT2_START, indirect2_start) | |
741 | REG_SET(RADEON_INDIRECT1_START, indirect1_start)); |
795 | REG_SET(RADEON_INDIRECT1_START, indirect1_start)); |
742 | WREG32(RADEON_CP_RB_WPTR_DELAY, 0); |
796 | WREG32(RADEON_CP_RB_WPTR_DELAY, 0); |
743 | WREG32(RADEON_CP_CSQ_MODE, 0x00004D4D); |
797 | WREG32(RADEON_CP_CSQ_MODE, 0x00004D4D); |
744 | WREG32(RADEON_CP_CSQ_CNTL, RADEON_CSQ_PRIBM_INDBM); |
798 | WREG32(RADEON_CP_CSQ_CNTL, RADEON_CSQ_PRIBM_INDBM); |
745 | radeon_ring_start(rdev); |
799 | radeon_ring_start(rdev, RADEON_RING_TYPE_GFX_INDEX, &rdev->ring[RADEON_RING_TYPE_GFX_INDEX]); |
746 | r = radeon_ring_test(rdev); |
800 | r = radeon_ring_test(rdev, RADEON_RING_TYPE_GFX_INDEX, ring); |
747 | if (r) { |
801 | if (r) { |
748 | DRM_ERROR("radeon: cp isn't working (%d).\n", r); |
802 | DRM_ERROR("radeon: cp isn't working (%d).\n", r); |
749 | return r; |
803 | return r; |
750 | } |
804 | } |
751 | rdev->cp.ready = true; |
805 | ring->ready = true; |
752 | // radeon_ttm_set_active_vram_size(rdev, rdev->mc.real_vram_size); |
806 | // radeon_ttm_set_active_vram_size(rdev, rdev->mc.real_vram_size); |
753 | return 0; |
807 | return 0; |
Line 754... | Line 808... | ||
754 | } |
808 | } |
Line 758... | Line 812... | ||
758 | if (r100_cp_wait_for_idle(rdev)) { |
812 | if (r100_cp_wait_for_idle(rdev)) { |
759 | DRM_ERROR("Wait for CP idle timeout, shutting down CP.\n"); |
813 | DRM_ERROR("Wait for CP idle timeout, shutting down CP.\n"); |
760 | } |
814 | } |
761 | /* Disable ring */ |
815 | /* Disable ring */ |
762 | r100_cp_disable(rdev); |
816 | r100_cp_disable(rdev); |
763 | radeon_ring_fini(rdev); |
817 | radeon_ring_fini(rdev, &rdev->ring[RADEON_RING_TYPE_GFX_INDEX]); |
764 | DRM_INFO("radeon: cp finalized\n"); |
818 | DRM_INFO("radeon: cp finalized\n"); |
765 | } |
819 | } |
Line 766... | Line 820... | ||
766 | 820 | ||
767 | void r100_cp_disable(struct radeon_device *rdev) |
821 | void r100_cp_disable(struct radeon_device *rdev) |
768 | { |
822 | { |
769 | /* Disable ring */ |
823 | /* Disable ring */ |
770 | // radeon_ttm_set_active_vram_size(rdev, rdev->mc.visible_vram_size); |
824 | // radeon_ttm_set_active_vram_size(rdev, rdev->mc.visible_vram_size); |
771 | rdev->cp.ready = false; |
825 | rdev->ring[RADEON_RING_TYPE_GFX_INDEX].ready = false; |
772 | WREG32(RADEON_CP_CSQ_MODE, 0); |
826 | WREG32(RADEON_CP_CSQ_MODE, 0); |
773 | WREG32(RADEON_CP_CSQ_CNTL, 0); |
827 | WREG32(RADEON_CP_CSQ_CNTL, 0); |
774 | WREG32(R_000770_SCRATCH_UMSK, 0); |
828 | WREG32(R_000770_SCRATCH_UMSK, 0); |
775 | if (r100_gui_wait_for_idle(rdev)) { |
829 | if (r100_gui_wait_for_idle(rdev)) { |
776 | printk(KERN_WARNING "Failed to wait GUI idle while " |
830 | printk(KERN_WARNING "Failed to wait GUI idle while " |
777 | "programming pipes. Bad things might happen.\n"); |
831 | "programming pipes. Bad things might happen.\n"); |
778 | } |
832 | } |
Line 779... | Line -... | ||
779 | } |
- | |
780 | - | ||
781 | void r100_cp_commit(struct radeon_device *rdev) |
- | |
782 | { |
- | |
783 | WREG32(RADEON_CP_RB_WPTR, rdev->cp.wptr); |
- | |
784 | (void)RREG32(RADEON_CP_RB_WPTR); |
- | |
785 | } |
- | |
786 | 833 | } |
|
787 | 834 | ||
788 | #if 0 |
835 | #if 0 |
789 | /* |
836 | /* |
- | 837 | * CS functions |
|
- | 838 | */ |
|
- | 839 | int r100_reloc_pitch_offset(struct radeon_cs_parser *p, |
|
- | 840 | struct radeon_cs_packet *pkt, |
|
- | 841 | unsigned idx, |
|
- | 842 | unsigned reg) |
|
- | 843 | { |
|
- | 844 | int r; |
|
- | 845 | u32 tile_flags = 0; |
|
- | 846 | u32 tmp; |
|
- | 847 | struct radeon_cs_reloc *reloc; |
|
- | 848 | u32 value; |
|
- | 849 | ||
- | 850 | r = r100_cs_packet_next_reloc(p, &reloc); |
|
- | 851 | if (r) { |
|
- | 852 | DRM_ERROR("No reloc for ib[%d]=0x%04X\n", |
|
- | 853 | idx, reg); |
|
- | 854 | r100_cs_dump_packet(p, pkt); |
|
- | 855 | return r; |
|
- | 856 | } |
|
- | 857 | ||
- | 858 | value = radeon_get_ib_value(p, idx); |
|
- | 859 | tmp = value & 0x003fffff; |
|
- | 860 | tmp += (((u32)reloc->lobj.gpu_offset) >> 10); |
|
- | 861 | ||
- | 862 | if (!(p->cs_flags & RADEON_CS_KEEP_TILING_FLAGS)) { |
|
- | 863 | if (reloc->lobj.tiling_flags & RADEON_TILING_MACRO) |
|
- | 864 | tile_flags |= RADEON_DST_TILE_MACRO; |
|
- | 865 | if (reloc->lobj.tiling_flags & RADEON_TILING_MICRO) { |
|
- | 866 | if (reg == RADEON_SRC_PITCH_OFFSET) { |
|
- | 867 | DRM_ERROR("Cannot src blit from microtiled surface\n"); |
|
- | 868 | r100_cs_dump_packet(p, pkt); |
|
- | 869 | return -EINVAL; |
|
- | 870 | } |
|
- | 871 | tile_flags |= RADEON_DST_TILE_MICRO; |
|
- | 872 | } |
|
- | 873 | ||
- | 874 | tmp |= tile_flags; |
|
- | 875 | p->ib.ptr[idx] = (value & 0x3fc00000) | tmp; |
|
- | 876 | } else |
|
- | 877 | p->ib.ptr[idx] = (value & 0xffc00000) | tmp; |
|
- | 878 | return 0; |
|
- | 879 | } |
|
- | 880 | ||
- | 881 | int r100_packet3_load_vbpntr(struct radeon_cs_parser *p, |
|
- | 882 | struct radeon_cs_packet *pkt, |
|
- | 883 | int idx) |
|
- | 884 | { |
|
- | 885 | unsigned c, i; |
|
- | 886 | struct radeon_cs_reloc *reloc; |
|
- | 887 | struct r100_cs_track *track; |
|
- | 888 | int r = 0; |
|
- | 889 | volatile uint32_t *ib; |
|
- | 890 | u32 idx_value; |
|
- | 891 | ||
- | 892 | ib = p->ib.ptr; |
|
- | 893 | track = (struct r100_cs_track *)p->track; |
|
- | 894 | c = radeon_get_ib_value(p, idx++) & 0x1F; |
|
- | 895 | if (c > 16) { |
|
- | 896 | DRM_ERROR("Only 16 vertex buffers are allowed %d\n", |
|
- | 897 | pkt->opcode); |
|
- | 898 | r100_cs_dump_packet(p, pkt); |
|
- | 899 | return -EINVAL; |
|
- | 900 | } |
|
- | 901 | track->num_arrays = c; |
|
- | 902 | for (i = 0; i < (c - 1); i+=2, idx+=3) { |
|
- | 903 | r = r100_cs_packet_next_reloc(p, &reloc); |
|
- | 904 | if (r) { |
|
- | 905 | DRM_ERROR("No reloc for packet3 %d\n", |
|
- | 906 | pkt->opcode); |
|
- | 907 | r100_cs_dump_packet(p, pkt); |
|
- | 908 | return r; |
|
- | 909 | } |
|
- | 910 | idx_value = radeon_get_ib_value(p, idx); |
|
- | 911 | ib[idx+1] = radeon_get_ib_value(p, idx + 1) + ((u32)reloc->lobj.gpu_offset); |
|
- | 912 | ||
- | 913 | track->arrays[i + 0].esize = idx_value >> 8; |
|
- | 914 | track->arrays[i + 0].robj = reloc->robj; |
|
- | 915 | track->arrays[i + 0].esize &= 0x7F; |
|
- | 916 | r = r100_cs_packet_next_reloc(p, &reloc); |
|
- | 917 | if (r) { |
|
- | 918 | DRM_ERROR("No reloc for packet3 %d\n", |
|
- | 919 | pkt->opcode); |
|
- | 920 | r100_cs_dump_packet(p, pkt); |
|
- | 921 | return r; |
|
- | 922 | } |
|
- | 923 | ib[idx+2] = radeon_get_ib_value(p, idx + 2) + ((u32)reloc->lobj.gpu_offset); |
|
- | 924 | track->arrays[i + 1].robj = reloc->robj; |
|
- | 925 | track->arrays[i + 1].esize = idx_value >> 24; |
|
- | 926 | track->arrays[i + 1].esize &= 0x7F; |
|
- | 927 | } |
|
- | 928 | if (c & 1) { |
|
- | 929 | r = r100_cs_packet_next_reloc(p, &reloc); |
|
- | 930 | if (r) { |
|
- | 931 | DRM_ERROR("No reloc for packet3 %d\n", |
|
- | 932 | pkt->opcode); |
|
- | 933 | r100_cs_dump_packet(p, pkt); |
|
- | 934 | return r; |
|
- | 935 | } |
|
- | 936 | idx_value = radeon_get_ib_value(p, idx); |
|
- | 937 | ib[idx+1] = radeon_get_ib_value(p, idx + 1) + ((u32)reloc->lobj.gpu_offset); |
|
- | 938 | track->arrays[i + 0].robj = reloc->robj; |
|
- | 939 | track->arrays[i + 0].esize = idx_value >> 8; |
|
- | 940 | track->arrays[i + 0].esize &= 0x7F; |
|
- | 941 | } |
|
- | 942 | return r; |
|
790 | * CS functions |
943 | } |
791 | */ |
944 | |
792 | int r100_cs_parse_packet0(struct radeon_cs_parser *p, |
945 | int r100_cs_parse_packet0(struct radeon_cs_parser *p, |
793 | struct radeon_cs_packet *pkt, |
946 | struct radeon_cs_packet *pkt, |
794 | const unsigned *auth, unsigned n, |
947 | const unsigned *auth, unsigned n, |
Line 839... | Line 992... | ||
839 | { |
992 | { |
840 | volatile uint32_t *ib; |
993 | volatile uint32_t *ib; |
841 | unsigned i; |
994 | unsigned i; |
842 | unsigned idx; |
995 | unsigned idx; |
Line 843... | Line 996... | ||
843 | 996 | ||
844 | ib = p->ib->ptr; |
997 | ib = p->ib.ptr; |
845 | idx = pkt->idx; |
998 | idx = pkt->idx; |
846 | for (i = 0; i <= (pkt->count + 1); i++, idx++) { |
999 | for (i = 0; i <= (pkt->count + 1); i++, idx++) { |
847 | DRM_INFO("ib[%d]=0x%08X\n", idx, ib[idx]); |
1000 | DRM_INFO("ib[%d]=0x%08X\n", idx, ib[idx]); |
848 | } |
1001 | } |
Line 918... | Line 1071... | ||
918 | int crtc_id; |
1071 | int crtc_id; |
919 | int r; |
1072 | int r; |
920 | uint32_t header, h_idx, reg; |
1073 | uint32_t header, h_idx, reg; |
921 | volatile uint32_t *ib; |
1074 | volatile uint32_t *ib; |
Line 922... | Line 1075... | ||
922 | 1075 | ||
Line 923... | Line 1076... | ||
923 | ib = p->ib->ptr; |
1076 | ib = p->ib.ptr; |
924 | 1077 | ||
925 | /* parse the wait until */ |
1078 | /* parse the wait until */ |
926 | r = r100_cs_packet_parse(p, &waitreloc, p->idx); |
1079 | r = r100_cs_packet_parse(p, &waitreloc, p->idx); |
Line 1097... | Line 1250... | ||
1097 | int r; |
1250 | int r; |
1098 | int i, face; |
1251 | int i, face; |
1099 | u32 tile_flags = 0; |
1252 | u32 tile_flags = 0; |
1100 | u32 idx_value; |
1253 | u32 idx_value; |
Line 1101... | Line 1254... | ||
1101 | 1254 | ||
1102 | ib = p->ib->ptr; |
1255 | ib = p->ib.ptr; |
Line 1103... | Line 1256... | ||
1103 | track = (struct r100_cs_track *)p->track; |
1256 | track = (struct r100_cs_track *)p->track; |
Line 1104... | Line 1257... | ||
1104 | 1257 | ||
Line 1157... | Line 1310... | ||
1157 | DRM_ERROR("No reloc for ib[%d]=0x%04X\n", |
1310 | DRM_ERROR("No reloc for ib[%d]=0x%04X\n", |
1158 | idx, reg); |
1311 | idx, reg); |
1159 | r100_cs_dump_packet(p, pkt); |
1312 | r100_cs_dump_packet(p, pkt); |
1160 | return r; |
1313 | return r; |
1161 | } |
1314 | } |
- | 1315 | if (!(p->cs_flags & RADEON_CS_KEEP_TILING_FLAGS)) { |
|
- | 1316 | if (reloc->lobj.tiling_flags & RADEON_TILING_MACRO) |
|
- | 1317 | tile_flags |= RADEON_TXO_MACRO_TILE; |
|
- | 1318 | if (reloc->lobj.tiling_flags & RADEON_TILING_MICRO) |
|
- | 1319 | tile_flags |= RADEON_TXO_MICRO_TILE_X2; |
|
- | 1320 | ||
- | 1321 | tmp = idx_value & ~(0x7 << 2); |
|
- | 1322 | tmp |= tile_flags; |
|
- | 1323 | ib[idx] = tmp + ((u32)reloc->lobj.gpu_offset); |
|
- | 1324 | } else |
|
1162 | ib[idx] = idx_value + ((u32)reloc->lobj.gpu_offset); |
1325 | ib[idx] = idx_value + ((u32)reloc->lobj.gpu_offset); |
1163 | track->textures[i].robj = reloc->robj; |
1326 | track->textures[i].robj = reloc->robj; |
1164 | track->tex_dirty = true; |
1327 | track->tex_dirty = true; |
1165 | break; |
1328 | break; |
1166 | case RADEON_PP_CUBIC_OFFSET_T0_0: |
1329 | case RADEON_PP_CUBIC_OFFSET_T0_0: |
Line 1228... | Line 1391... | ||
1228 | DRM_ERROR("No reloc for ib[%d]=0x%04X\n", |
1391 | DRM_ERROR("No reloc for ib[%d]=0x%04X\n", |
1229 | idx, reg); |
1392 | idx, reg); |
1230 | r100_cs_dump_packet(p, pkt); |
1393 | r100_cs_dump_packet(p, pkt); |
1231 | return r; |
1394 | return r; |
1232 | } |
1395 | } |
1233 | - | ||
- | 1396 | if (!(p->cs_flags & RADEON_CS_KEEP_TILING_FLAGS)) { |
|
1234 | if (reloc->lobj.tiling_flags & RADEON_TILING_MACRO) |
1397 | if (reloc->lobj.tiling_flags & RADEON_TILING_MACRO) |
1235 | tile_flags |= RADEON_COLOR_TILE_ENABLE; |
1398 | tile_flags |= RADEON_COLOR_TILE_ENABLE; |
1236 | if (reloc->lobj.tiling_flags & RADEON_TILING_MICRO) |
1399 | if (reloc->lobj.tiling_flags & RADEON_TILING_MICRO) |
1237 | tile_flags |= RADEON_COLOR_MICROTILE_ENABLE; |
1400 | tile_flags |= RADEON_COLOR_MICROTILE_ENABLE; |
Line 1238... | Line 1401... | ||
1238 | 1401 | ||
1239 | tmp = idx_value & ~(0x7 << 16); |
1402 | tmp = idx_value & ~(0x7 << 16); |
1240 | tmp |= tile_flags; |
1403 | tmp |= tile_flags; |
- | 1404 | ib[idx] = tmp; |
|
- | 1405 | } else |
|
Line 1241... | Line 1406... | ||
1241 | ib[idx] = tmp; |
1406 | ib[idx] = idx_value; |
1242 | 1407 | ||
1243 | track->cb[0].pitch = idx_value & RADEON_COLORPITCH_MASK; |
1408 | track->cb[0].pitch = idx_value & RADEON_COLORPITCH_MASK; |
1244 | track->cb_dirty = true; |
1409 | track->cb_dirty = true; |
Line 1441... | Line 1606... | ||
1441 | struct r100_cs_track *track; |
1606 | struct r100_cs_track *track; |
1442 | unsigned idx; |
1607 | unsigned idx; |
1443 | volatile uint32_t *ib; |
1608 | volatile uint32_t *ib; |
1444 | int r; |
1609 | int r; |
Line 1445... | Line 1610... | ||
1445 | 1610 | ||
1446 | ib = p->ib->ptr; |
1611 | ib = p->ib.ptr; |
1447 | idx = pkt->idx + 1; |
1612 | idx = pkt->idx + 1; |
1448 | track = (struct r100_cs_track *)p->track; |
1613 | track = (struct r100_cs_track *)p->track; |
1449 | switch (pkt->opcode) { |
1614 | switch (pkt->opcode) { |
1450 | case PACKET3_3D_LOAD_VBPNTR: |
1615 | case PACKET3_3D_LOAD_VBPNTR: |
Line 1560... | Line 1725... | ||
1560 | struct radeon_cs_packet pkt; |
1725 | struct radeon_cs_packet pkt; |
1561 | struct r100_cs_track *track; |
1726 | struct r100_cs_track *track; |
1562 | int r; |
1727 | int r; |
Line 1563... | Line 1728... | ||
1563 | 1728 | ||
- | 1729 | track = kzalloc(sizeof(*track), GFP_KERNEL); |
|
- | 1730 | if (!track) |
|
1564 | track = kzalloc(sizeof(*track), GFP_KERNEL); |
1731 | return -ENOMEM; |
1565 | r100_cs_track_clear(p->rdev, track); |
1732 | r100_cs_track_clear(p->rdev, track); |
1566 | p->track = track; |
1733 | p->track = track; |
1567 | do { |
1734 | do { |
1568 | r = r100_cs_packet_parse(p, &pkt, p->idx); |
1735 | r = r100_cs_packet_parse(p, &pkt, p->idx); |
Line 1598... | Line 1765... | ||
1598 | } |
1765 | } |
1599 | } while (p->idx < p->chunks[p->chunk_ib_idx].length_dw); |
1766 | } while (p->idx < p->chunks[p->chunk_ib_idx].length_dw); |
1600 | return 0; |
1767 | return 0; |
1601 | } |
1768 | } |
Line -... | Line 1769... | ||
- | 1769 | ||
1602 | 1770 | static void r100_cs_track_texture_print(struct r100_cs_track_texture *t) |
|
- | 1771 | { |
|
- | 1772 | DRM_ERROR("pitch %d\n", t->pitch); |
|
- | 1773 | DRM_ERROR("use_pitch %d\n", t->use_pitch); |
|
- | 1774 | DRM_ERROR("width %d\n", t->width); |
|
- | 1775 | DRM_ERROR("width_11 %d\n", t->width_11); |
|
- | 1776 | DRM_ERROR("height %d\n", t->height); |
|
- | 1777 | DRM_ERROR("height_11 %d\n", t->height_11); |
|
- | 1778 | DRM_ERROR("num levels %d\n", t->num_levels); |
|
- | 1779 | DRM_ERROR("depth %d\n", t->txdepth); |
|
- | 1780 | DRM_ERROR("bpp %d\n", t->cpp); |
|
- | 1781 | DRM_ERROR("coordinate type %d\n", t->tex_coord_type); |
|
- | 1782 | DRM_ERROR("width round to power of 2 %d\n", t->roundup_w); |
|
- | 1783 | DRM_ERROR("height round to power of 2 %d\n", t->roundup_h); |
|
- | 1784 | DRM_ERROR("compress format %d\n", t->compress_format); |
|
Line 1603... | Line -... | ||
1603 | #endif |
- | |
1604 | - | ||
1605 | /* |
- | |
1606 | * Global GPU functions |
1785 | } |
1607 | */ |
1786 | |
- | 1787 | static int r100_track_compress_size(int compress_format, int w, int h) |
|
1608 | void r100_errata(struct radeon_device *rdev) |
1788 | { |
- | 1789 | int block_width, block_height, block_bytes; |
|
- | 1790 | int wblocks, hblocks; |
|
Line -... | Line 1791... | ||
- | 1791 | int min_wblocks; |
|
- | 1792 | int sz; |
|
- | 1793 | ||
- | 1794 | block_width = 4; |
|
1609 | { |
1795 | block_height = 4; |
- | 1796 | ||
- | 1797 | switch (compress_format) { |
|
- | 1798 | case R100_TRACK_COMP_DXT1: |
|
- | 1799 | block_bytes = 8; |
|
1610 | rdev->pll_errata = 0; |
1800 | min_wblocks = 4; |
- | 1801 | break; |
|
- | 1802 | default: |
|
- | 1803 | case R100_TRACK_COMP_DXT35: |
|
1611 | 1804 | block_bytes = 16; |
|
Line -... | Line 1805... | ||
- | 1805 | min_wblocks = 2; |
|
1612 | if (rdev->family == CHIP_RV200 || rdev->family == CHIP_RS200) { |
1806 | break; |
1613 | rdev->pll_errata |= CHIP_ERRATA_PLL_DUMMYREADS; |
1807 | } |
1614 | } |
1808 | |
1615 | 1809 | hblocks = (h + block_height - 1) / block_height; |
|
- | 1810 | wblocks = (w + block_width - 1) / block_width; |
|
1616 | if (rdev->family == CHIP_RV100 || |
1811 | if (wblocks < min_wblocks) |
- | 1812 | wblocks = min_wblocks; |
|
- | 1813 | sz = wblocks * hblocks * block_bytes; |
|
- | 1814 | return sz; |
|
- | 1815 | } |
|
- | 1816 | ||
- | 1817 | static int r100_cs_track_cube(struct radeon_device *rdev, |
|
- | 1818 | struct r100_cs_track *track, unsigned idx) |
|
- | 1819 | { |
|
- | 1820 | unsigned face, w, h; |
|
- | 1821 | struct radeon_bo *cube_robj; |
|
- | 1822 | unsigned long size; |
|
- | 1823 | unsigned compress_format = track->textures[idx].compress_format; |
|
- | 1824 | ||
- | 1825 | for (face = 0; face < 5; face++) { |
|
- | 1826 | cube_robj = track->textures[idx].cube_info[face].robj; |
|
- | 1827 | w = track->textures[idx].cube_info[face].width; |
|
- | 1828 | h = track->textures[idx].cube_info[face].height; |
|
- | 1829 | ||
- | 1830 | if (compress_format) { |
|
- | 1831 | size = r100_track_compress_size(compress_format, w, h); |
|
- | 1832 | } else |
|
- | 1833 | size = w * h; |
|
- | 1834 | size *= track->textures[idx].cpp; |
|
- | 1835 | ||
- | 1836 | size += track->textures[idx].cube_info[face].offset; |
|
- | 1837 | ||
- | 1838 | if (size > radeon_bo_size(cube_robj)) { |
|
- | 1839 | DRM_ERROR("Cube texture offset greater than object size %lu %lu\n", |
|
- | 1840 | size, radeon_bo_size(cube_robj)); |
|
- | 1841 | r100_cs_track_texture_print(&track->textures[idx]); |
|
1617 | rdev->family == CHIP_RS100 || |
1842 | return -1; |
Line 1618... | Line 1843... | ||
1618 | rdev->family == CHIP_RS200) { |
1843 | } |
1619 | rdev->pll_errata |= CHIP_ERRATA_PLL_DELAY; |
1844 | } |
1620 | } |
1845 | return 0; |
1621 | } |
1846 | } |
- | 1847 | ||
- | 1848 | static int r100_cs_track_texture_check(struct radeon_device *rdev, |
|
1622 | 1849 | struct r100_cs_track *track) |
|
Line 1623... | Line 1850... | ||
1623 | /* Wait for vertical sync on primary CRTC */ |
1850 | { |
1624 | void r100_gpu_wait_for_vsync(struct radeon_device *rdev) |
1851 | struct radeon_bo *robj; |
- | 1852 | unsigned long size; |
|
1625 | { |
1853 | unsigned u, i, w, h, d; |
- | 1854 | int ret; |
|
- | 1855 | ||
- | 1856 | for (u = 0; u < track->num_texture; u++) { |
|
- | 1857 | if (!track->textures[u].enabled) |
|
1626 | uint32_t crtc_gen_cntl, tmp; |
1858 | continue; |
1627 | int i; |
1859 | if (track->textures[u].lookup_disable) |
- | 1860 | continue; |
|
- | 1861 | robj = track->textures[u].robj; |
|
1628 | 1862 | if (robj == NULL) { |
|
- | 1863 | DRM_ERROR("No texture bound to unit %u\n", u); |
|
1629 | crtc_gen_cntl = RREG32(RADEON_CRTC_GEN_CNTL); |
1864 | return -EINVAL; |
- | 1865 | } |
|
1630 | if ((crtc_gen_cntl & RADEON_CRTC_DISP_REQ_EN_B) || |
1866 | size = 0; |
- | 1867 | for (i = 0; i <= track->textures[u].num_levels; i++) { |
|
1631 | !(crtc_gen_cntl & RADEON_CRTC_EN)) { |
1868 | if (track->textures[u].use_pitch) { |
1632 | return; |
1869 | if (rdev->family < CHIP_R300) |
- | 1870 | w = (track->textures[u].pitch / track->textures[u].cpp) / (1 << i); |
|
1633 | } |
1871 | else |
- | 1872 | w = track->textures[u].pitch / (1 << i); |
|
- | 1873 | } else { |
|
1634 | /* Clear the CRTC_VBLANK_SAVE bit */ |
1874 | w = track->textures[u].width; |
- | 1875 | if (rdev->family >= CHIP_RV515) |
|
- | 1876 | w |= track->textures[u].width_11; |
|
- | 1877 | w = w / (1 << i); |
|
1635 | WREG32(RADEON_CRTC_STATUS, RADEON_CRTC_VBLANK_SAVE_CLEAR); |
1878 | if (track->textures[u].roundup_w) |
- | 1879 | w = roundup_pow_of_two(w); |
|
- | 1880 | } |
|
- | 1881 | h = track->textures[u].height; |
|
- | 1882 | if (rdev->family >= CHIP_RV515) |
|
- | 1883 | h |= track->textures[u].height_11; |
|
- | 1884 | h = h / (1 << i); |
|
- | 1885 | if (track->textures[u].roundup_h) |
|
- | 1886 | h = roundup_pow_of_two(h); |
|
1636 | for (i = 0; i < rdev->usec_timeout; i++) { |
1887 | if (track->textures[u].tex_coord_type == 1) { |
- | 1888 | d = (1 << track->textures[u].txdepth) / (1 << i); |
|
- | 1889 | if (!d) |
|
- | 1890 | d = 1; |
|
- | 1891 | } else { |
|
- | 1892 | d = 1; |
|
- | 1893 | } |
|
1637 | tmp = RREG32(RADEON_CRTC_STATUS); |
1894 | if (track->textures[u].compress_format) { |
- | 1895 | ||
Line 1638... | Line 1896... | ||
1638 | if (tmp & RADEON_CRTC_VBLANK_SAVE) { |
1896 | size += r100_track_compress_size(track->textures[u].compress_format, w, h) * d; |
- | 1897 | /* compressed textures are block based */ |
|
- | 1898 | } else |
|
- | 1899 | size += w * h * d; |
|
- | 1900 | } |
|
- | 1901 | size *= track->textures[u].cpp; |
|
- | 1902 | ||
- | 1903 | switch (track->textures[u].tex_coord_type) { |
|
- | 1904 | case 0: |
|
- | 1905 | case 1: |
|
- | 1906 | break; |
|
- | 1907 | case 2: |
|
- | 1908 | if (track->separate_cube) { |
|
- | 1909 | ret = r100_cs_track_cube(rdev, track, u); |
|
- | 1910 | if (ret) |
|
- | 1911 | return ret; |
|
- | 1912 | } else |
|
- | 1913 | size *= 6; |
|
- | 1914 | break; |
|
- | 1915 | default: |
|
- | 1916 | DRM_ERROR("Invalid texture coordinate type %u for unit " |
|
- | 1917 | "%u\n", track->textures[u].tex_coord_type, u); |
|
- | 1918 | return -EINVAL; |
|
- | 1919 | } |
|
- | 1920 | if (size > radeon_bo_size(robj)) { |
|
- | 1921 | DRM_ERROR("Texture of unit %u needs %lu bytes but is " |
|
- | 1922 | "%lu\n", u, size, radeon_bo_size(robj)); |
|
1639 | return; |
1923 | r100_cs_track_texture_print(&track->textures[u]); |
1640 | } |
1924 | return -EINVAL; |
- | 1925 | } |
|
- | 1926 | } |
|
1641 | DRM_UDELAY(1); |
1927 | return 0; |
1642 | } |
1928 | } |
- | 1929 | ||
Line 1643... | Line -... | ||
1643 | } |
- | |
1644 | 1930 | int r100_cs_track_check(struct radeon_device *rdev, struct r100_cs_track *track) |
|
1645 | /* Wait for vertical sync on secondary CRTC */ |
1931 | { |
1646 | void r100_gpu_wait_for_vsync2(struct radeon_device *rdev) |
1932 | unsigned i; |
Line 1647... | Line -... | ||
1647 | { |
- | |
1648 | uint32_t crtc2_gen_cntl, tmp; |
- | |
1649 | int i; |
1933 | unsigned long size; |
1650 | 1934 | unsigned prim_walk; |
|
1651 | crtc2_gen_cntl = RREG32(RADEON_CRTC2_GEN_CNTL); |
1935 | unsigned nverts; |
1652 | if ((crtc2_gen_cntl & RADEON_CRTC2_DISP_REQ_EN_B) || |
1936 | unsigned num_cb = track->cb_dirty ? track->num_cb : 0; |
1653 | !(crtc2_gen_cntl & RADEON_CRTC2_EN)) |
1937 | |
- | 1938 | if (num_cb && !track->zb_cb_clear && !track->color_channel_mask && |
|
- | 1939 | !track->blend_read_enable) |
|
- | 1940 | num_cb = 0; |
|
- | 1941 | ||
- | 1942 | for (i = 0; i < num_cb; i++) { |
|
- | 1943 | if (track->cb[i].robj == NULL) { |
|
- | 1944 | DRM_ERROR("[drm] No buffer for color buffer %d !\n", i); |
|
- | 1945 | return -EINVAL; |
|
- | 1946 | } |
|
1654 | return; |
1947 | size = track->cb[i].pitch * track->cb[i].cpp * track->maxy; |
1655 | 1948 | size += track->cb[i].offset; |
|
1656 | /* Clear the CRTC_VBLANK_SAVE bit */ |
1949 | if (size > radeon_bo_size(track->cb[i].robj)) { |
- | 1950 | DRM_ERROR("[drm] Buffer too small for color buffer %d " |
|
Line -... | Line 1951... | ||
- | 1951 | "(need %lu have %lu) !\n", i, size, |
|
- | 1952 | radeon_bo_size(track->cb[i].robj)); |
|
- | 1953 | DRM_ERROR("[drm] color buffer %d (%u %u %u %u)\n", |
|
- | 1954 | i, track->cb[i].pitch, track->cb[i].cpp, |
|
- | 1955 | track->cb[i].offset, track->maxy); |
|
- | 1956 | return -EINVAL; |
|
- | 1957 | } |
|
- | 1958 | } |
|
- | 1959 | track->cb_dirty = false; |
|
- | 1960 | ||
- | 1961 | if (track->zb_dirty && track->z_enabled) { |
|
- | 1962 | if (track->zb.robj == NULL) { |
|
- | 1963 | DRM_ERROR("[drm] No buffer for z buffer !\n"); |
|
- | 1964 | return -EINVAL; |
|
- | 1965 | } |
|
- | 1966 | size = track->zb.pitch * track->zb.cpp * track->maxy; |
|
- | 1967 | size += track->zb.offset; |
|
- | 1968 | if (size > radeon_bo_size(track->zb.robj)) { |
|
- | 1969 | DRM_ERROR("[drm] Buffer too small for z buffer " |
|
- | 1970 | "(need %lu have %lu) !\n", size, |
|
- | 1971 | radeon_bo_size(track->zb.robj)); |
|
- | 1972 | DRM_ERROR("[drm] zbuffer (%u %u %u %u)\n", |
|
- | 1973 | track->zb.pitch, track->zb.cpp, |
|
- | 1974 | track->zb.offset, track->maxy); |
|
- | 1975 | return -EINVAL; |
|
- | 1976 | } |
|
- | 1977 | } |
|
- | 1978 | track->zb_dirty = false; |
|
- | 1979 | ||
- | 1980 | if (track->aa_dirty && track->aaresolve) { |
|
- | 1981 | if (track->aa.robj == NULL) { |
|
- | 1982 | DRM_ERROR("[drm] No buffer for AA resolve buffer %d !\n", i); |
|
- | 1983 | return -EINVAL; |
|
- | 1984 | } |
|
- | 1985 | /* I believe the format comes from colorbuffer0. */ |
|
- | 1986 | size = track->aa.pitch * track->cb[0].cpp * track->maxy; |
|
- | 1987 | size += track->aa.offset; |
|
- | 1988 | if (size > radeon_bo_size(track->aa.robj)) { |
|
- | 1989 | DRM_ERROR("[drm] Buffer too small for AA resolve buffer %d " |
|
- | 1990 | "(need %lu have %lu) !\n", i, size, |
|
- | 1991 | radeon_bo_size(track->aa.robj)); |
|
- | 1992 | DRM_ERROR("[drm] AA resolve buffer %d (%u %u %u %u)\n", |
|
- | 1993 | i, track->aa.pitch, track->cb[0].cpp, |
|
- | 1994 | track->aa.offset, track->maxy); |
|
- | 1995 | return -EINVAL; |
|
- | 1996 | } |
|
- | 1997 | } |
|
- | 1998 | track->aa_dirty = false; |
|
- | 1999 | ||
- | 2000 | prim_walk = (track->vap_vf_cntl >> 4) & 0x3; |
|
- | 2001 | if (track->vap_vf_cntl & (1 << 14)) { |
|
- | 2002 | nverts = track->vap_alt_nverts; |
|
- | 2003 | } else { |
|
- | 2004 | nverts = (track->vap_vf_cntl >> 16) & 0xFFFF; |
|
- | 2005 | } |
|
- | 2006 | switch (prim_walk) { |
|
- | 2007 | case 1: |
|
- | 2008 | for (i = 0; i < track->num_arrays; i++) { |
|
- | 2009 | size = track->arrays[i].esize * track->max_indx * 4; |
|
- | 2010 | if (track->arrays[i].robj == NULL) { |
|
- | 2011 | DRM_ERROR("(PW %u) Vertex array %u no buffer " |
|
- | 2012 | "bound\n", prim_walk, i); |
|
- | 2013 | return -EINVAL; |
|
- | 2014 | } |
|
- | 2015 | if (size > radeon_bo_size(track->arrays[i].robj)) { |
|
- | 2016 | dev_err(rdev->dev, "(PW %u) Vertex array %u " |
|
- | 2017 | "need %lu dwords have %lu dwords\n", |
|
- | 2018 | prim_walk, i, size >> 2, |
|
- | 2019 | radeon_bo_size(track->arrays[i].robj) |
|
- | 2020 | >> 2); |
|
- | 2021 | DRM_ERROR("Max indices %u\n", track->max_indx); |
|
- | 2022 | return -EINVAL; |
|
- | 2023 | } |
|
- | 2024 | } |
|
- | 2025 | break; |
|
- | 2026 | case 2: |
|
- | 2027 | for (i = 0; i < track->num_arrays; i++) { |
|
- | 2028 | size = track->arrays[i].esize * (nverts - 1) * 4; |
|
- | 2029 | if (track->arrays[i].robj == NULL) { |
|
- | 2030 | DRM_ERROR("(PW %u) Vertex array %u no buffer " |
|
- | 2031 | "bound\n", prim_walk, i); |
|
- | 2032 | return -EINVAL; |
|
- | 2033 | } |
|
- | 2034 | if (size > radeon_bo_size(track->arrays[i].robj)) { |
|
- | 2035 | dev_err(rdev->dev, "(PW %u) Vertex array %u " |
|
- | 2036 | "need %lu dwords have %lu dwords\n", |
|
- | 2037 | prim_walk, i, size >> 2, |
|
- | 2038 | radeon_bo_size(track->arrays[i].robj) |
|
- | 2039 | >> 2); |
|
- | 2040 | return -EINVAL; |
|
- | 2041 | } |
|
- | 2042 | } |
|
- | 2043 | break; |
|
- | 2044 | case 3: |
|
- | 2045 | size = track->vtx_size * nverts; |
|
- | 2046 | if (size != track->immd_dwords) { |
|
- | 2047 | DRM_ERROR("IMMD draw %u dwors but needs %lu dwords\n", |
|
- | 2048 | track->immd_dwords, size); |
|
- | 2049 | DRM_ERROR("VAP_VF_CNTL.NUM_VERTICES %u, VTX_SIZE %u\n", |
|
- | 2050 | nverts, track->vtx_size); |
|
- | 2051 | return -EINVAL; |
|
- | 2052 | } |
|
- | 2053 | break; |
|
- | 2054 | default: |
|
- | 2055 | DRM_ERROR("[drm] Invalid primitive walk %d for VAP_VF_CNTL\n", |
|
- | 2056 | prim_walk); |
|
- | 2057 | return -EINVAL; |
|
- | 2058 | } |
|
- | 2059 | ||
- | 2060 | if (track->tex_dirty) { |
|
- | 2061 | track->tex_dirty = false; |
|
- | 2062 | return r100_cs_track_texture_check(rdev, track); |
|
- | 2063 | } |
|
- | 2064 | return 0; |
|
- | 2065 | } |
|
- | 2066 | ||
- | 2067 | void r100_cs_track_clear(struct radeon_device *rdev, struct r100_cs_track *track) |
|
- | 2068 | { |
|
- | 2069 | unsigned i, face; |
|
- | 2070 | ||
- | 2071 | track->cb_dirty = true; |
|
- | 2072 | track->zb_dirty = true; |
|
- | 2073 | track->tex_dirty = true; |
|
- | 2074 | track->aa_dirty = true; |
|
- | 2075 | ||
- | 2076 | if (rdev->family < CHIP_R300) { |
|
- | 2077 | track->num_cb = 1; |
|
- | 2078 | if (rdev->family <= CHIP_RS200) |
|
- | 2079 | track->num_texture = 3; |
|
- | 2080 | else |
|
- | 2081 | track->num_texture = 6; |
|
- | 2082 | track->maxy = 2048; |
|
- | 2083 | track->separate_cube = 1; |
|
- | 2084 | } else { |
|
- | 2085 | track->num_cb = 4; |
|
- | 2086 | track->num_texture = 16; |
|
- | 2087 | track->maxy = 4096; |
|
- | 2088 | track->separate_cube = 0; |
|
- | 2089 | track->aaresolve = false; |
|
- | 2090 | track->aa.robj = NULL; |
|
- | 2091 | } |
|
- | 2092 | ||
- | 2093 | for (i = 0; i < track->num_cb; i++) { |
|
- | 2094 | track->cb[i].robj = NULL; |
|
- | 2095 | track->cb[i].pitch = 8192; |
|
- | 2096 | track->cb[i].cpp = 16; |
|
- | 2097 | track->cb[i].offset = 0; |
|
- | 2098 | } |
|
- | 2099 | track->z_enabled = true; |
|
- | 2100 | track->zb.robj = NULL; |
|
- | 2101 | track->zb.pitch = 8192; |
|
- | 2102 | track->zb.cpp = 4; |
|
- | 2103 | track->zb.offset = 0; |
|
- | 2104 | track->vtx_size = 0x7F; |
|
- | 2105 | track->immd_dwords = 0xFFFFFFFFUL; |
|
- | 2106 | track->num_arrays = 11; |
|
- | 2107 | track->max_indx = 0x00FFFFFFUL; |
|
- | 2108 | for (i = 0; i < track->num_arrays; i++) { |
|
- | 2109 | track->arrays[i].robj = NULL; |
|
- | 2110 | track->arrays[i].esize = 0x7F; |
|
- | 2111 | } |
|
- | 2112 | for (i = 0; i < track->num_texture; i++) { |
|
- | 2113 | track->textures[i].compress_format = R100_TRACK_COMP_NONE; |
|
- | 2114 | track->textures[i].pitch = 16536; |
|
- | 2115 | track->textures[i].width = 16536; |
|
- | 2116 | track->textures[i].height = 16536; |
|
- | 2117 | track->textures[i].width_11 = 1 << 11; |
|
- | 2118 | track->textures[i].height_11 = 1 << 11; |
|
- | 2119 | track->textures[i].num_levels = 12; |
|
- | 2120 | if (rdev->family <= CHIP_RS200) { |
|
- | 2121 | track->textures[i].tex_coord_type = 0; |
|
- | 2122 | track->textures[i].txdepth = 0; |
|
- | 2123 | } else { |
|
- | 2124 | track->textures[i].txdepth = 16; |
|
- | 2125 | track->textures[i].tex_coord_type = 1; |
|
- | 2126 | } |
|
- | 2127 | track->textures[i].cpp = 64; |
|
- | 2128 | track->textures[i].robj = NULL; |
|
- | 2129 | /* CS IB emission code makes sure texture unit are disabled */ |
|
- | 2130 | track->textures[i].enabled = false; |
|
- | 2131 | track->textures[i].lookup_disable = false; |
|
- | 2132 | track->textures[i].roundup_w = true; |
|
- | 2133 | track->textures[i].roundup_h = true; |
|
- | 2134 | if (track->separate_cube) |
|
- | 2135 | for (face = 0; face < 5; face++) { |
|
- | 2136 | track->textures[i].cube_info[face].robj = NULL; |
|
- | 2137 | track->textures[i].cube_info[face].width = 16536; |
|
- | 2138 | track->textures[i].cube_info[face].height = 16536; |
|
- | 2139 | track->textures[i].cube_info[face].offset = 0; |
|
- | 2140 | } |
|
- | 2141 | } |
|
- | 2142 | } |
|
- | 2143 | #endif |
|
- | 2144 | ||
- | 2145 | /* |
|
- | 2146 | * Global GPU functions |
|
- | 2147 | */ |
|
- | 2148 | static void r100_errata(struct radeon_device *rdev) |
|
- | 2149 | { |
|
- | 2150 | rdev->pll_errata = 0; |
|
- | 2151 | ||
- | 2152 | if (rdev->family == CHIP_RV200 || rdev->family == CHIP_RS200) { |
|
1657 | WREG32(RADEON_CRTC2_STATUS, RADEON_CRTC2_VBLANK_SAVE_CLEAR); |
2153 | rdev->pll_errata |= CHIP_ERRATA_PLL_DUMMYREADS; |
1658 | for (i = 0; i < rdev->usec_timeout; i++) { |
2154 | } |
1659 | tmp = RREG32(RADEON_CRTC2_STATUS); |
2155 | |
1660 | if (tmp & RADEON_CRTC2_VBLANK_SAVE) { |
2156 | if (rdev->family == CHIP_RV100 || |
Line 1661... | Line 2157... | ||
1661 | return; |
2157 | rdev->family == CHIP_RS100 || |
Line 1712... | Line 2208... | ||
1712 | DRM_UDELAY(1); |
2208 | DRM_UDELAY(1); |
1713 | } |
2209 | } |
1714 | return -1; |
2210 | return -1; |
1715 | } |
2211 | } |
Line 1716... | Line -... | ||
1716 | - | ||
1717 | void r100_gpu_lockup_update(struct r100_gpu_lockup *lockup, struct radeon_cp *cp) |
- | |
1718 | { |
- | |
1719 | lockup->last_cp_rptr = cp->rptr; |
- | |
1720 | lockup->last_jiffies = GetTimerTicks(); |
- | |
1721 | } |
- | |
1722 | - | ||
1723 | /** |
- | |
1724 | * r100_gpu_cp_is_lockup() - check if CP is lockup by recording information |
- | |
1725 | * @rdev: radeon device structure |
- | |
1726 | * @lockup: r100_gpu_lockup structure holding CP lockup tracking informations |
- | |
1727 | * @cp: radeon_cp structure holding CP information |
- | |
1728 | * |
- | |
1729 | * We don't need to initialize the lockup tracking information as we will either |
- | |
1730 | * have CP rptr to a different value of jiffies wrap around which will force |
- | |
1731 | * initialization of the lockup tracking informations. |
- | |
1732 | * |
- | |
1733 | * A possible false positivie is if we get call after while and last_cp_rptr == |
- | |
1734 | * the current CP rptr, even if it's unlikely it might happen. To avoid this |
- | |
1735 | * if the elapsed time since last call is bigger than 2 second than we return |
- | |
1736 | * false and update the tracking information. Due to this the caller must call |
- | |
1737 | * r100_gpu_cp_is_lockup several time in less than 2sec for lockup to be reported |
- | |
1738 | * the fencing code should be cautious about that. |
- | |
1739 | * |
- | |
1740 | * Caller should write to the ring to force CP to do something so we don't get |
- | |
1741 | * false positive when CP is just gived nothing to do. |
- | |
1742 | * |
- | |
1743 | **/ |
- | |
1744 | bool r100_gpu_cp_is_lockup(struct radeon_device *rdev, struct r100_gpu_lockup *lockup, struct radeon_cp *cp) |
- | |
1745 | { |
- | |
1746 | unsigned long cjiffies, elapsed; |
- | |
1747 | - | ||
1748 | cjiffies = GetTimerTicks(); |
- | |
1749 | if (!time_after(cjiffies, lockup->last_jiffies)) { |
- | |
1750 | /* likely a wrap around */ |
- | |
1751 | lockup->last_cp_rptr = cp->rptr; |
- | |
1752 | lockup->last_jiffies = GetTimerTicks(); |
- | |
1753 | return false; |
- | |
1754 | } |
- | |
1755 | if (cp->rptr != lockup->last_cp_rptr) { |
- | |
1756 | /* CP is still working no lockup */ |
- | |
1757 | lockup->last_cp_rptr = cp->rptr; |
- | |
1758 | lockup->last_jiffies = GetTimerTicks(); |
- | |
1759 | return false; |
- | |
1760 | } |
- | |
1761 | elapsed = jiffies_to_msecs(cjiffies - lockup->last_jiffies); |
- | |
1762 | if (elapsed >= 10000) { |
- | |
1763 | dev_err(rdev->dev, "GPU lockup CP stall for more than %lumsec\n", elapsed); |
- | |
1764 | return true; |
- | |
1765 | } |
- | |
1766 | /* give a chance to the GPU ... */ |
- | |
1767 | return false; |
- | |
1768 | } |
- | |
1769 | 2212 | ||
1770 | bool r100_gpu_is_lockup(struct radeon_device *rdev) |
2213 | bool r100_gpu_is_lockup(struct radeon_device *rdev, struct radeon_ring *ring) |
1771 | { |
2214 | { |
1772 | u32 rbbm_status; |
- | |
Line 1773... | Line 2215... | ||
1773 | int r; |
2215 | u32 rbbm_status; |
1774 | 2216 | ||
1775 | rbbm_status = RREG32(R_000E40_RBBM_STATUS); |
2217 | rbbm_status = RREG32(R_000E40_RBBM_STATUS); |
1776 | if (!G_000E40_GUI_ACTIVE(rbbm_status)) { |
2218 | if (!G_000E40_GUI_ACTIVE(rbbm_status)) { |
1777 | r100_gpu_lockup_update(&rdev->config.r100.lockup, &rdev->cp); |
2219 | radeon_ring_lockup_update(ring); |
1778 | return false; |
2220 | return false; |
1779 | } |
2221 | } |
1780 | /* force CP activities */ |
- | |
1781 | r = radeon_ring_lock(rdev, 2); |
- | |
1782 | if (!r) { |
- | |
1783 | /* PACKET2 NOP */ |
- | |
1784 | radeon_ring_write(rdev, 0x80000000); |
2222 | /* force CP activities */ |
1785 | radeon_ring_write(rdev, 0x80000000); |
2223 | radeon_ring_force_activity(rdev, ring); |
- | 2224 | return radeon_ring_test_lockup(rdev, ring); |
|
1786 | radeon_ring_unlock_commit(rdev); |
2225 | } |
1787 | } |
2226 | |
- | 2227 | /* required on r1xx, r2xx, r300, r(v)350, r420/r481, rs400/rs480 */ |
|
- | 2228 | void r100_enable_bm(struct radeon_device *rdev) |
|
- | 2229 | { |
|
- | 2230 | uint32_t tmp; |
|
- | 2231 | /* Enable bus mastering */ |
|
1788 | rdev->cp.rptr = RREG32(RADEON_CP_RB_RPTR); |
2232 | tmp = RREG32(RADEON_BUS_CNTL) & ~RADEON_BUS_MASTER_DIS; |
Line 1789... | Line 2233... | ||
1789 | return r100_gpu_cp_is_lockup(rdev, &rdev->config.r100.lockup, &rdev->cp); |
2233 | WREG32(RADEON_BUS_CNTL, tmp); |
1790 | } |
2234 | } |
1791 | 2235 | ||
Line 1800... | Line 2244... | ||
1800 | WREG32(R_000030_BUS_CNTL, (tmp & 0xFFFFFFFF) | 0x00000042); |
2244 | WREG32(R_000030_BUS_CNTL, (tmp & 0xFFFFFFFF) | 0x00000042); |
1801 | mdelay(1); |
2245 | mdelay(1); |
1802 | WREG32(R_000030_BUS_CNTL, (tmp & 0xFFFFFFFF) | 0x00000040); |
2246 | WREG32(R_000030_BUS_CNTL, (tmp & 0xFFFFFFFF) | 0x00000040); |
1803 | tmp = RREG32(RADEON_BUS_CNTL); |
2247 | tmp = RREG32(RADEON_BUS_CNTL); |
1804 | mdelay(1); |
2248 | mdelay(1); |
1805 | tmp = PciRead16(rdev->pdev->bus, rdev->pdev->devfn, 0x4); |
2249 | pci_clear_master(rdev->pdev); |
1806 | PciWrite16(rdev->pdev->bus, rdev->pdev->devfn, 0x4, tmp & 0xFFFB); |
- | |
1807 | mdelay(1); |
2250 | mdelay(1); |
1808 | } |
2251 | } |
Line 1809... | Line 2252... | ||
1809 | 2252 | ||
1810 | int r100_asic_reset(struct radeon_device *rdev) |
2253 | int r100_asic_reset(struct radeon_device *rdev) |
Line 1854... | Line 2297... | ||
1854 | r100_enable_bm(rdev); |
2297 | r100_enable_bm(rdev); |
1855 | /* Check if GPU is idle */ |
2298 | /* Check if GPU is idle */ |
1856 | if (G_000E40_SE_BUSY(status) || G_000E40_RE_BUSY(status) || |
2299 | if (G_000E40_SE_BUSY(status) || G_000E40_RE_BUSY(status) || |
1857 | G_000E40_TAM_BUSY(status) || G_000E40_PB_BUSY(status)) { |
2300 | G_000E40_TAM_BUSY(status) || G_000E40_PB_BUSY(status)) { |
1858 | dev_err(rdev->dev, "failed to reset GPU\n"); |
2301 | dev_err(rdev->dev, "failed to reset GPU\n"); |
1859 | rdev->gpu_lockup = true; |
- | |
1860 | ret = -1; |
2302 | ret = -1; |
1861 | } else |
2303 | } else |
1862 | dev_info(rdev->dev, "GPU reset succeed\n"); |
2304 | dev_info(rdev->dev, "GPU reset succeed\n"); |
1863 | r100_mc_resume(rdev, &save); |
2305 | r100_mc_resume(rdev, &save); |
1864 | return ret; |
2306 | return ret; |
Line 2077... | Line 2519... | ||
2077 | temp &= ~RADEON_CFG_VGA_IO_DIS; |
2519 | temp &= ~RADEON_CFG_VGA_IO_DIS; |
2078 | } |
2520 | } |
2079 | WREG32(RADEON_CONFIG_CNTL, temp); |
2521 | WREG32(RADEON_CONFIG_CNTL, temp); |
2080 | } |
2522 | } |
Line 2081... | Line 2523... | ||
2081 | 2523 | ||
2082 | void r100_mc_init(struct radeon_device *rdev) |
2524 | static void r100_mc_init(struct radeon_device *rdev) |
2083 | { |
2525 | { |
Line 2084... | Line 2526... | ||
2084 | u64 base; |
2526 | u64 base; |
2085 | 2527 | ||
Line 2111... | Line 2553... | ||
2111 | { |
2553 | { |
2112 | /* This workarounds is necessary on RV100, RS100 and RS200 chips |
2554 | /* This workarounds is necessary on RV100, RS100 and RS200 chips |
2113 | * or the chip could hang on a subsequent access |
2555 | * or the chip could hang on a subsequent access |
2114 | */ |
2556 | */ |
2115 | if (rdev->pll_errata & CHIP_ERRATA_PLL_DELAY) { |
2557 | if (rdev->pll_errata & CHIP_ERRATA_PLL_DELAY) { |
2116 | udelay(5000); |
2558 | mdelay(5); |
2117 | } |
2559 | } |
Line 2118... | Line 2560... | ||
2118 | 2560 | ||
2119 | /* This function is required to workaround a hardware bug in some (all?) |
2561 | /* This function is required to workaround a hardware bug in some (all?) |
2120 | * revisions of the R300. This workaround should be called after every |
2562 | * revisions of the R300. This workaround should be called after every |
Line 2149... | Line 2591... | ||
2149 | r100_pll_errata_after_index(rdev); |
2591 | r100_pll_errata_after_index(rdev); |
2150 | WREG32(RADEON_CLOCK_CNTL_DATA, v); |
2592 | WREG32(RADEON_CLOCK_CNTL_DATA, v); |
2151 | r100_pll_errata_after_data(rdev); |
2593 | r100_pll_errata_after_data(rdev); |
2152 | } |
2594 | } |
Line 2153... | Line 2595... | ||
2153 | 2595 | ||
2154 | void r100_set_safe_registers(struct radeon_device *rdev) |
2596 | static void r100_set_safe_registers(struct radeon_device *rdev) |
2155 | { |
2597 | { |
2156 | if (ASIC_IS_RN50(rdev)) { |
2598 | if (ASIC_IS_RN50(rdev)) { |
2157 | rdev->config.r100.reg_safe_bm = rn50_reg_safe_bm; |
2599 | rdev->config.r100.reg_safe_bm = rn50_reg_safe_bm; |
2158 | rdev->config.r100.reg_safe_bm_size = ARRAY_SIZE(rn50_reg_safe_bm); |
2600 | rdev->config.r100.reg_safe_bm_size = ARRAY_SIZE(rn50_reg_safe_bm); |
Line 2192... | Line 2634... | ||
2192 | static int r100_debugfs_cp_ring_info(struct seq_file *m, void *data) |
2634 | static int r100_debugfs_cp_ring_info(struct seq_file *m, void *data) |
2193 | { |
2635 | { |
2194 | struct drm_info_node *node = (struct drm_info_node *) m->private; |
2636 | struct drm_info_node *node = (struct drm_info_node *) m->private; |
2195 | struct drm_device *dev = node->minor->dev; |
2637 | struct drm_device *dev = node->minor->dev; |
2196 | struct radeon_device *rdev = dev->dev_private; |
2638 | struct radeon_device *rdev = dev->dev_private; |
- | 2639 | struct radeon_ring *ring = &rdev->ring[RADEON_RING_TYPE_GFX_INDEX]; |
|
2197 | uint32_t rdp, wdp; |
2640 | uint32_t rdp, wdp; |
2198 | unsigned count, i, j; |
2641 | unsigned count, i, j; |
Line 2199... | Line 2642... | ||
2199 | 2642 | ||
2200 | radeon_ring_free_size(rdev); |
2643 | radeon_ring_free_size(rdev, ring); |
2201 | rdp = RREG32(RADEON_CP_RB_RPTR); |
2644 | rdp = RREG32(RADEON_CP_RB_RPTR); |
2202 | wdp = RREG32(RADEON_CP_RB_WPTR); |
2645 | wdp = RREG32(RADEON_CP_RB_WPTR); |
2203 | count = (rdp + rdev->cp.ring_size - wdp) & rdev->cp.ptr_mask; |
2646 | count = (rdp + ring->ring_size - wdp) & ring->ptr_mask; |
2204 | seq_printf(m, "CP_STAT 0x%08x\n", RREG32(RADEON_CP_STAT)); |
2647 | seq_printf(m, "CP_STAT 0x%08x\n", RREG32(RADEON_CP_STAT)); |
2205 | seq_printf(m, "CP_RB_WPTR 0x%08x\n", wdp); |
2648 | seq_printf(m, "CP_RB_WPTR 0x%08x\n", wdp); |
2206 | seq_printf(m, "CP_RB_RPTR 0x%08x\n", rdp); |
2649 | seq_printf(m, "CP_RB_RPTR 0x%08x\n", rdp); |
2207 | seq_printf(m, "%u free dwords in ring\n", rdev->cp.ring_free_dw); |
2650 | seq_printf(m, "%u free dwords in ring\n", ring->ring_free_dw); |
2208 | seq_printf(m, "%u dwords in ring\n", count); |
2651 | seq_printf(m, "%u dwords in ring\n", count); |
2209 | for (j = 0; j <= count; j++) { |
2652 | for (j = 0; j <= count; j++) { |
2210 | i = (rdp + j) & rdev->cp.ptr_mask; |
2653 | i = (rdp + j) & ring->ptr_mask; |
2211 | seq_printf(m, "r[%04d]=0x%08x\n", i, rdev->cp.ring[i]); |
2654 | seq_printf(m, "r[%04d]=0x%08x\n", i, ring->ring[i]); |
2212 | } |
2655 | } |
2213 | return 0; |
2656 | return 0; |
Line 2874... | Line 3317... | ||
2874 | DRM_DEBUG_KMS("GRPH2_BUFFER_CNTL from to %x\n", |
3317 | DRM_DEBUG_KMS("GRPH2_BUFFER_CNTL from to %x\n", |
2875 | (unsigned int)RREG32(RADEON_GRPH2_BUFFER_CNTL)); |
3318 | (unsigned int)RREG32(RADEON_GRPH2_BUFFER_CNTL)); |
2876 | } |
3319 | } |
2877 | } |
3320 | } |
Line 2878... | Line -... | ||
2878 | - | ||
2879 | #if 0 |
- | |
2880 | static inline void r100_cs_track_texture_print(struct r100_cs_track_texture *t) |
- | |
2881 | { |
- | |
2882 | DRM_ERROR("pitch %d\n", t->pitch); |
- | |
2883 | DRM_ERROR("use_pitch %d\n", t->use_pitch); |
- | |
2884 | DRM_ERROR("width %d\n", t->width); |
- | |
2885 | DRM_ERROR("width_11 %d\n", t->width_11); |
- | |
2886 | DRM_ERROR("height %d\n", t->height); |
- | |
2887 | DRM_ERROR("height_11 %d\n", t->height_11); |
- | |
2888 | DRM_ERROR("num levels %d\n", t->num_levels); |
- | |
2889 | DRM_ERROR("depth %d\n", t->txdepth); |
- | |
2890 | DRM_ERROR("bpp %d\n", t->cpp); |
- | |
2891 | DRM_ERROR("coordinate type %d\n", t->tex_coord_type); |
- | |
2892 | DRM_ERROR("width round to power of 2 %d\n", t->roundup_w); |
- | |
2893 | DRM_ERROR("height round to power of 2 %d\n", t->roundup_h); |
- | |
2894 | DRM_ERROR("compress format %d\n", t->compress_format); |
- | |
2895 | } |
- | |
2896 | - | ||
2897 | static int r100_track_compress_size(int compress_format, int w, int h) |
- | |
2898 | { |
- | |
2899 | int block_width, block_height, block_bytes; |
- | |
2900 | int wblocks, hblocks; |
- | |
2901 | int min_wblocks; |
- | |
2902 | int sz; |
- | |
2903 | - | ||
2904 | block_width = 4; |
- | |
2905 | block_height = 4; |
- | |
2906 | - | ||
2907 | switch (compress_format) { |
- | |
2908 | case R100_TRACK_COMP_DXT1: |
- | |
2909 | block_bytes = 8; |
- | |
2910 | min_wblocks = 4; |
- | |
2911 | break; |
- | |
2912 | default: |
- | |
2913 | case R100_TRACK_COMP_DXT35: |
- | |
2914 | block_bytes = 16; |
- | |
2915 | min_wblocks = 2; |
- | |
2916 | break; |
- | |
2917 | } |
- | |
2918 | - | ||
2919 | hblocks = (h + block_height - 1) / block_height; |
- | |
2920 | wblocks = (w + block_width - 1) / block_width; |
- | |
2921 | if (wblocks < min_wblocks) |
- | |
2922 | wblocks = min_wblocks; |
- | |
2923 | sz = wblocks * hblocks * block_bytes; |
- | |
2924 | return sz; |
- | |
2925 | } |
- | |
2926 | - | ||
2927 | static int r100_cs_track_cube(struct radeon_device *rdev, |
- | |
2928 | struct r100_cs_track *track, unsigned idx) |
- | |
2929 | { |
- | |
2930 | unsigned face, w, h; |
- | |
2931 | struct radeon_bo *cube_robj; |
- | |
2932 | unsigned long size; |
- | |
2933 | unsigned compress_format = track->textures[idx].compress_format; |
- | |
2934 | - | ||
2935 | for (face = 0; face < 5; face++) { |
- | |
2936 | cube_robj = track->textures[idx].cube_info[face].robj; |
- | |
2937 | w = track->textures[idx].cube_info[face].width; |
- | |
2938 | h = track->textures[idx].cube_info[face].height; |
- | |
2939 | - | ||
2940 | if (compress_format) { |
- | |
2941 | size = r100_track_compress_size(compress_format, w, h); |
- | |
2942 | } else |
- | |
2943 | size = w * h; |
- | |
2944 | size *= track->textures[idx].cpp; |
- | |
2945 | - | ||
2946 | size += track->textures[idx].cube_info[face].offset; |
- | |
2947 | - | ||
2948 | if (size > radeon_bo_size(cube_robj)) { |
- | |
2949 | DRM_ERROR("Cube texture offset greater than object size %lu %lu\n", |
- | |
2950 | size, radeon_bo_size(cube_robj)); |
- | |
2951 | r100_cs_track_texture_print(&track->textures[idx]); |
- | |
2952 | return -1; |
- | |
2953 | } |
- | |
2954 | } |
- | |
2955 | return 0; |
- | |
2956 | } |
- | |
2957 | - | ||
2958 | static int r100_cs_track_texture_check(struct radeon_device *rdev, |
- | |
2959 | struct r100_cs_track *track) |
- | |
2960 | { |
- | |
2961 | struct radeon_bo *robj; |
- | |
2962 | unsigned long size; |
- | |
2963 | unsigned u, i, w, h, d; |
- | |
2964 | int ret; |
- | |
2965 | - | ||
2966 | for (u = 0; u < track->num_texture; u++) { |
- | |
2967 | if (!track->textures[u].enabled) |
- | |
2968 | continue; |
- | |
2969 | if (track->textures[u].lookup_disable) |
- | |
2970 | continue; |
- | |
2971 | robj = track->textures[u].robj; |
- | |
2972 | if (robj == NULL) { |
- | |
2973 | DRM_ERROR("No texture bound to unit %u\n", u); |
- | |
2974 | return -EINVAL; |
- | |
2975 | } |
- | |
2976 | size = 0; |
- | |
2977 | for (i = 0; i <= track->textures[u].num_levels; i++) { |
- | |
2978 | if (track->textures[u].use_pitch) { |
- | |
2979 | if (rdev->family < CHIP_R300) |
- | |
2980 | w = (track->textures[u].pitch / track->textures[u].cpp) / (1 << i); |
- | |
2981 | else |
- | |
2982 | w = track->textures[u].pitch / (1 << i); |
- | |
2983 | } else { |
- | |
2984 | w = track->textures[u].width; |
- | |
2985 | if (rdev->family >= CHIP_RV515) |
- | |
2986 | w |= track->textures[u].width_11; |
- | |
2987 | w = w / (1 << i); |
- | |
2988 | if (track->textures[u].roundup_w) |
- | |
2989 | w = roundup_pow_of_two(w); |
- | |
2990 | } |
- | |
2991 | h = track->textures[u].height; |
- | |
2992 | if (rdev->family >= CHIP_RV515) |
- | |
2993 | h |= track->textures[u].height_11; |
- | |
2994 | h = h / (1 << i); |
- | |
2995 | if (track->textures[u].roundup_h) |
- | |
2996 | h = roundup_pow_of_two(h); |
- | |
2997 | if (track->textures[u].tex_coord_type == 1) { |
- | |
2998 | d = (1 << track->textures[u].txdepth) / (1 << i); |
- | |
2999 | if (!d) |
- | |
3000 | d = 1; |
- | |
3001 | } else { |
- | |
3002 | d = 1; |
- | |
3003 | } |
- | |
3004 | if (track->textures[u].compress_format) { |
- | |
3005 | - | ||
3006 | size += r100_track_compress_size(track->textures[u].compress_format, w, h) * d; |
- | |
3007 | /* compressed textures are block based */ |
- | |
3008 | } else |
- | |
3009 | size += w * h * d; |
- | |
3010 | } |
- | |
3011 | size *= track->textures[u].cpp; |
- | |
3012 | - | ||
3013 | switch (track->textures[u].tex_coord_type) { |
- | |
3014 | case 0: |
- | |
3015 | case 1: |
- | |
3016 | break; |
- | |
3017 | case 2: |
- | |
3018 | if (track->separate_cube) { |
- | |
3019 | ret = r100_cs_track_cube(rdev, track, u); |
- | |
3020 | if (ret) |
- | |
3021 | return ret; |
- | |
3022 | } else |
- | |
3023 | size *= 6; |
- | |
3024 | break; |
- | |
3025 | default: |
- | |
3026 | DRM_ERROR("Invalid texture coordinate type %u for unit " |
- | |
3027 | "%u\n", track->textures[u].tex_coord_type, u); |
- | |
3028 | return -EINVAL; |
- | |
3029 | } |
- | |
3030 | if (size > radeon_bo_size(robj)) { |
- | |
3031 | DRM_ERROR("Texture of unit %u needs %lu bytes but is " |
- | |
3032 | "%lu\n", u, size, radeon_bo_size(robj)); |
- | |
3033 | r100_cs_track_texture_print(&track->textures[u]); |
- | |
3034 | return -EINVAL; |
- | |
3035 | } |
- | |
3036 | } |
- | |
3037 | return 0; |
- | |
3038 | } |
- | |
3039 | 3321 | ||
3040 | int r100_cs_track_check(struct radeon_device *rdev, struct r100_cs_track *track) |
- | |
3041 | { |
- | |
3042 | unsigned i; |
- | |
3043 | unsigned long size; |
- | |
3044 | unsigned prim_walk; |
- | |
3045 | unsigned nverts; |
- | |
3046 | unsigned num_cb = track->cb_dirty ? track->num_cb : 0; |
- | |
3047 | - | ||
3048 | if (num_cb && !track->zb_cb_clear && !track->color_channel_mask && |
- | |
3049 | !track->blend_read_enable) |
- | |
3050 | num_cb = 0; |
- | |
3051 | - | ||
3052 | for (i = 0; i < num_cb; i++) { |
- | |
3053 | if (track->cb[i].robj == NULL) { |
- | |
3054 | DRM_ERROR("[drm] No buffer for color buffer %d !\n", i); |
- | |
3055 | return -EINVAL; |
- | |
3056 | } |
- | |
3057 | size = track->cb[i].pitch * track->cb[i].cpp * track->maxy; |
- | |
3058 | size += track->cb[i].offset; |
- | |
3059 | if (size > radeon_bo_size(track->cb[i].robj)) { |
- | |
3060 | DRM_ERROR("[drm] Buffer too small for color buffer %d " |
- | |
3061 | "(need %lu have %lu) !\n", i, size, |
- | |
3062 | radeon_bo_size(track->cb[i].robj)); |
- | |
3063 | DRM_ERROR("[drm] color buffer %d (%u %u %u %u)\n", |
- | |
3064 | i, track->cb[i].pitch, track->cb[i].cpp, |
- | |
3065 | track->cb[i].offset, track->maxy); |
- | |
3066 | return -EINVAL; |
- | |
3067 | } |
- | |
3068 | } |
- | |
3069 | track->cb_dirty = false; |
- | |
3070 | - | ||
3071 | if (track->zb_dirty && track->z_enabled) { |
- | |
3072 | if (track->zb.robj == NULL) { |
- | |
3073 | DRM_ERROR("[drm] No buffer for z buffer !\n"); |
- | |
3074 | return -EINVAL; |
- | |
3075 | } |
- | |
3076 | size = track->zb.pitch * track->zb.cpp * track->maxy; |
- | |
3077 | size += track->zb.offset; |
- | |
3078 | if (size > radeon_bo_size(track->zb.robj)) { |
- | |
3079 | DRM_ERROR("[drm] Buffer too small for z buffer " |
- | |
3080 | "(need %lu have %lu) !\n", size, |
- | |
3081 | radeon_bo_size(track->zb.robj)); |
- | |
3082 | DRM_ERROR("[drm] zbuffer (%u %u %u %u)\n", |
- | |
3083 | track->zb.pitch, track->zb.cpp, |
- | |
3084 | track->zb.offset, track->maxy); |
- | |
3085 | return -EINVAL; |
- | |
3086 | } |
- | |
3087 | } |
- | |
3088 | track->zb_dirty = false; |
- | |
3089 | - | ||
3090 | if (track->aa_dirty && track->aaresolve) { |
- | |
3091 | if (track->aa.robj == NULL) { |
- | |
3092 | DRM_ERROR("[drm] No buffer for AA resolve buffer %d !\n", i); |
- | |
3093 | return -EINVAL; |
- | |
3094 | } |
- | |
3095 | /* I believe the format comes from colorbuffer0. */ |
- | |
3096 | size = track->aa.pitch * track->cb[0].cpp * track->maxy; |
- | |
3097 | size += track->aa.offset; |
- | |
3098 | if (size > radeon_bo_size(track->aa.robj)) { |
- | |
3099 | DRM_ERROR("[drm] Buffer too small for AA resolve buffer %d " |
- | |
3100 | "(need %lu have %lu) !\n", i, size, |
- | |
3101 | radeon_bo_size(track->aa.robj)); |
- | |
3102 | DRM_ERROR("[drm] AA resolve buffer %d (%u %u %u %u)\n", |
- | |
3103 | i, track->aa.pitch, track->cb[0].cpp, |
- | |
3104 | track->aa.offset, track->maxy); |
- | |
3105 | return -EINVAL; |
- | |
3106 | } |
- | |
3107 | } |
- | |
3108 | track->aa_dirty = false; |
- | |
3109 | - | ||
3110 | prim_walk = (track->vap_vf_cntl >> 4) & 0x3; |
- | |
3111 | if (track->vap_vf_cntl & (1 << 14)) { |
- | |
3112 | nverts = track->vap_alt_nverts; |
- | |
3113 | } else { |
- | |
3114 | nverts = (track->vap_vf_cntl >> 16) & 0xFFFF; |
- | |
3115 | } |
- | |
3116 | switch (prim_walk) { |
- | |
3117 | case 1: |
- | |
3118 | for (i = 0; i < track->num_arrays; i++) { |
- | |
3119 | size = track->arrays[i].esize * track->max_indx * 4; |
- | |
3120 | if (track->arrays[i].robj == NULL) { |
- | |
3121 | DRM_ERROR("(PW %u) Vertex array %u no buffer " |
- | |
3122 | "bound\n", prim_walk, i); |
- | |
3123 | return -EINVAL; |
- | |
3124 | } |
- | |
3125 | if (size > radeon_bo_size(track->arrays[i].robj)) { |
- | |
3126 | dev_err(rdev->dev, "(PW %u) Vertex array %u " |
- | |
3127 | "need %lu dwords have %lu dwords\n", |
- | |
3128 | prim_walk, i, size >> 2, |
- | |
3129 | radeon_bo_size(track->arrays[i].robj) |
- | |
3130 | >> 2); |
- | |
3131 | DRM_ERROR("Max indices %u\n", track->max_indx); |
- | |
3132 | return -EINVAL; |
- | |
3133 | } |
- | |
3134 | } |
- | |
3135 | break; |
- | |
3136 | case 2: |
- | |
3137 | for (i = 0; i < track->num_arrays; i++) { |
- | |
3138 | size = track->arrays[i].esize * (nverts - 1) * 4; |
- | |
3139 | if (track->arrays[i].robj == NULL) { |
- | |
3140 | DRM_ERROR("(PW %u) Vertex array %u no buffer " |
- | |
3141 | "bound\n", prim_walk, i); |
- | |
3142 | return -EINVAL; |
- | |
3143 | } |
- | |
3144 | if (size > radeon_bo_size(track->arrays[i].robj)) { |
- | |
3145 | dev_err(rdev->dev, "(PW %u) Vertex array %u " |
- | |
3146 | "need %lu dwords have %lu dwords\n", |
- | |
3147 | prim_walk, i, size >> 2, |
- | |
3148 | radeon_bo_size(track->arrays[i].robj) |
- | |
3149 | >> 2); |
- | |
3150 | return -EINVAL; |
- | |
3151 | } |
- | |
3152 | } |
- | |
3153 | break; |
- | |
3154 | case 3: |
- | |
3155 | size = track->vtx_size * nverts; |
- | |
3156 | if (size != track->immd_dwords) { |
- | |
3157 | DRM_ERROR("IMMD draw %u dwors but needs %lu dwords\n", |
- | |
3158 | track->immd_dwords, size); |
- | |
3159 | DRM_ERROR("VAP_VF_CNTL.NUM_VERTICES %u, VTX_SIZE %u\n", |
- | |
3160 | nverts, track->vtx_size); |
- | |
3161 | return -EINVAL; |
- | |
3162 | } |
- | |
3163 | break; |
- | |
3164 | default: |
- | |
3165 | DRM_ERROR("[drm] Invalid primitive walk %d for VAP_VF_CNTL\n", |
- | |
3166 | prim_walk); |
- | |
3167 | return -EINVAL; |
- | |
3168 | } |
- | |
3169 | - | ||
3170 | if (track->tex_dirty) { |
- | |
3171 | track->tex_dirty = false; |
- | |
3172 | return r100_cs_track_texture_check(rdev, track); |
- | |
3173 | } |
- | |
3174 | return 0; |
- | |
3175 | } |
- | |
3176 | - | ||
3177 | void r100_cs_track_clear(struct radeon_device *rdev, struct r100_cs_track *track) |
- | |
3178 | { |
- | |
3179 | unsigned i, face; |
- | |
3180 | - | ||
3181 | track->cb_dirty = true; |
- | |
3182 | track->zb_dirty = true; |
- | |
3183 | track->tex_dirty = true; |
- | |
3184 | track->aa_dirty = true; |
- | |
3185 | - | ||
3186 | if (rdev->family < CHIP_R300) { |
- | |
3187 | track->num_cb = 1; |
- | |
3188 | if (rdev->family <= CHIP_RS200) |
- | |
3189 | track->num_texture = 3; |
- | |
3190 | else |
- | |
3191 | track->num_texture = 6; |
- | |
3192 | track->maxy = 2048; |
- | |
3193 | track->separate_cube = 1; |
- | |
3194 | } else { |
- | |
3195 | track->num_cb = 4; |
- | |
3196 | track->num_texture = 16; |
- | |
3197 | track->maxy = 4096; |
- | |
3198 | track->separate_cube = 0; |
- | |
3199 | track->aaresolve = false; |
- | |
3200 | track->aa.robj = NULL; |
- | |
3201 | } |
- | |
3202 | - | ||
3203 | for (i = 0; i < track->num_cb; i++) { |
- | |
3204 | track->cb[i].robj = NULL; |
- | |
3205 | track->cb[i].pitch = 8192; |
- | |
3206 | track->cb[i].cpp = 16; |
- | |
3207 | track->cb[i].offset = 0; |
- | |
3208 | } |
- | |
3209 | track->z_enabled = true; |
- | |
3210 | track->zb.robj = NULL; |
- | |
3211 | track->zb.pitch = 8192; |
- | |
3212 | track->zb.cpp = 4; |
- | |
3213 | track->zb.offset = 0; |
- | |
3214 | track->vtx_size = 0x7F; |
- | |
3215 | track->immd_dwords = 0xFFFFFFFFUL; |
- | |
3216 | track->num_arrays = 11; |
- | |
3217 | track->max_indx = 0x00FFFFFFUL; |
- | |
3218 | for (i = 0; i < track->num_arrays; i++) { |
- | |
3219 | track->arrays[i].robj = NULL; |
- | |
3220 | track->arrays[i].esize = 0x7F; |
- | |
3221 | } |
- | |
3222 | for (i = 0; i < track->num_texture; i++) { |
- | |
3223 | track->textures[i].compress_format = R100_TRACK_COMP_NONE; |
- | |
3224 | track->textures[i].pitch = 16536; |
- | |
3225 | track->textures[i].width = 16536; |
- | |
3226 | track->textures[i].height = 16536; |
- | |
3227 | track->textures[i].width_11 = 1 << 11; |
- | |
3228 | track->textures[i].height_11 = 1 << 11; |
- | |
3229 | track->textures[i].num_levels = 12; |
- | |
3230 | if (rdev->family <= CHIP_RS200) { |
- | |
3231 | track->textures[i].tex_coord_type = 0; |
- | |
3232 | track->textures[i].txdepth = 0; |
- | |
3233 | } else { |
- | |
3234 | track->textures[i].txdepth = 16; |
- | |
3235 | track->textures[i].tex_coord_type = 1; |
- | |
3236 | } |
- | |
3237 | track->textures[i].cpp = 64; |
- | |
3238 | track->textures[i].robj = NULL; |
- | |
3239 | /* CS IB emission code makes sure texture unit are disabled */ |
- | |
3240 | track->textures[i].enabled = false; |
- | |
3241 | track->textures[i].lookup_disable = false; |
- | |
3242 | track->textures[i].roundup_w = true; |
- | |
3243 | track->textures[i].roundup_h = true; |
- | |
3244 | if (track->separate_cube) |
- | |
3245 | for (face = 0; face < 5; face++) { |
- | |
3246 | track->textures[i].cube_info[face].robj = NULL; |
- | |
3247 | track->textures[i].cube_info[face].width = 16536; |
- | |
3248 | track->textures[i].cube_info[face].height = 16536; |
- | |
3249 | track->textures[i].cube_info[face].offset = 0; |
- | |
3250 | } |
- | |
3251 | } |
- | |
3252 | } |
- | |
3253 | #endif |
- | |
3254 | - | ||
3255 | int r100_ring_test(struct radeon_device *rdev) |
3322 | int r100_ring_test(struct radeon_device *rdev, struct radeon_ring *ring) |
3256 | { |
3323 | { |
3257 | uint32_t scratch; |
3324 | uint32_t scratch; |
3258 | uint32_t tmp = 0; |
3325 | uint32_t tmp = 0; |
3259 | unsigned i; |
3326 | unsigned i; |
Line 3263... | Line 3330... | ||
3263 | if (r) { |
3330 | if (r) { |
3264 | DRM_ERROR("radeon: cp failed to get scratch reg (%d).\n", r); |
3331 | DRM_ERROR("radeon: cp failed to get scratch reg (%d).\n", r); |
3265 | return r; |
3332 | return r; |
3266 | } |
3333 | } |
3267 | WREG32(scratch, 0xCAFEDEAD); |
3334 | WREG32(scratch, 0xCAFEDEAD); |
3268 | r = radeon_ring_lock(rdev, 2); |
3335 | r = radeon_ring_lock(rdev, ring, 2); |
3269 | if (r) { |
3336 | if (r) { |
3270 | DRM_ERROR("radeon: cp failed to lock ring (%d).\n", r); |
3337 | DRM_ERROR("radeon: cp failed to lock ring (%d).\n", r); |
3271 | radeon_scratch_free(rdev, scratch); |
3338 | radeon_scratch_free(rdev, scratch); |
3272 | return r; |
3339 | return r; |
3273 | } |
3340 | } |
3274 | radeon_ring_write(rdev, PACKET0(scratch, 0)); |
3341 | radeon_ring_write(ring, PACKET0(scratch, 0)); |
3275 | radeon_ring_write(rdev, 0xDEADBEEF); |
3342 | radeon_ring_write(ring, 0xDEADBEEF); |
3276 | radeon_ring_unlock_commit(rdev); |
3343 | radeon_ring_unlock_commit(rdev, ring); |
3277 | for (i = 0; i < rdev->usec_timeout; i++) { |
3344 | for (i = 0; i < rdev->usec_timeout; i++) { |
3278 | tmp = RREG32(scratch); |
3345 | tmp = RREG32(scratch); |
3279 | if (tmp == 0xDEADBEEF) { |
3346 | if (tmp == 0xDEADBEEF) { |
3280 | break; |
3347 | break; |
3281 | } |
3348 | } |
Line 3292... | Line 3359... | ||
3292 | return r; |
3359 | return r; |
3293 | } |
3360 | } |
Line 3294... | Line 3361... | ||
3294 | 3361 | ||
3295 | void r100_ring_ib_execute(struct radeon_device *rdev, struct radeon_ib *ib) |
3362 | void r100_ring_ib_execute(struct radeon_device *rdev, struct radeon_ib *ib) |
3296 | { |
3363 | { |
- | 3364 | struct radeon_ring *ring = &rdev->ring[RADEON_RING_TYPE_GFX_INDEX]; |
|
- | 3365 | ||
- | 3366 | if (ring->rptr_save_reg) { |
|
3297 | radeon_ring_write(rdev, PACKET0(RADEON_CP_IB_BASE, 1)); |
3367 | u32 next_rptr = ring->wptr + 2 + 3; |
3298 | radeon_ring_write(rdev, ib->gpu_addr); |
3368 | radeon_ring_write(ring, PACKET0(ring->rptr_save_reg, 0)); |
3299 | radeon_ring_write(rdev, ib->length_dw); |
3369 | radeon_ring_write(ring, next_rptr); |
Line -... | Line 3370... | ||
- | 3370 | } |
|
- | 3371 | ||
- | 3372 | radeon_ring_write(ring, PACKET0(RADEON_CP_IB_BASE, 1)); |
|
- | 3373 | radeon_ring_write(ring, ib->gpu_addr); |
|
- | 3374 | radeon_ring_write(ring, ib->length_dw); |
|
3300 | } |
3375 | } |
3301 | 3376 | ||
3302 | int r100_ib_test(struct radeon_device *rdev) |
3377 | int r100_ib_test(struct radeon_device *rdev, struct radeon_ring *ring) |
3303 | { |
3378 | { |
3304 | struct radeon_ib *ib; |
3379 | struct radeon_ib ib; |
3305 | uint32_t scratch; |
3380 | uint32_t scratch; |
3306 | uint32_t tmp = 0; |
3381 | uint32_t tmp = 0; |
Line 3311... | Line 3386... | ||
3311 | if (r) { |
3386 | if (r) { |
3312 | DRM_ERROR("radeon: failed to get scratch reg (%d).\n", r); |
3387 | DRM_ERROR("radeon: failed to get scratch reg (%d).\n", r); |
3313 | return r; |
3388 | return r; |
3314 | } |
3389 | } |
3315 | WREG32(scratch, 0xCAFEDEAD); |
3390 | WREG32(scratch, 0xCAFEDEAD); |
3316 | r = radeon_ib_get(rdev, &ib); |
3391 | r = radeon_ib_get(rdev, RADEON_RING_TYPE_GFX_INDEX, &ib, NULL, 256); |
3317 | if (r) { |
3392 | if (r) { |
- | 3393 | DRM_ERROR("radeon: failed to get ib (%d).\n", r); |
|
3318 | return r; |
3394 | goto free_scratch; |
3319 | } |
3395 | } |
3320 | ib->ptr[0] = PACKET0(scratch, 0); |
3396 | ib.ptr[0] = PACKET0(scratch, 0); |
3321 | ib->ptr[1] = 0xDEADBEEF; |
3397 | ib.ptr[1] = 0xDEADBEEF; |
3322 | ib->ptr[2] = PACKET2(0); |
3398 | ib.ptr[2] = PACKET2(0); |
3323 | ib->ptr[3] = PACKET2(0); |
3399 | ib.ptr[3] = PACKET2(0); |
3324 | ib->ptr[4] = PACKET2(0); |
3400 | ib.ptr[4] = PACKET2(0); |
3325 | ib->ptr[5] = PACKET2(0); |
3401 | ib.ptr[5] = PACKET2(0); |
3326 | ib->ptr[6] = PACKET2(0); |
3402 | ib.ptr[6] = PACKET2(0); |
3327 | ib->ptr[7] = PACKET2(0); |
3403 | ib.ptr[7] = PACKET2(0); |
3328 | ib->length_dw = 8; |
3404 | ib.length_dw = 8; |
3329 | r = radeon_ib_schedule(rdev, ib); |
3405 | r = radeon_ib_schedule(rdev, &ib, NULL); |
3330 | if (r) { |
3406 | if (r) { |
3331 | radeon_scratch_free(rdev, scratch); |
3407 | DRM_ERROR("radeon: failed to schedule ib (%d).\n", r); |
3332 | radeon_ib_free(rdev, &ib); |
- | |
3333 | return r; |
3408 | goto free_ib; |
3334 | } |
3409 | } |
3335 | r = radeon_fence_wait(ib->fence, false); |
3410 | r = radeon_fence_wait(ib.fence, false); |
3336 | if (r) { |
3411 | if (r) { |
- | 3412 | DRM_ERROR("radeon: fence wait failed (%d).\n", r); |
|
3337 | return r; |
3413 | goto free_ib; |
3338 | } |
3414 | } |
3339 | for (i = 0; i < rdev->usec_timeout; i++) { |
3415 | for (i = 0; i < rdev->usec_timeout; i++) { |
3340 | tmp = RREG32(scratch); |
3416 | tmp = RREG32(scratch); |
3341 | if (tmp == 0xDEADBEEF) { |
3417 | if (tmp == 0xDEADBEEF) { |
3342 | break; |
3418 | break; |
Line 3348... | Line 3424... | ||
3348 | } else { |
3424 | } else { |
3349 | DRM_ERROR("radeon: ib test failed (scratch(0x%04X)=0x%08X)\n", |
3425 | DRM_ERROR("radeon: ib test failed (scratch(0x%04X)=0x%08X)\n", |
3350 | scratch, tmp); |
3426 | scratch, tmp); |
3351 | r = -EINVAL; |
3427 | r = -EINVAL; |
3352 | } |
3428 | } |
3353 | radeon_scratch_free(rdev, scratch); |
3429 | free_ib: |
3354 | radeon_ib_free(rdev, &ib); |
3430 | radeon_ib_free(rdev, &ib); |
- | 3431 | free_scratch: |
|
- | 3432 | radeon_scratch_free(rdev, scratch); |
|
3355 | return r; |
3433 | return r; |
3356 | } |
3434 | } |
Line 3357... | Line -... | ||
3357 | - | ||
3358 | void r100_ib_fini(struct radeon_device *rdev) |
- | |
3359 | { |
- | |
3360 | radeon_ib_pool_fini(rdev); |
- | |
3361 | } |
- | |
3362 | - | ||
3363 | int r100_ib_init(struct radeon_device *rdev) |
- | |
3364 | { |
- | |
3365 | int r; |
- | |
3366 | - | ||
3367 | r = radeon_ib_pool_init(rdev); |
- | |
3368 | if (r) { |
- | |
3369 | dev_err(rdev->dev, "failed initializing IB pool (%d).\n", r); |
- | |
3370 | r100_ib_fini(rdev); |
- | |
3371 | return r; |
- | |
3372 | } |
- | |
3373 | r = r100_ib_test(rdev); |
- | |
3374 | if (r) { |
- | |
3375 | dev_err(rdev->dev, "failed testing IB (%d).\n", r); |
- | |
3376 | r100_ib_fini(rdev); |
- | |
3377 | return r; |
- | |
3378 | } |
- | |
3379 | return 0; |
- | |
3380 | } |
- | |
3381 | 3435 | ||
3382 | void r100_mc_stop(struct radeon_device *rdev, struct r100_mc_save *save) |
3436 | void r100_mc_stop(struct radeon_device *rdev, struct r100_mc_save *save) |
3383 | { |
3437 | { |
3384 | /* Shutdown CP we shouldn't need to do that but better be safe than |
3438 | /* Shutdown CP we shouldn't need to do that but better be safe than |
3385 | * sorry |
3439 | * sorry |
3386 | */ |
3440 | */ |
3387 | rdev->cp.ready = false; |
3441 | rdev->ring[RADEON_RING_TYPE_GFX_INDEX].ready = false; |
Line 3388... | Line 3442... | ||
3388 | WREG32(R_000740_CP_CSQ_CNTL, 0); |
3442 | WREG32(R_000740_CP_CSQ_CNTL, 0); |
3389 | 3443 | ||
3390 | /* Save few CRTC registers */ |
3444 | /* Save few CRTC registers */ |
Line 3452... | Line 3506... | ||
3452 | r = r100_debugfs_mc_info_init(rdev); |
3506 | r = r100_debugfs_mc_info_init(rdev); |
3453 | if (r) |
3507 | if (r) |
3454 | dev_warn(rdev->dev, "Failed to create r100_mc debugfs file.\n"); |
3508 | dev_warn(rdev->dev, "Failed to create r100_mc debugfs file.\n"); |
3455 | } |
3509 | } |
Line 3456... | Line -... | ||
3456 | - | ||
3457 | - | ||
3458 | int drm_order(unsigned long size) |
- | |
3459 | { |
- | |
3460 | int order; |
- | |
3461 | unsigned long tmp; |
- | |
3462 | - | ||
3463 | for (order = 0, tmp = size >> 1; tmp; tmp >>= 1, order++) ; |
- | |
3464 | - | ||
3465 | if (size & (size - 1)) |
- | |
3466 | ++order; |
- | |
3467 | - | ||
3468 | return order; |
- | |
3469 | } |
- | |
3470 | 3510 | ||
3471 | static void r100_mc_program(struct radeon_device *rdev) |
3511 | static void r100_mc_program(struct radeon_device *rdev) |
3472 | { |
3512 | { |
Line 3473... | Line 3513... | ||
3473 | struct r100_mc_save save; |
3513 | struct r100_mc_save save; |
Line 3496... | Line 3536... | ||
3496 | S_000148_MC_FB_START(rdev->mc.vram_start >> 16) | |
3536 | S_000148_MC_FB_START(rdev->mc.vram_start >> 16) | |
3497 | S_000148_MC_FB_TOP(rdev->mc.vram_end >> 16)); |
3537 | S_000148_MC_FB_TOP(rdev->mc.vram_end >> 16)); |
3498 | r100_mc_resume(rdev, &save); |
3538 | r100_mc_resume(rdev, &save); |
3499 | } |
3539 | } |
Line 3500... | Line 3540... | ||
3500 | 3540 | ||
3501 | void r100_clock_startup(struct radeon_device *rdev) |
3541 | static void r100_clock_startup(struct radeon_device *rdev) |
3502 | { |
3542 | { |
Line 3503... | Line 3543... | ||
3503 | u32 tmp; |
3543 | u32 tmp; |
3504 | 3544 | ||
Line 3543... | Line 3583... | ||
3543 | r = r100_cp_init(rdev, 1024 * 1024); |
3583 | r = r100_cp_init(rdev, 1024 * 1024); |
3544 | if (r) { |
3584 | if (r) { |
3545 | dev_err(rdev->dev, "failed initializing CP (%d).\n", r); |
3585 | dev_err(rdev->dev, "failed initializing CP (%d).\n", r); |
3546 | return r; |
3586 | return r; |
3547 | } |
3587 | } |
- | 3588 | ||
3548 | r = r100_ib_init(rdev); |
3589 | r = radeon_ib_pool_init(rdev); |
3549 | if (r) { |
3590 | if (r) { |
3550 | dev_err(rdev->dev, "failed initializing IB (%d).\n", r); |
3591 | dev_err(rdev->dev, "IB initialization failed (%d).\n", r); |
3551 | return r; |
3592 | return r; |
3552 | } |
3593 | } |
3553 | return 0; |
3594 | return 0; |
3554 | } |
3595 | } |
Line 3644... | Line 3685... | ||
3644 | r = r100_pci_gart_init(rdev); |
3685 | r = r100_pci_gart_init(rdev); |
3645 | if (r) |
3686 | if (r) |
3646 | return r; |
3687 | return r; |
3647 | } |
3688 | } |
3648 | r100_set_safe_registers(rdev); |
3689 | r100_set_safe_registers(rdev); |
- | 3690 | ||
3649 | rdev->accel_working = true; |
3691 | rdev->accel_working = true; |
3650 | r = r100_startup(rdev); |
3692 | r = r100_startup(rdev); |
3651 | if (r) { |
3693 | if (r) { |
3652 | /* Somethings want wront with the accel init stop accel */ |
3694 | /* Somethings want wront with the accel init stop accel */ |
3653 | dev_err(rdev->dev, "Disabling GPU acceleration\n"); |
3695 | dev_err(rdev->dev, "Disabling GPU acceleration\n"); |
Line 3655... | Line 3697... | ||
3655 | r100_pci_gart_fini(rdev); |
3697 | r100_pci_gart_fini(rdev); |
3656 | rdev->accel_working = false; |
3698 | rdev->accel_working = false; |
3657 | } |
3699 | } |
3658 | return 0; |
3700 | return 0; |
3659 | }>>>>>=>><>><>>>>=>>>>><>>><>><>><>><>><>><>>=>>>>><>><>><>><>><>>>><>><>><>><>><>><>><>><>><>>=>>>><>=>><>><>><>><>>=>=>><>>><>=>><>>=>>>><>><>=>><>>>>>>>><>><>>><>><>><>><>><>>><>><>=>><>=>><>><>><>>>><>><>><>><>><>><>> |
3701 | } |
- | 3702 | ||
- | 3703 | uint32_t r100_mm_rreg(struct radeon_device *rdev, uint32_t reg) |
|
- | 3704 | { |
|
- | 3705 | if (reg < rdev->rmmio_size) |
|
- | 3706 | return readl(((void __iomem *)rdev->rmmio) + reg); |
|
- | 3707 | else { |
|
- | 3708 | writel(reg, ((void __iomem *)rdev->rmmio) + RADEON_MM_INDEX); |
|
- | 3709 | return readl(((void __iomem *)rdev->rmmio) + RADEON_MM_DATA); |
|
- | 3710 | } |
|
- | 3711 | } |
|
- | 3712 | ||
- | 3713 | void r100_mm_wreg(struct radeon_device *rdev, uint32_t reg, uint32_t v) |
|
- | 3714 | { |
|
- | 3715 | if (reg < rdev->rmmio_size) |
|
- | 3716 | writel(v, ((void __iomem *)rdev->rmmio) + reg); |
|
- | 3717 | else { |
|
- | 3718 | writel(reg, ((void __iomem *)rdev->rmmio) + RADEON_MM_INDEX); |
|
- | 3719 | writel(v, ((void __iomem *)rdev->rmmio) + RADEON_MM_DATA); |
|
- | 3720 | } |
|
- | 3721 | } |
|
- | 3722 | ||
- | 3723 | u32 r100_io_rreg(struct radeon_device *rdev, u32 reg) |
|
- | 3724 | { |
|
- | 3725 | if (reg < rdev->rio_mem_size) |
|
- | 3726 | return ioread32(rdev->rio_mem + reg); |
|
- | 3727 | else { |
|
- | 3728 | iowrite32(reg, rdev->rio_mem + RADEON_MM_INDEX); |
|
- | 3729 | return ioread32(rdev->rio_mem + RADEON_MM_DATA); |
|
- | 3730 | } |
|
- | 3731 | } |
|
- | 3732 | ||
- | 3733 | void r100_io_wreg(struct radeon_device *rdev, u32 reg, u32 v) |
|
- | 3734 | { |
|
- | 3735 | if (reg < rdev->rio_mem_size) |
|
- | 3736 | iowrite32(v, rdev->rio_mem + reg); |
|
- | 3737 | else { |
|
- | 3738 | iowrite32(reg, rdev->rio_mem + RADEON_MM_INDEX); |
|
- | 3739 | iowrite32(v, rdev->rio_mem + RADEON_MM_DATA); |
|
- | 3740 | } |
|
- | 3741 | }>>>>>>>>><>><>><>><>><>>>><>><>><>><>><>><>><>><>><>>=>>>><>=>><>><>><>><>>=>=>><>>><>=>><>>=>>>><>><>=>><>>>>>=>><>><>>>>=>>>>><>>><>><>><>><>><>><>>=>>>>>><>><>>><>><>><>><>><>>><>><>><>=>><>=>><>>><>><>>>><>><>><>><>><>><>>><>><>>>>>> |