diff options
Diffstat (limited to 'drivers/gpu/drm/radeon/r600.c')
-rw-r--r-- | drivers/gpu/drm/radeon/r600.c | 1462 |
1 files changed, 1279 insertions, 183 deletions
diff --git a/drivers/gpu/drm/radeon/r600.c b/drivers/gpu/drm/radeon/r600.c index 278f646bc18e..8f3454e2056a 100644 --- a/drivers/gpu/drm/radeon/r600.c +++ b/drivers/gpu/drm/radeon/r600.c | |||
@@ -25,12 +25,14 @@ | |||
25 | * Alex Deucher | 25 | * Alex Deucher |
26 | * Jerome Glisse | 26 | * Jerome Glisse |
27 | */ | 27 | */ |
28 | #include <linux/slab.h> | ||
28 | #include <linux/seq_file.h> | 29 | #include <linux/seq_file.h> |
29 | #include <linux/firmware.h> | 30 | #include <linux/firmware.h> |
30 | #include <linux/platform_device.h> | 31 | #include <linux/platform_device.h> |
31 | #include "drmP.h" | 32 | #include "drmP.h" |
32 | #include "radeon_drm.h" | 33 | #include "radeon_drm.h" |
33 | #include "radeon.h" | 34 | #include "radeon.h" |
35 | #include "radeon_asic.h" | ||
34 | #include "radeon_mode.h" | 36 | #include "radeon_mode.h" |
35 | #include "r600d.h" | 37 | #include "r600d.h" |
36 | #include "atom.h" | 38 | #include "atom.h" |
@@ -38,8 +40,10 @@ | |||
38 | 40 | ||
39 | #define PFP_UCODE_SIZE 576 | 41 | #define PFP_UCODE_SIZE 576 |
40 | #define PM4_UCODE_SIZE 1792 | 42 | #define PM4_UCODE_SIZE 1792 |
43 | #define RLC_UCODE_SIZE 768 | ||
41 | #define R700_PFP_UCODE_SIZE 848 | 44 | #define R700_PFP_UCODE_SIZE 848 |
42 | #define R700_PM4_UCODE_SIZE 1360 | 45 | #define R700_PM4_UCODE_SIZE 1360 |
46 | #define R700_RLC_UCODE_SIZE 1024 | ||
43 | 47 | ||
44 | /* Firmware Names */ | 48 | /* Firmware Names */ |
45 | MODULE_FIRMWARE("radeon/R600_pfp.bin"); | 49 | MODULE_FIRMWARE("radeon/R600_pfp.bin"); |
@@ -62,6 +66,8 @@ MODULE_FIRMWARE("radeon/RV730_pfp.bin"); | |||
62 | MODULE_FIRMWARE("radeon/RV730_me.bin"); | 66 | MODULE_FIRMWARE("radeon/RV730_me.bin"); |
63 | MODULE_FIRMWARE("radeon/RV710_pfp.bin"); | 67 | MODULE_FIRMWARE("radeon/RV710_pfp.bin"); |
64 | MODULE_FIRMWARE("radeon/RV710_me.bin"); | 68 | MODULE_FIRMWARE("radeon/RV710_me.bin"); |
69 | MODULE_FIRMWARE("radeon/R600_rlc.bin"); | ||
70 | MODULE_FIRMWARE("radeon/R700_rlc.bin"); | ||
65 | 71 | ||
66 | int r600_debugfs_mc_info_init(struct radeon_device *rdev); | 72 | int r600_debugfs_mc_info_init(struct radeon_device *rdev); |
67 | 73 | ||
@@ -70,26 +76,293 @@ int r600_mc_wait_for_idle(struct radeon_device *rdev); | |||
70 | void r600_gpu_init(struct radeon_device *rdev); | 76 | void r600_gpu_init(struct radeon_device *rdev); |
71 | void r600_fini(struct radeon_device *rdev); | 77 | void r600_fini(struct radeon_device *rdev); |
72 | 78 | ||
73 | /* | 79 | /* hpd for digital panel detect/disconnect */ |
74 | * R600 PCIE GART | 80 | bool r600_hpd_sense(struct radeon_device *rdev, enum radeon_hpd_id hpd) |
75 | */ | ||
76 | int r600_gart_clear_page(struct radeon_device *rdev, int i) | ||
77 | { | 81 | { |
78 | void __iomem *ptr = (void *)rdev->gart.table.vram.ptr; | 82 | bool connected = false; |
79 | u64 pte; | ||
80 | 83 | ||
81 | if (i < 0 || i > rdev->gart.num_gpu_pages) | 84 | if (ASIC_IS_DCE3(rdev)) { |
82 | return -EINVAL; | 85 | switch (hpd) { |
83 | pte = 0; | 86 | case RADEON_HPD_1: |
84 | writeq(pte, ((void __iomem *)ptr) + (i * 8)); | 87 | if (RREG32(DC_HPD1_INT_STATUS) & DC_HPDx_SENSE) |
85 | return 0; | 88 | connected = true; |
89 | break; | ||
90 | case RADEON_HPD_2: | ||
91 | if (RREG32(DC_HPD2_INT_STATUS) & DC_HPDx_SENSE) | ||
92 | connected = true; | ||
93 | break; | ||
94 | case RADEON_HPD_3: | ||
95 | if (RREG32(DC_HPD3_INT_STATUS) & DC_HPDx_SENSE) | ||
96 | connected = true; | ||
97 | break; | ||
98 | case RADEON_HPD_4: | ||
99 | if (RREG32(DC_HPD4_INT_STATUS) & DC_HPDx_SENSE) | ||
100 | connected = true; | ||
101 | break; | ||
102 | /* DCE 3.2 */ | ||
103 | case RADEON_HPD_5: | ||
104 | if (RREG32(DC_HPD5_INT_STATUS) & DC_HPDx_SENSE) | ||
105 | connected = true; | ||
106 | break; | ||
107 | case RADEON_HPD_6: | ||
108 | if (RREG32(DC_HPD6_INT_STATUS) & DC_HPDx_SENSE) | ||
109 | connected = true; | ||
110 | break; | ||
111 | default: | ||
112 | break; | ||
113 | } | ||
114 | } else { | ||
115 | switch (hpd) { | ||
116 | case RADEON_HPD_1: | ||
117 | if (RREG32(DC_HOT_PLUG_DETECT1_INT_STATUS) & DC_HOT_PLUG_DETECTx_SENSE) | ||
118 | connected = true; | ||
119 | break; | ||
120 | case RADEON_HPD_2: | ||
121 | if (RREG32(DC_HOT_PLUG_DETECT2_INT_STATUS) & DC_HOT_PLUG_DETECTx_SENSE) | ||
122 | connected = true; | ||
123 | break; | ||
124 | case RADEON_HPD_3: | ||
125 | if (RREG32(DC_HOT_PLUG_DETECT3_INT_STATUS) & DC_HOT_PLUG_DETECTx_SENSE) | ||
126 | connected = true; | ||
127 | break; | ||
128 | default: | ||
129 | break; | ||
130 | } | ||
131 | } | ||
132 | return connected; | ||
133 | } | ||
134 | |||
135 | void r600_hpd_set_polarity(struct radeon_device *rdev, | ||
136 | enum radeon_hpd_id hpd) | ||
137 | { | ||
138 | u32 tmp; | ||
139 | bool connected = r600_hpd_sense(rdev, hpd); | ||
140 | |||
141 | if (ASIC_IS_DCE3(rdev)) { | ||
142 | switch (hpd) { | ||
143 | case RADEON_HPD_1: | ||
144 | tmp = RREG32(DC_HPD1_INT_CONTROL); | ||
145 | if (connected) | ||
146 | tmp &= ~DC_HPDx_INT_POLARITY; | ||
147 | else | ||
148 | tmp |= DC_HPDx_INT_POLARITY; | ||
149 | WREG32(DC_HPD1_INT_CONTROL, tmp); | ||
150 | break; | ||
151 | case RADEON_HPD_2: | ||
152 | tmp = RREG32(DC_HPD2_INT_CONTROL); | ||
153 | if (connected) | ||
154 | tmp &= ~DC_HPDx_INT_POLARITY; | ||
155 | else | ||
156 | tmp |= DC_HPDx_INT_POLARITY; | ||
157 | WREG32(DC_HPD2_INT_CONTROL, tmp); | ||
158 | break; | ||
159 | case RADEON_HPD_3: | ||
160 | tmp = RREG32(DC_HPD3_INT_CONTROL); | ||
161 | if (connected) | ||
162 | tmp &= ~DC_HPDx_INT_POLARITY; | ||
163 | else | ||
164 | tmp |= DC_HPDx_INT_POLARITY; | ||
165 | WREG32(DC_HPD3_INT_CONTROL, tmp); | ||
166 | break; | ||
167 | case RADEON_HPD_4: | ||
168 | tmp = RREG32(DC_HPD4_INT_CONTROL); | ||
169 | if (connected) | ||
170 | tmp &= ~DC_HPDx_INT_POLARITY; | ||
171 | else | ||
172 | tmp |= DC_HPDx_INT_POLARITY; | ||
173 | WREG32(DC_HPD4_INT_CONTROL, tmp); | ||
174 | break; | ||
175 | case RADEON_HPD_5: | ||
176 | tmp = RREG32(DC_HPD5_INT_CONTROL); | ||
177 | if (connected) | ||
178 | tmp &= ~DC_HPDx_INT_POLARITY; | ||
179 | else | ||
180 | tmp |= DC_HPDx_INT_POLARITY; | ||
181 | WREG32(DC_HPD5_INT_CONTROL, tmp); | ||
182 | break; | ||
183 | /* DCE 3.2 */ | ||
184 | case RADEON_HPD_6: | ||
185 | tmp = RREG32(DC_HPD6_INT_CONTROL); | ||
186 | if (connected) | ||
187 | tmp &= ~DC_HPDx_INT_POLARITY; | ||
188 | else | ||
189 | tmp |= DC_HPDx_INT_POLARITY; | ||
190 | WREG32(DC_HPD6_INT_CONTROL, tmp); | ||
191 | break; | ||
192 | default: | ||
193 | break; | ||
194 | } | ||
195 | } else { | ||
196 | switch (hpd) { | ||
197 | case RADEON_HPD_1: | ||
198 | tmp = RREG32(DC_HOT_PLUG_DETECT1_INT_CONTROL); | ||
199 | if (connected) | ||
200 | tmp &= ~DC_HOT_PLUG_DETECTx_INT_POLARITY; | ||
201 | else | ||
202 | tmp |= DC_HOT_PLUG_DETECTx_INT_POLARITY; | ||
203 | WREG32(DC_HOT_PLUG_DETECT1_INT_CONTROL, tmp); | ||
204 | break; | ||
205 | case RADEON_HPD_2: | ||
206 | tmp = RREG32(DC_HOT_PLUG_DETECT2_INT_CONTROL); | ||
207 | if (connected) | ||
208 | tmp &= ~DC_HOT_PLUG_DETECTx_INT_POLARITY; | ||
209 | else | ||
210 | tmp |= DC_HOT_PLUG_DETECTx_INT_POLARITY; | ||
211 | WREG32(DC_HOT_PLUG_DETECT2_INT_CONTROL, tmp); | ||
212 | break; | ||
213 | case RADEON_HPD_3: | ||
214 | tmp = RREG32(DC_HOT_PLUG_DETECT3_INT_CONTROL); | ||
215 | if (connected) | ||
216 | tmp &= ~DC_HOT_PLUG_DETECTx_INT_POLARITY; | ||
217 | else | ||
218 | tmp |= DC_HOT_PLUG_DETECTx_INT_POLARITY; | ||
219 | WREG32(DC_HOT_PLUG_DETECT3_INT_CONTROL, tmp); | ||
220 | break; | ||
221 | default: | ||
222 | break; | ||
223 | } | ||
224 | } | ||
225 | } | ||
226 | |||
227 | void r600_hpd_init(struct radeon_device *rdev) | ||
228 | { | ||
229 | struct drm_device *dev = rdev->ddev; | ||
230 | struct drm_connector *connector; | ||
231 | |||
232 | if (ASIC_IS_DCE3(rdev)) { | ||
233 | u32 tmp = DC_HPDx_CONNECTION_TIMER(0x9c4) | DC_HPDx_RX_INT_TIMER(0xfa); | ||
234 | if (ASIC_IS_DCE32(rdev)) | ||
235 | tmp |= DC_HPDx_EN; | ||
236 | |||
237 | list_for_each_entry(connector, &dev->mode_config.connector_list, head) { | ||
238 | struct radeon_connector *radeon_connector = to_radeon_connector(connector); | ||
239 | switch (radeon_connector->hpd.hpd) { | ||
240 | case RADEON_HPD_1: | ||
241 | WREG32(DC_HPD1_CONTROL, tmp); | ||
242 | rdev->irq.hpd[0] = true; | ||
243 | break; | ||
244 | case RADEON_HPD_2: | ||
245 | WREG32(DC_HPD2_CONTROL, tmp); | ||
246 | rdev->irq.hpd[1] = true; | ||
247 | break; | ||
248 | case RADEON_HPD_3: | ||
249 | WREG32(DC_HPD3_CONTROL, tmp); | ||
250 | rdev->irq.hpd[2] = true; | ||
251 | break; | ||
252 | case RADEON_HPD_4: | ||
253 | WREG32(DC_HPD4_CONTROL, tmp); | ||
254 | rdev->irq.hpd[3] = true; | ||
255 | break; | ||
256 | /* DCE 3.2 */ | ||
257 | case RADEON_HPD_5: | ||
258 | WREG32(DC_HPD5_CONTROL, tmp); | ||
259 | rdev->irq.hpd[4] = true; | ||
260 | break; | ||
261 | case RADEON_HPD_6: | ||
262 | WREG32(DC_HPD6_CONTROL, tmp); | ||
263 | rdev->irq.hpd[5] = true; | ||
264 | break; | ||
265 | default: | ||
266 | break; | ||
267 | } | ||
268 | } | ||
269 | } else { | ||
270 | list_for_each_entry(connector, &dev->mode_config.connector_list, head) { | ||
271 | struct radeon_connector *radeon_connector = to_radeon_connector(connector); | ||
272 | switch (radeon_connector->hpd.hpd) { | ||
273 | case RADEON_HPD_1: | ||
274 | WREG32(DC_HOT_PLUG_DETECT1_CONTROL, DC_HOT_PLUG_DETECTx_EN); | ||
275 | rdev->irq.hpd[0] = true; | ||
276 | break; | ||
277 | case RADEON_HPD_2: | ||
278 | WREG32(DC_HOT_PLUG_DETECT2_CONTROL, DC_HOT_PLUG_DETECTx_EN); | ||
279 | rdev->irq.hpd[1] = true; | ||
280 | break; | ||
281 | case RADEON_HPD_3: | ||
282 | WREG32(DC_HOT_PLUG_DETECT3_CONTROL, DC_HOT_PLUG_DETECTx_EN); | ||
283 | rdev->irq.hpd[2] = true; | ||
284 | break; | ||
285 | default: | ||
286 | break; | ||
287 | } | ||
288 | } | ||
289 | } | ||
290 | if (rdev->irq.installed) | ||
291 | r600_irq_set(rdev); | ||
292 | } | ||
293 | |||
294 | void r600_hpd_fini(struct radeon_device *rdev) | ||
295 | { | ||
296 | struct drm_device *dev = rdev->ddev; | ||
297 | struct drm_connector *connector; | ||
298 | |||
299 | if (ASIC_IS_DCE3(rdev)) { | ||
300 | list_for_each_entry(connector, &dev->mode_config.connector_list, head) { | ||
301 | struct radeon_connector *radeon_connector = to_radeon_connector(connector); | ||
302 | switch (radeon_connector->hpd.hpd) { | ||
303 | case RADEON_HPD_1: | ||
304 | WREG32(DC_HPD1_CONTROL, 0); | ||
305 | rdev->irq.hpd[0] = false; | ||
306 | break; | ||
307 | case RADEON_HPD_2: | ||
308 | WREG32(DC_HPD2_CONTROL, 0); | ||
309 | rdev->irq.hpd[1] = false; | ||
310 | break; | ||
311 | case RADEON_HPD_3: | ||
312 | WREG32(DC_HPD3_CONTROL, 0); | ||
313 | rdev->irq.hpd[2] = false; | ||
314 | break; | ||
315 | case RADEON_HPD_4: | ||
316 | WREG32(DC_HPD4_CONTROL, 0); | ||
317 | rdev->irq.hpd[3] = false; | ||
318 | break; | ||
319 | /* DCE 3.2 */ | ||
320 | case RADEON_HPD_5: | ||
321 | WREG32(DC_HPD5_CONTROL, 0); | ||
322 | rdev->irq.hpd[4] = false; | ||
323 | break; | ||
324 | case RADEON_HPD_6: | ||
325 | WREG32(DC_HPD6_CONTROL, 0); | ||
326 | rdev->irq.hpd[5] = false; | ||
327 | break; | ||
328 | default: | ||
329 | break; | ||
330 | } | ||
331 | } | ||
332 | } else { | ||
333 | list_for_each_entry(connector, &dev->mode_config.connector_list, head) { | ||
334 | struct radeon_connector *radeon_connector = to_radeon_connector(connector); | ||
335 | switch (radeon_connector->hpd.hpd) { | ||
336 | case RADEON_HPD_1: | ||
337 | WREG32(DC_HOT_PLUG_DETECT1_CONTROL, 0); | ||
338 | rdev->irq.hpd[0] = false; | ||
339 | break; | ||
340 | case RADEON_HPD_2: | ||
341 | WREG32(DC_HOT_PLUG_DETECT2_CONTROL, 0); | ||
342 | rdev->irq.hpd[1] = false; | ||
343 | break; | ||
344 | case RADEON_HPD_3: | ||
345 | WREG32(DC_HOT_PLUG_DETECT3_CONTROL, 0); | ||
346 | rdev->irq.hpd[2] = false; | ||
347 | break; | ||
348 | default: | ||
349 | break; | ||
350 | } | ||
351 | } | ||
352 | } | ||
86 | } | 353 | } |
87 | 354 | ||
355 | /* | ||
356 | * R600 PCIE GART | ||
357 | */ | ||
88 | void r600_pcie_gart_tlb_flush(struct radeon_device *rdev) | 358 | void r600_pcie_gart_tlb_flush(struct radeon_device *rdev) |
89 | { | 359 | { |
90 | unsigned i; | 360 | unsigned i; |
91 | u32 tmp; | 361 | u32 tmp; |
92 | 362 | ||
363 | /* flush hdp cache so updates hit vram */ | ||
364 | WREG32(R_005480_HDP_MEM_COHERENCY_FLUSH_CNTL, 0x1); | ||
365 | |||
93 | WREG32(VM_CONTEXT0_INVALIDATION_LOW_ADDR, rdev->mc.gtt_start >> 12); | 366 | WREG32(VM_CONTEXT0_INVALIDATION_LOW_ADDR, rdev->mc.gtt_start >> 12); |
94 | WREG32(VM_CONTEXT0_INVALIDATION_HIGH_ADDR, (rdev->mc.gtt_end - 1) >> 12); | 367 | WREG32(VM_CONTEXT0_INVALIDATION_HIGH_ADDR, (rdev->mc.gtt_end - 1) >> 12); |
95 | WREG32(VM_CONTEXT0_REQUEST_RESPONSE, REQUEST_TYPE(1)); | 368 | WREG32(VM_CONTEXT0_REQUEST_RESPONSE, REQUEST_TYPE(1)); |
@@ -136,6 +409,7 @@ int r600_pcie_gart_enable(struct radeon_device *rdev) | |||
136 | r = radeon_gart_table_vram_pin(rdev); | 409 | r = radeon_gart_table_vram_pin(rdev); |
137 | if (r) | 410 | if (r) |
138 | return r; | 411 | return r; |
412 | radeon_gart_restore(rdev); | ||
139 | 413 | ||
140 | /* Setup L2 cache */ | 414 | /* Setup L2 cache */ |
141 | WREG32(VM_L2_CNTL, ENABLE_L2_CACHE | ENABLE_L2_FRAGMENT_PROCESSING | | 415 | WREG32(VM_L2_CNTL, ENABLE_L2_CACHE | ENABLE_L2_FRAGMENT_PROCESSING | |
@@ -180,7 +454,7 @@ int r600_pcie_gart_enable(struct radeon_device *rdev) | |||
180 | void r600_pcie_gart_disable(struct radeon_device *rdev) | 454 | void r600_pcie_gart_disable(struct radeon_device *rdev) |
181 | { | 455 | { |
182 | u32 tmp; | 456 | u32 tmp; |
183 | int i; | 457 | int i, r; |
184 | 458 | ||
185 | /* Disable all tables */ | 459 | /* Disable all tables */ |
186 | for (i = 0; i < 7; i++) | 460 | for (i = 0; i < 7; i++) |
@@ -208,16 +482,20 @@ void r600_pcie_gart_disable(struct radeon_device *rdev) | |||
208 | WREG32(MC_VM_L1_TLB_MCB_RD_HDP_CNTL, tmp); | 482 | WREG32(MC_VM_L1_TLB_MCB_RD_HDP_CNTL, tmp); |
209 | WREG32(MC_VM_L1_TLB_MCB_WR_HDP_CNTL, tmp); | 483 | WREG32(MC_VM_L1_TLB_MCB_WR_HDP_CNTL, tmp); |
210 | if (rdev->gart.table.vram.robj) { | 484 | if (rdev->gart.table.vram.robj) { |
211 | radeon_object_kunmap(rdev->gart.table.vram.robj); | 485 | r = radeon_bo_reserve(rdev->gart.table.vram.robj, false); |
212 | radeon_object_unpin(rdev->gart.table.vram.robj); | 486 | if (likely(r == 0)) { |
487 | radeon_bo_kunmap(rdev->gart.table.vram.robj); | ||
488 | radeon_bo_unpin(rdev->gart.table.vram.robj); | ||
489 | radeon_bo_unreserve(rdev->gart.table.vram.robj); | ||
490 | } | ||
213 | } | 491 | } |
214 | } | 492 | } |
215 | 493 | ||
216 | void r600_pcie_gart_fini(struct radeon_device *rdev) | 494 | void r600_pcie_gart_fini(struct radeon_device *rdev) |
217 | { | 495 | { |
496 | radeon_gart_fini(rdev); | ||
218 | r600_pcie_gart_disable(rdev); | 497 | r600_pcie_gart_disable(rdev); |
219 | radeon_gart_table_vram_free(rdev); | 498 | radeon_gart_table_vram_free(rdev); |
220 | radeon_gart_fini(rdev); | ||
221 | } | 499 | } |
222 | 500 | ||
223 | void r600_agp_enable(struct radeon_device *rdev) | 501 | void r600_agp_enable(struct radeon_device *rdev) |
@@ -335,12 +613,72 @@ static void r600_mc_program(struct radeon_device *rdev) | |||
335 | rv515_vga_render_disable(rdev); | 613 | rv515_vga_render_disable(rdev); |
336 | } | 614 | } |
337 | 615 | ||
616 | /** | ||
617 | * r600_vram_gtt_location - try to find VRAM & GTT location | ||
618 | * @rdev: radeon device structure holding all necessary informations | ||
619 | * @mc: memory controller structure holding memory informations | ||
620 | * | ||
621 | * Function will place try to place VRAM at same place as in CPU (PCI) | ||
622 | * address space as some GPU seems to have issue when we reprogram at | ||
623 | * different address space. | ||
624 | * | ||
625 | * If there is not enough space to fit the unvisible VRAM after the | ||
626 | * aperture then we limit the VRAM size to the aperture. | ||
627 | * | ||
628 | * If we are using AGP then place VRAM adjacent to AGP aperture are we need | ||
629 | * them to be in one from GPU point of view so that we can program GPU to | ||
630 | * catch access outside them (weird GPU policy see ??). | ||
631 | * | ||
632 | * This function will never fails, worst case are limiting VRAM or GTT. | ||
633 | * | ||
634 | * Note: GTT start, end, size should be initialized before calling this | ||
635 | * function on AGP platform. | ||
636 | */ | ||
637 | void r600_vram_gtt_location(struct radeon_device *rdev, struct radeon_mc *mc) | ||
638 | { | ||
639 | u64 size_bf, size_af; | ||
640 | |||
641 | if (mc->mc_vram_size > 0xE0000000) { | ||
642 | /* leave room for at least 512M GTT */ | ||
643 | dev_warn(rdev->dev, "limiting VRAM\n"); | ||
644 | mc->real_vram_size = 0xE0000000; | ||
645 | mc->mc_vram_size = 0xE0000000; | ||
646 | } | ||
647 | if (rdev->flags & RADEON_IS_AGP) { | ||
648 | size_bf = mc->gtt_start; | ||
649 | size_af = 0xFFFFFFFF - mc->gtt_end + 1; | ||
650 | if (size_bf > size_af) { | ||
651 | if (mc->mc_vram_size > size_bf) { | ||
652 | dev_warn(rdev->dev, "limiting VRAM\n"); | ||
653 | mc->real_vram_size = size_bf; | ||
654 | mc->mc_vram_size = size_bf; | ||
655 | } | ||
656 | mc->vram_start = mc->gtt_start - mc->mc_vram_size; | ||
657 | } else { | ||
658 | if (mc->mc_vram_size > size_af) { | ||
659 | dev_warn(rdev->dev, "limiting VRAM\n"); | ||
660 | mc->real_vram_size = size_af; | ||
661 | mc->mc_vram_size = size_af; | ||
662 | } | ||
663 | mc->vram_start = mc->gtt_end; | ||
664 | } | ||
665 | mc->vram_end = mc->vram_start + mc->mc_vram_size - 1; | ||
666 | dev_info(rdev->dev, "VRAM: %lluM 0x%08llX - 0x%08llX (%lluM used)\n", | ||
667 | mc->mc_vram_size >> 20, mc->vram_start, | ||
668 | mc->vram_end, mc->real_vram_size >> 20); | ||
669 | } else { | ||
670 | u64 base = 0; | ||
671 | if (rdev->flags & RADEON_IS_IGP) | ||
672 | base = (RREG32(MC_VM_FB_LOCATION) & 0xFFFF) << 24; | ||
673 | radeon_vram_location(rdev, &rdev->mc, base); | ||
674 | radeon_gtt_location(rdev, mc); | ||
675 | } | ||
676 | } | ||
677 | |||
338 | int r600_mc_init(struct radeon_device *rdev) | 678 | int r600_mc_init(struct radeon_device *rdev) |
339 | { | 679 | { |
340 | fixed20_12 a; | ||
341 | u32 tmp; | 680 | u32 tmp; |
342 | int chansize, numchan; | 681 | int chansize, numchan; |
343 | int r; | ||
344 | 682 | ||
345 | /* Get VRAM informations */ | 683 | /* Get VRAM informations */ |
346 | rdev->mc.vram_is_ddr = true; | 684 | rdev->mc.vram_is_ddr = true; |
@@ -375,74 +713,17 @@ int r600_mc_init(struct radeon_device *rdev) | |||
375 | /* Setup GPU memory space */ | 713 | /* Setup GPU memory space */ |
376 | rdev->mc.mc_vram_size = RREG32(CONFIG_MEMSIZE); | 714 | rdev->mc.mc_vram_size = RREG32(CONFIG_MEMSIZE); |
377 | rdev->mc.real_vram_size = RREG32(CONFIG_MEMSIZE); | 715 | rdev->mc.real_vram_size = RREG32(CONFIG_MEMSIZE); |
378 | 716 | rdev->mc.visible_vram_size = rdev->mc.aper_size; | |
379 | if (rdev->mc.mc_vram_size > rdev->mc.aper_size) | 717 | /* FIXME remove this once we support unmappable VRAM */ |
718 | if (rdev->mc.mc_vram_size > rdev->mc.aper_size) { | ||
380 | rdev->mc.mc_vram_size = rdev->mc.aper_size; | 719 | rdev->mc.mc_vram_size = rdev->mc.aper_size; |
381 | |||
382 | if (rdev->mc.real_vram_size > rdev->mc.aper_size) | ||
383 | rdev->mc.real_vram_size = rdev->mc.aper_size; | 720 | rdev->mc.real_vram_size = rdev->mc.aper_size; |
721 | } | ||
722 | r600_vram_gtt_location(rdev, &rdev->mc); | ||
384 | 723 | ||
385 | if (rdev->flags & RADEON_IS_AGP) { | 724 | if (rdev->flags & RADEON_IS_IGP) |
386 | r = radeon_agp_init(rdev); | 725 | rdev->mc.igp_sideport_enabled = radeon_atombios_sideport_present(rdev); |
387 | if (r) | 726 | radeon_update_bandwidth_info(rdev); |
388 | return r; | ||
389 | /* gtt_size is setup by radeon_agp_init */ | ||
390 | rdev->mc.gtt_location = rdev->mc.agp_base; | ||
391 | tmp = 0xFFFFFFFFUL - rdev->mc.agp_base - rdev->mc.gtt_size; | ||
392 | /* Try to put vram before or after AGP because we | ||
393 | * we want SYSTEM_APERTURE to cover both VRAM and | ||
394 | * AGP so that GPU can catch out of VRAM/AGP access | ||
395 | */ | ||
396 | if (rdev->mc.gtt_location > rdev->mc.mc_vram_size) { | ||
397 | /* Enought place before */ | ||
398 | rdev->mc.vram_location = rdev->mc.gtt_location - | ||
399 | rdev->mc.mc_vram_size; | ||
400 | } else if (tmp > rdev->mc.mc_vram_size) { | ||
401 | /* Enought place after */ | ||
402 | rdev->mc.vram_location = rdev->mc.gtt_location + | ||
403 | rdev->mc.gtt_size; | ||
404 | } else { | ||
405 | /* Try to setup VRAM then AGP might not | ||
406 | * not work on some card | ||
407 | */ | ||
408 | rdev->mc.vram_location = 0x00000000UL; | ||
409 | rdev->mc.gtt_location = rdev->mc.mc_vram_size; | ||
410 | } | ||
411 | } else { | ||
412 | rdev->mc.gtt_size = radeon_gart_size * 1024 * 1024; | ||
413 | rdev->mc.vram_location = (RREG32(MC_VM_FB_LOCATION) & | ||
414 | 0xFFFF) << 24; | ||
415 | tmp = rdev->mc.vram_location + rdev->mc.mc_vram_size; | ||
416 | if ((0xFFFFFFFFUL - tmp) >= rdev->mc.gtt_size) { | ||
417 | /* Enough place after vram */ | ||
418 | rdev->mc.gtt_location = tmp; | ||
419 | } else if (rdev->mc.vram_location >= rdev->mc.gtt_size) { | ||
420 | /* Enough place before vram */ | ||
421 | rdev->mc.gtt_location = 0; | ||
422 | } else { | ||
423 | /* Not enough place after or before shrink | ||
424 | * gart size | ||
425 | */ | ||
426 | if (rdev->mc.vram_location > (0xFFFFFFFFUL - tmp)) { | ||
427 | rdev->mc.gtt_location = 0; | ||
428 | rdev->mc.gtt_size = rdev->mc.vram_location; | ||
429 | } else { | ||
430 | rdev->mc.gtt_location = tmp; | ||
431 | rdev->mc.gtt_size = 0xFFFFFFFFUL - tmp; | ||
432 | } | ||
433 | } | ||
434 | rdev->mc.gtt_location = rdev->mc.mc_vram_size; | ||
435 | } | ||
436 | rdev->mc.vram_start = rdev->mc.vram_location; | ||
437 | rdev->mc.vram_end = rdev->mc.vram_location + rdev->mc.mc_vram_size - 1; | ||
438 | rdev->mc.gtt_start = rdev->mc.gtt_location; | ||
439 | rdev->mc.gtt_end = rdev->mc.gtt_location + rdev->mc.gtt_size - 1; | ||
440 | /* FIXME: we should enforce default clock in case GPU is not in | ||
441 | * default setup | ||
442 | */ | ||
443 | a.full = rfixed_const(100); | ||
444 | rdev->pm.sclk.full = rfixed_const(rdev->clock.default_sclk); | ||
445 | rdev->pm.sclk.full = rfixed_div(rdev->pm.sclk, a); | ||
446 | return 0; | 727 | return 0; |
447 | } | 728 | } |
448 | 729 | ||
@@ -697,6 +978,9 @@ void r600_gpu_init(struct radeon_device *rdev) | |||
697 | { | 978 | { |
698 | u32 tiling_config; | 979 | u32 tiling_config; |
699 | u32 ramcfg; | 980 | u32 ramcfg; |
981 | u32 backend_map; | ||
982 | u32 cc_rb_backend_disable; | ||
983 | u32 cc_gc_shader_pipe_config; | ||
700 | u32 tmp; | 984 | u32 tmp; |
701 | int i, j; | 985 | int i, j; |
702 | u32 sq_config; | 986 | u32 sq_config; |
@@ -806,8 +1090,11 @@ void r600_gpu_init(struct radeon_device *rdev) | |||
806 | default: | 1090 | default: |
807 | break; | 1091 | break; |
808 | } | 1092 | } |
1093 | rdev->config.r600.tiling_npipes = rdev->config.r600.max_tile_pipes; | ||
1094 | rdev->config.r600.tiling_nbanks = 4 << ((ramcfg & NOOFBANK_MASK) >> NOOFBANK_SHIFT); | ||
809 | tiling_config |= BANK_TILING((ramcfg & NOOFBANK_MASK) >> NOOFBANK_SHIFT); | 1095 | tiling_config |= BANK_TILING((ramcfg & NOOFBANK_MASK) >> NOOFBANK_SHIFT); |
810 | tiling_config |= GROUP_SIZE(0); | 1096 | tiling_config |= GROUP_SIZE(0); |
1097 | rdev->config.r600.tiling_group_size = 256; | ||
811 | tmp = (ramcfg & NOOFROWS_MASK) >> NOOFROWS_SHIFT; | 1098 | tmp = (ramcfg & NOOFROWS_MASK) >> NOOFROWS_SHIFT; |
812 | if (tmp > 3) { | 1099 | if (tmp > 3) { |
813 | tiling_config |= ROW_TILING(3); | 1100 | tiling_config |= ROW_TILING(3); |
@@ -817,24 +1104,34 @@ void r600_gpu_init(struct radeon_device *rdev) | |||
817 | tiling_config |= SAMPLE_SPLIT(tmp); | 1104 | tiling_config |= SAMPLE_SPLIT(tmp); |
818 | } | 1105 | } |
819 | tiling_config |= BANK_SWAPS(1); | 1106 | tiling_config |= BANK_SWAPS(1); |
820 | tmp = r600_get_tile_pipe_to_backend_map(rdev->config.r600.max_tile_pipes, | 1107 | |
821 | rdev->config.r600.max_backends, | 1108 | cc_rb_backend_disable = RREG32(CC_RB_BACKEND_DISABLE) & 0x00ff0000; |
822 | (0xff << rdev->config.r600.max_backends) & 0xff); | 1109 | cc_rb_backend_disable |= |
823 | tiling_config |= BACKEND_MAP(tmp); | 1110 | BACKEND_DISABLE((R6XX_MAX_BACKENDS_MASK << rdev->config.r600.max_backends) & R6XX_MAX_BACKENDS_MASK); |
1111 | |||
1112 | cc_gc_shader_pipe_config = RREG32(CC_GC_SHADER_PIPE_CONFIG) & 0xffffff00; | ||
1113 | cc_gc_shader_pipe_config |= | ||
1114 | INACTIVE_QD_PIPES((R6XX_MAX_PIPES_MASK << rdev->config.r600.max_pipes) & R6XX_MAX_PIPES_MASK); | ||
1115 | cc_gc_shader_pipe_config |= | ||
1116 | INACTIVE_SIMDS((R6XX_MAX_SIMDS_MASK << rdev->config.r600.max_simds) & R6XX_MAX_SIMDS_MASK); | ||
1117 | |||
1118 | backend_map = r600_get_tile_pipe_to_backend_map(rdev->config.r600.max_tile_pipes, | ||
1119 | (R6XX_MAX_BACKENDS - | ||
1120 | r600_count_pipe_bits((cc_rb_backend_disable & | ||
1121 | R6XX_MAX_BACKENDS_MASK) >> 16)), | ||
1122 | (cc_rb_backend_disable >> 16)); | ||
1123 | |||
1124 | tiling_config |= BACKEND_MAP(backend_map); | ||
824 | WREG32(GB_TILING_CONFIG, tiling_config); | 1125 | WREG32(GB_TILING_CONFIG, tiling_config); |
825 | WREG32(DCP_TILING_CONFIG, tiling_config & 0xffff); | 1126 | WREG32(DCP_TILING_CONFIG, tiling_config & 0xffff); |
826 | WREG32(HDP_TILING_CONFIG, tiling_config & 0xffff); | 1127 | WREG32(HDP_TILING_CONFIG, tiling_config & 0xffff); |
827 | 1128 | ||
828 | tmp = BACKEND_DISABLE((R6XX_MAX_BACKENDS_MASK << rdev->config.r600.max_backends) & R6XX_MAX_BACKENDS_MASK); | ||
829 | WREG32(CC_RB_BACKEND_DISABLE, tmp); | ||
830 | |||
831 | /* Setup pipes */ | 1129 | /* Setup pipes */ |
832 | tmp = INACTIVE_QD_PIPES((R6XX_MAX_PIPES_MASK << rdev->config.r600.max_pipes) & R6XX_MAX_PIPES_MASK); | 1130 | WREG32(CC_RB_BACKEND_DISABLE, cc_rb_backend_disable); |
833 | tmp |= INACTIVE_SIMDS((R6XX_MAX_SIMDS_MASK << rdev->config.r600.max_simds) & R6XX_MAX_SIMDS_MASK); | 1131 | WREG32(CC_GC_SHADER_PIPE_CONFIG, cc_gc_shader_pipe_config); |
834 | WREG32(CC_GC_SHADER_PIPE_CONFIG, tmp); | 1132 | WREG32(GC_USER_SHADER_PIPE_CONFIG, cc_gc_shader_pipe_config); |
835 | WREG32(GC_USER_SHADER_PIPE_CONFIG, tmp); | ||
836 | 1133 | ||
837 | tmp = R6XX_MAX_BACKENDS - r600_count_pipe_bits(tmp & INACTIVE_QD_PIPES_MASK); | 1134 | tmp = R6XX_MAX_PIPES - r600_count_pipe_bits((cc_gc_shader_pipe_config & INACTIVE_QD_PIPES_MASK) >> 8); |
838 | WREG32(VGT_OUT_DEALLOC_CNTL, (tmp * 4) & DEALLOC_DIST_MASK); | 1135 | WREG32(VGT_OUT_DEALLOC_CNTL, (tmp * 4) & DEALLOC_DIST_MASK); |
839 | WREG32(VGT_VERTEX_REUSE_BLOCK_CNTL, ((tmp * 4) - 2) & VTX_REUSE_DEPTH_MASK); | 1136 | WREG32(VGT_VERTEX_REUSE_BLOCK_CNTL, ((tmp * 4) - 2) & VTX_REUSE_DEPTH_MASK); |
840 | 1137 | ||
@@ -1101,7 +1398,6 @@ void r600_pciep_wreg(struct radeon_device *rdev, u32 reg, u32 v) | |||
1101 | (void)RREG32(PCIE_PORT_DATA); | 1398 | (void)RREG32(PCIE_PORT_DATA); |
1102 | } | 1399 | } |
1103 | 1400 | ||
1104 | |||
1105 | /* | 1401 | /* |
1106 | * CP & Ring | 1402 | * CP & Ring |
1107 | */ | 1403 | */ |
@@ -1110,11 +1406,12 @@ void r600_cp_stop(struct radeon_device *rdev) | |||
1110 | WREG32(R_0086D8_CP_ME_CNTL, S_0086D8_CP_ME_HALT(1)); | 1406 | WREG32(R_0086D8_CP_ME_CNTL, S_0086D8_CP_ME_HALT(1)); |
1111 | } | 1407 | } |
1112 | 1408 | ||
1113 | int r600_cp_init_microcode(struct radeon_device *rdev) | 1409 | int r600_init_microcode(struct radeon_device *rdev) |
1114 | { | 1410 | { |
1115 | struct platform_device *pdev; | 1411 | struct platform_device *pdev; |
1116 | const char *chip_name; | 1412 | const char *chip_name; |
1117 | size_t pfp_req_size, me_req_size; | 1413 | const char *rlc_chip_name; |
1414 | size_t pfp_req_size, me_req_size, rlc_req_size; | ||
1118 | char fw_name[30]; | 1415 | char fw_name[30]; |
1119 | int err; | 1416 | int err; |
1120 | 1417 | ||
@@ -1128,30 +1425,62 @@ int r600_cp_init_microcode(struct radeon_device *rdev) | |||
1128 | } | 1425 | } |
1129 | 1426 | ||
1130 | switch (rdev->family) { | 1427 | switch (rdev->family) { |
1131 | case CHIP_R600: chip_name = "R600"; break; | 1428 | case CHIP_R600: |
1132 | case CHIP_RV610: chip_name = "RV610"; break; | 1429 | chip_name = "R600"; |
1133 | case CHIP_RV630: chip_name = "RV630"; break; | 1430 | rlc_chip_name = "R600"; |
1134 | case CHIP_RV620: chip_name = "RV620"; break; | 1431 | break; |
1135 | case CHIP_RV635: chip_name = "RV635"; break; | 1432 | case CHIP_RV610: |
1136 | case CHIP_RV670: chip_name = "RV670"; break; | 1433 | chip_name = "RV610"; |
1434 | rlc_chip_name = "R600"; | ||
1435 | break; | ||
1436 | case CHIP_RV630: | ||
1437 | chip_name = "RV630"; | ||
1438 | rlc_chip_name = "R600"; | ||
1439 | break; | ||
1440 | case CHIP_RV620: | ||
1441 | chip_name = "RV620"; | ||
1442 | rlc_chip_name = "R600"; | ||
1443 | break; | ||
1444 | case CHIP_RV635: | ||
1445 | chip_name = "RV635"; | ||
1446 | rlc_chip_name = "R600"; | ||
1447 | break; | ||
1448 | case CHIP_RV670: | ||
1449 | chip_name = "RV670"; | ||
1450 | rlc_chip_name = "R600"; | ||
1451 | break; | ||
1137 | case CHIP_RS780: | 1452 | case CHIP_RS780: |
1138 | case CHIP_RS880: chip_name = "RS780"; break; | 1453 | case CHIP_RS880: |
1139 | case CHIP_RV770: chip_name = "RV770"; break; | 1454 | chip_name = "RS780"; |
1455 | rlc_chip_name = "R600"; | ||
1456 | break; | ||
1457 | case CHIP_RV770: | ||
1458 | chip_name = "RV770"; | ||
1459 | rlc_chip_name = "R700"; | ||
1460 | break; | ||
1140 | case CHIP_RV730: | 1461 | case CHIP_RV730: |
1141 | case CHIP_RV740: chip_name = "RV730"; break; | 1462 | case CHIP_RV740: |
1142 | case CHIP_RV710: chip_name = "RV710"; break; | 1463 | chip_name = "RV730"; |
1464 | rlc_chip_name = "R700"; | ||
1465 | break; | ||
1466 | case CHIP_RV710: | ||
1467 | chip_name = "RV710"; | ||
1468 | rlc_chip_name = "R700"; | ||
1469 | break; | ||
1143 | default: BUG(); | 1470 | default: BUG(); |
1144 | } | 1471 | } |
1145 | 1472 | ||
1146 | if (rdev->family >= CHIP_RV770) { | 1473 | if (rdev->family >= CHIP_RV770) { |
1147 | pfp_req_size = R700_PFP_UCODE_SIZE * 4; | 1474 | pfp_req_size = R700_PFP_UCODE_SIZE * 4; |
1148 | me_req_size = R700_PM4_UCODE_SIZE * 4; | 1475 | me_req_size = R700_PM4_UCODE_SIZE * 4; |
1476 | rlc_req_size = R700_RLC_UCODE_SIZE * 4; | ||
1149 | } else { | 1477 | } else { |
1150 | pfp_req_size = PFP_UCODE_SIZE * 4; | 1478 | pfp_req_size = PFP_UCODE_SIZE * 4; |
1151 | me_req_size = PM4_UCODE_SIZE * 12; | 1479 | me_req_size = PM4_UCODE_SIZE * 12; |
1480 | rlc_req_size = RLC_UCODE_SIZE * 4; | ||
1152 | } | 1481 | } |
1153 | 1482 | ||
1154 | DRM_INFO("Loading %s CP Microcode\n", chip_name); | 1483 | DRM_INFO("Loading %s Microcode\n", chip_name); |
1155 | 1484 | ||
1156 | snprintf(fw_name, sizeof(fw_name), "radeon/%s_pfp.bin", chip_name); | 1485 | snprintf(fw_name, sizeof(fw_name), "radeon/%s_pfp.bin", chip_name); |
1157 | err = request_firmware(&rdev->pfp_fw, fw_name, &pdev->dev); | 1486 | err = request_firmware(&rdev->pfp_fw, fw_name, &pdev->dev); |
@@ -1175,6 +1504,18 @@ int r600_cp_init_microcode(struct radeon_device *rdev) | |||
1175 | rdev->me_fw->size, fw_name); | 1504 | rdev->me_fw->size, fw_name); |
1176 | err = -EINVAL; | 1505 | err = -EINVAL; |
1177 | } | 1506 | } |
1507 | |||
1508 | snprintf(fw_name, sizeof(fw_name), "radeon/%s_rlc.bin", rlc_chip_name); | ||
1509 | err = request_firmware(&rdev->rlc_fw, fw_name, &pdev->dev); | ||
1510 | if (err) | ||
1511 | goto out; | ||
1512 | if (rdev->rlc_fw->size != rlc_req_size) { | ||
1513 | printk(KERN_ERR | ||
1514 | "r600_rlc: Bogus length %zu in firmware \"%s\"\n", | ||
1515 | rdev->rlc_fw->size, fw_name); | ||
1516 | err = -EINVAL; | ||
1517 | } | ||
1518 | |||
1178 | out: | 1519 | out: |
1179 | platform_device_unregister(pdev); | 1520 | platform_device_unregister(pdev); |
1180 | 1521 | ||
@@ -1187,6 +1528,8 @@ out: | |||
1187 | rdev->pfp_fw = NULL; | 1528 | rdev->pfp_fw = NULL; |
1188 | release_firmware(rdev->me_fw); | 1529 | release_firmware(rdev->me_fw); |
1189 | rdev->me_fw = NULL; | 1530 | rdev->me_fw = NULL; |
1531 | release_firmware(rdev->rlc_fw); | ||
1532 | rdev->rlc_fw = NULL; | ||
1190 | } | 1533 | } |
1191 | return err; | 1534 | return err; |
1192 | } | 1535 | } |
@@ -1324,6 +1667,12 @@ void r600_ring_init(struct radeon_device *rdev, unsigned ring_size) | |||
1324 | rdev->cp.align_mask = 16 - 1; | 1667 | rdev->cp.align_mask = 16 - 1; |
1325 | } | 1668 | } |
1326 | 1669 | ||
1670 | void r600_cp_fini(struct radeon_device *rdev) | ||
1671 | { | ||
1672 | r600_cp_stop(rdev); | ||
1673 | radeon_ring_fini(rdev); | ||
1674 | } | ||
1675 | |||
1327 | 1676 | ||
1328 | /* | 1677 | /* |
1329 | * GPU scratch registers helpers function. | 1678 | * GPU scratch registers helpers function. |
@@ -1381,10 +1730,16 @@ int r600_ring_test(struct radeon_device *rdev) | |||
1381 | 1730 | ||
1382 | void r600_wb_disable(struct radeon_device *rdev) | 1731 | void r600_wb_disable(struct radeon_device *rdev) |
1383 | { | 1732 | { |
1733 | int r; | ||
1734 | |||
1384 | WREG32(SCRATCH_UMSK, 0); | 1735 | WREG32(SCRATCH_UMSK, 0); |
1385 | if (rdev->wb.wb_obj) { | 1736 | if (rdev->wb.wb_obj) { |
1386 | radeon_object_kunmap(rdev->wb.wb_obj); | 1737 | r = radeon_bo_reserve(rdev->wb.wb_obj, false); |
1387 | radeon_object_unpin(rdev->wb.wb_obj); | 1738 | if (unlikely(r != 0)) |
1739 | return; | ||
1740 | radeon_bo_kunmap(rdev->wb.wb_obj); | ||
1741 | radeon_bo_unpin(rdev->wb.wb_obj); | ||
1742 | radeon_bo_unreserve(rdev->wb.wb_obj); | ||
1388 | } | 1743 | } |
1389 | } | 1744 | } |
1390 | 1745 | ||
@@ -1392,7 +1747,7 @@ void r600_wb_fini(struct radeon_device *rdev) | |||
1392 | { | 1747 | { |
1393 | r600_wb_disable(rdev); | 1748 | r600_wb_disable(rdev); |
1394 | if (rdev->wb.wb_obj) { | 1749 | if (rdev->wb.wb_obj) { |
1395 | radeon_object_unref(&rdev->wb.wb_obj); | 1750 | radeon_bo_unref(&rdev->wb.wb_obj); |
1396 | rdev->wb.wb = NULL; | 1751 | rdev->wb.wb = NULL; |
1397 | rdev->wb.wb_obj = NULL; | 1752 | rdev->wb.wb_obj = NULL; |
1398 | } | 1753 | } |
@@ -1403,22 +1758,29 @@ int r600_wb_enable(struct radeon_device *rdev) | |||
1403 | int r; | 1758 | int r; |
1404 | 1759 | ||
1405 | if (rdev->wb.wb_obj == NULL) { | 1760 | if (rdev->wb.wb_obj == NULL) { |
1406 | r = radeon_object_create(rdev, NULL, RADEON_GPU_PAGE_SIZE, true, | 1761 | r = radeon_bo_create(rdev, NULL, RADEON_GPU_PAGE_SIZE, true, |
1407 | RADEON_GEM_DOMAIN_GTT, false, &rdev->wb.wb_obj); | 1762 | RADEON_GEM_DOMAIN_GTT, &rdev->wb.wb_obj); |
1408 | if (r) { | 1763 | if (r) { |
1409 | dev_warn(rdev->dev, "failed to create WB buffer (%d).\n", r); | 1764 | dev_warn(rdev->dev, "(%d) create WB bo failed\n", r); |
1410 | return r; | 1765 | return r; |
1411 | } | 1766 | } |
1412 | r = radeon_object_pin(rdev->wb.wb_obj, RADEON_GEM_DOMAIN_GTT, | 1767 | r = radeon_bo_reserve(rdev->wb.wb_obj, false); |
1768 | if (unlikely(r != 0)) { | ||
1769 | r600_wb_fini(rdev); | ||
1770 | return r; | ||
1771 | } | ||
1772 | r = radeon_bo_pin(rdev->wb.wb_obj, RADEON_GEM_DOMAIN_GTT, | ||
1413 | &rdev->wb.gpu_addr); | 1773 | &rdev->wb.gpu_addr); |
1414 | if (r) { | 1774 | if (r) { |
1415 | dev_warn(rdev->dev, "failed to pin WB buffer (%d).\n", r); | 1775 | radeon_bo_unreserve(rdev->wb.wb_obj); |
1776 | dev_warn(rdev->dev, "(%d) pin WB bo failed\n", r); | ||
1416 | r600_wb_fini(rdev); | 1777 | r600_wb_fini(rdev); |
1417 | return r; | 1778 | return r; |
1418 | } | 1779 | } |
1419 | r = radeon_object_kmap(rdev->wb.wb_obj, (void **)&rdev->wb.wb); | 1780 | r = radeon_bo_kmap(rdev->wb.wb_obj, (void **)&rdev->wb.wb); |
1781 | radeon_bo_unreserve(rdev->wb.wb_obj); | ||
1420 | if (r) { | 1782 | if (r) { |
1421 | dev_warn(rdev->dev, "failed to map WB buffer (%d).\n", r); | 1783 | dev_warn(rdev->dev, "(%d) map WB bo failed\n", r); |
1422 | r600_wb_fini(rdev); | 1784 | r600_wb_fini(rdev); |
1423 | return r; | 1785 | return r; |
1424 | } | 1786 | } |
@@ -1433,41 +1795,41 @@ int r600_wb_enable(struct radeon_device *rdev) | |||
1433 | void r600_fence_ring_emit(struct radeon_device *rdev, | 1795 | void r600_fence_ring_emit(struct radeon_device *rdev, |
1434 | struct radeon_fence *fence) | 1796 | struct radeon_fence *fence) |
1435 | { | 1797 | { |
1798 | /* Also consider EVENT_WRITE_EOP. it handles the interrupts + timestamps + events */ | ||
1799 | |||
1800 | radeon_ring_write(rdev, PACKET3(PACKET3_EVENT_WRITE, 0)); | ||
1801 | radeon_ring_write(rdev, CACHE_FLUSH_AND_INV_EVENT); | ||
1802 | /* wait for 3D idle clean */ | ||
1803 | radeon_ring_write(rdev, PACKET3(PACKET3_SET_CONFIG_REG, 1)); | ||
1804 | radeon_ring_write(rdev, (WAIT_UNTIL - PACKET3_SET_CONFIG_REG_OFFSET) >> 2); | ||
1805 | radeon_ring_write(rdev, WAIT_3D_IDLE_bit | WAIT_3D_IDLECLEAN_bit); | ||
1436 | /* Emit fence sequence & fire IRQ */ | 1806 | /* Emit fence sequence & fire IRQ */ |
1437 | radeon_ring_write(rdev, PACKET3(PACKET3_SET_CONFIG_REG, 1)); | 1807 | radeon_ring_write(rdev, PACKET3(PACKET3_SET_CONFIG_REG, 1)); |
1438 | radeon_ring_write(rdev, ((rdev->fence_drv.scratch_reg - PACKET3_SET_CONFIG_REG_OFFSET) >> 2)); | 1808 | radeon_ring_write(rdev, ((rdev->fence_drv.scratch_reg - PACKET3_SET_CONFIG_REG_OFFSET) >> 2)); |
1439 | radeon_ring_write(rdev, fence->seq); | 1809 | radeon_ring_write(rdev, fence->seq); |
1440 | } | 1810 | /* CP_INTERRUPT packet 3 no longer exists, use packet 0 */ |
1441 | 1811 | radeon_ring_write(rdev, PACKET0(CP_INT_STATUS, 0)); | |
1442 | int r600_copy_dma(struct radeon_device *rdev, | 1812 | radeon_ring_write(rdev, RB_INT_STAT); |
1443 | uint64_t src_offset, | ||
1444 | uint64_t dst_offset, | ||
1445 | unsigned num_pages, | ||
1446 | struct radeon_fence *fence) | ||
1447 | { | ||
1448 | /* FIXME: implement */ | ||
1449 | return 0; | ||
1450 | } | 1813 | } |
1451 | 1814 | ||
1452 | int r600_copy_blit(struct radeon_device *rdev, | 1815 | int r600_copy_blit(struct radeon_device *rdev, |
1453 | uint64_t src_offset, uint64_t dst_offset, | 1816 | uint64_t src_offset, uint64_t dst_offset, |
1454 | unsigned num_pages, struct radeon_fence *fence) | 1817 | unsigned num_pages, struct radeon_fence *fence) |
1455 | { | 1818 | { |
1456 | r600_blit_prepare_copy(rdev, num_pages * RADEON_GPU_PAGE_SIZE); | 1819 | int r; |
1820 | |||
1821 | mutex_lock(&rdev->r600_blit.mutex); | ||
1822 | rdev->r600_blit.vb_ib = NULL; | ||
1823 | r = r600_blit_prepare_copy(rdev, num_pages * RADEON_GPU_PAGE_SIZE); | ||
1824 | if (r) { | ||
1825 | if (rdev->r600_blit.vb_ib) | ||
1826 | radeon_ib_free(rdev, &rdev->r600_blit.vb_ib); | ||
1827 | mutex_unlock(&rdev->r600_blit.mutex); | ||
1828 | return r; | ||
1829 | } | ||
1457 | r600_kms_blit_copy(rdev, src_offset, dst_offset, num_pages * RADEON_GPU_PAGE_SIZE); | 1830 | r600_kms_blit_copy(rdev, src_offset, dst_offset, num_pages * RADEON_GPU_PAGE_SIZE); |
1458 | r600_blit_done_copy(rdev, fence); | 1831 | r600_blit_done_copy(rdev, fence); |
1459 | return 0; | 1832 | mutex_unlock(&rdev->r600_blit.mutex); |
1460 | } | ||
1461 | |||
1462 | int r600_irq_process(struct radeon_device *rdev) | ||
1463 | { | ||
1464 | /* FIXME: implement */ | ||
1465 | return 0; | ||
1466 | } | ||
1467 | |||
1468 | int r600_irq_set(struct radeon_device *rdev) | ||
1469 | { | ||
1470 | /* FIXME: implement */ | ||
1471 | return 0; | 1833 | return 0; |
1472 | } | 1834 | } |
1473 | 1835 | ||
@@ -1506,6 +1868,14 @@ int r600_startup(struct radeon_device *rdev) | |||
1506 | { | 1868 | { |
1507 | int r; | 1869 | int r; |
1508 | 1870 | ||
1871 | if (!rdev->me_fw || !rdev->pfp_fw || !rdev->rlc_fw) { | ||
1872 | r = r600_init_microcode(rdev); | ||
1873 | if (r) { | ||
1874 | DRM_ERROR("Failed to load firmware!\n"); | ||
1875 | return r; | ||
1876 | } | ||
1877 | } | ||
1878 | |||
1509 | r600_mc_program(rdev); | 1879 | r600_mc_program(rdev); |
1510 | if (rdev->flags & RADEON_IS_AGP) { | 1880 | if (rdev->flags & RADEON_IS_AGP) { |
1511 | r600_agp_enable(rdev); | 1881 | r600_agp_enable(rdev); |
@@ -1515,13 +1885,33 @@ int r600_startup(struct radeon_device *rdev) | |||
1515 | return r; | 1885 | return r; |
1516 | } | 1886 | } |
1517 | r600_gpu_init(rdev); | 1887 | r600_gpu_init(rdev); |
1518 | 1888 | r = r600_blit_init(rdev); | |
1519 | r = radeon_object_pin(rdev->r600_blit.shader_obj, RADEON_GEM_DOMAIN_VRAM, | ||
1520 | &rdev->r600_blit.shader_gpu_addr); | ||
1521 | if (r) { | 1889 | if (r) { |
1522 | DRM_ERROR("failed to pin blit object %d\n", r); | 1890 | r600_blit_fini(rdev); |
1891 | rdev->asic->copy = NULL; | ||
1892 | dev_warn(rdev->dev, "failed blitter (%d) falling back to memcpy\n", r); | ||
1893 | } | ||
1894 | /* pin copy shader into vram */ | ||
1895 | if (rdev->r600_blit.shader_obj) { | ||
1896 | r = radeon_bo_reserve(rdev->r600_blit.shader_obj, false); | ||
1897 | if (unlikely(r != 0)) | ||
1898 | return r; | ||
1899 | r = radeon_bo_pin(rdev->r600_blit.shader_obj, RADEON_GEM_DOMAIN_VRAM, | ||
1900 | &rdev->r600_blit.shader_gpu_addr); | ||
1901 | radeon_bo_unreserve(rdev->r600_blit.shader_obj); | ||
1902 | if (r) { | ||
1903 | dev_err(rdev->dev, "(%d) pin blit object failed\n", r); | ||
1904 | return r; | ||
1905 | } | ||
1906 | } | ||
1907 | /* Enable IRQ */ | ||
1908 | r = r600_irq_init(rdev); | ||
1909 | if (r) { | ||
1910 | DRM_ERROR("radeon: IH init failed (%d).\n", r); | ||
1911 | radeon_irq_kms_fini(rdev); | ||
1523 | return r; | 1912 | return r; |
1524 | } | 1913 | } |
1914 | r600_irq_set(rdev); | ||
1525 | 1915 | ||
1526 | r = radeon_ring_init(rdev, rdev->cp.ring_size); | 1916 | r = radeon_ring_init(rdev, rdev->cp.ring_size); |
1527 | if (r) | 1917 | if (r) |
@@ -1578,18 +1968,35 @@ int r600_resume(struct radeon_device *rdev) | |||
1578 | DRM_ERROR("radeon: failled testing IB (%d).\n", r); | 1968 | DRM_ERROR("radeon: failled testing IB (%d).\n", r); |
1579 | return r; | 1969 | return r; |
1580 | } | 1970 | } |
1971 | |||
1972 | r = r600_audio_init(rdev); | ||
1973 | if (r) { | ||
1974 | DRM_ERROR("radeon: audio resume failed\n"); | ||
1975 | return r; | ||
1976 | } | ||
1977 | |||
1581 | return r; | 1978 | return r; |
1582 | } | 1979 | } |
1583 | 1980 | ||
1584 | int r600_suspend(struct radeon_device *rdev) | 1981 | int r600_suspend(struct radeon_device *rdev) |
1585 | { | 1982 | { |
1983 | int r; | ||
1984 | |||
1985 | r600_audio_fini(rdev); | ||
1586 | /* FIXME: we should wait for ring to be empty */ | 1986 | /* FIXME: we should wait for ring to be empty */ |
1587 | r600_cp_stop(rdev); | 1987 | r600_cp_stop(rdev); |
1588 | rdev->cp.ready = false; | 1988 | rdev->cp.ready = false; |
1989 | r600_irq_suspend(rdev); | ||
1589 | r600_wb_disable(rdev); | 1990 | r600_wb_disable(rdev); |
1590 | r600_pcie_gart_disable(rdev); | 1991 | r600_pcie_gart_disable(rdev); |
1591 | /* unpin shaders bo */ | 1992 | /* unpin shaders bo */ |
1592 | radeon_object_unpin(rdev->r600_blit.shader_obj); | 1993 | if (rdev->r600_blit.shader_obj) { |
1994 | r = radeon_bo_reserve(rdev->r600_blit.shader_obj, false); | ||
1995 | if (!r) { | ||
1996 | radeon_bo_unpin(rdev->r600_blit.shader_obj); | ||
1997 | radeon_bo_unreserve(rdev->r600_blit.shader_obj); | ||
1998 | } | ||
1999 | } | ||
1593 | return 0; | 2000 | return 0; |
1594 | } | 2001 | } |
1595 | 2002 | ||
@@ -1627,7 +2034,11 @@ int r600_init(struct radeon_device *rdev) | |||
1627 | if (r) | 2034 | if (r) |
1628 | return r; | 2035 | return r; |
1629 | /* Post card if necessary */ | 2036 | /* Post card if necessary */ |
1630 | if (!r600_card_posted(rdev) && rdev->bios) { | 2037 | if (!r600_card_posted(rdev)) { |
2038 | if (!rdev->bios) { | ||
2039 | dev_err(rdev->dev, "Card not posted and no BIOS - ignoring\n"); | ||
2040 | return -EINVAL; | ||
2041 | } | ||
1631 | DRM_INFO("GPU not posted. posting now...\n"); | 2042 | DRM_INFO("GPU not posted. posting now...\n"); |
1632 | atom_asic_init(rdev->mode_info.atom_context); | 2043 | atom_asic_init(rdev->mode_info.atom_context); |
1633 | } | 2044 | } |
@@ -1646,73 +2057,79 @@ int r600_init(struct radeon_device *rdev) | |||
1646 | r = radeon_fence_driver_init(rdev); | 2057 | r = radeon_fence_driver_init(rdev); |
1647 | if (r) | 2058 | if (r) |
1648 | return r; | 2059 | return r; |
2060 | if (rdev->flags & RADEON_IS_AGP) { | ||
2061 | r = radeon_agp_init(rdev); | ||
2062 | if (r) | ||
2063 | radeon_agp_disable(rdev); | ||
2064 | } | ||
1649 | r = r600_mc_init(rdev); | 2065 | r = r600_mc_init(rdev); |
1650 | if (r) | 2066 | if (r) |
1651 | return r; | 2067 | return r; |
1652 | /* Memory manager */ | 2068 | /* Memory manager */ |
1653 | r = radeon_object_init(rdev); | 2069 | r = radeon_bo_init(rdev); |
2070 | if (r) | ||
2071 | return r; | ||
2072 | |||
2073 | r = radeon_irq_kms_init(rdev); | ||
1654 | if (r) | 2074 | if (r) |
1655 | return r; | 2075 | return r; |
2076 | |||
1656 | rdev->cp.ring_obj = NULL; | 2077 | rdev->cp.ring_obj = NULL; |
1657 | r600_ring_init(rdev, 1024 * 1024); | 2078 | r600_ring_init(rdev, 1024 * 1024); |
1658 | 2079 | ||
1659 | if (!rdev->me_fw || !rdev->pfp_fw) { | 2080 | rdev->ih.ring_obj = NULL; |
1660 | r = r600_cp_init_microcode(rdev); | 2081 | r600_ih_ring_init(rdev, 64 * 1024); |
1661 | if (r) { | ||
1662 | DRM_ERROR("Failed to load firmware!\n"); | ||
1663 | return r; | ||
1664 | } | ||
1665 | } | ||
1666 | 2082 | ||
1667 | r = r600_pcie_gart_init(rdev); | 2083 | r = r600_pcie_gart_init(rdev); |
1668 | if (r) | 2084 | if (r) |
1669 | return r; | 2085 | return r; |
1670 | 2086 | ||
1671 | rdev->accel_working = true; | 2087 | rdev->accel_working = true; |
1672 | r = r600_blit_init(rdev); | ||
1673 | if (r) { | ||
1674 | DRM_ERROR("radeon: failled blitter (%d).\n", r); | ||
1675 | return r; | ||
1676 | } | ||
1677 | |||
1678 | r = r600_startup(rdev); | 2088 | r = r600_startup(rdev); |
1679 | if (r) { | 2089 | if (r) { |
1680 | r600_suspend(rdev); | 2090 | dev_err(rdev->dev, "disabling GPU acceleration\n"); |
2091 | r600_cp_fini(rdev); | ||
1681 | r600_wb_fini(rdev); | 2092 | r600_wb_fini(rdev); |
1682 | radeon_ring_fini(rdev); | 2093 | r600_irq_fini(rdev); |
2094 | radeon_irq_kms_fini(rdev); | ||
1683 | r600_pcie_gart_fini(rdev); | 2095 | r600_pcie_gart_fini(rdev); |
1684 | rdev->accel_working = false; | 2096 | rdev->accel_working = false; |
1685 | } | 2097 | } |
1686 | if (rdev->accel_working) { | 2098 | if (rdev->accel_working) { |
1687 | r = radeon_ib_pool_init(rdev); | 2099 | r = radeon_ib_pool_init(rdev); |
1688 | if (r) { | 2100 | if (r) { |
1689 | DRM_ERROR("radeon: failled initializing IB pool (%d).\n", r); | 2101 | dev_err(rdev->dev, "IB initialization failed (%d).\n", r); |
1690 | rdev->accel_working = false; | ||
1691 | } | ||
1692 | r = r600_ib_test(rdev); | ||
1693 | if (r) { | ||
1694 | DRM_ERROR("radeon: failled testing IB (%d).\n", r); | ||
1695 | rdev->accel_working = false; | 2102 | rdev->accel_working = false; |
2103 | } else { | ||
2104 | r = r600_ib_test(rdev); | ||
2105 | if (r) { | ||
2106 | dev_err(rdev->dev, "IB test failed (%d).\n", r); | ||
2107 | rdev->accel_working = false; | ||
2108 | } | ||
1696 | } | 2109 | } |
1697 | } | 2110 | } |
2111 | |||
2112 | r = r600_audio_init(rdev); | ||
2113 | if (r) | ||
2114 | return r; /* TODO error handling */ | ||
1698 | return 0; | 2115 | return 0; |
1699 | } | 2116 | } |
1700 | 2117 | ||
1701 | void r600_fini(struct radeon_device *rdev) | 2118 | void r600_fini(struct radeon_device *rdev) |
1702 | { | 2119 | { |
1703 | /* Suspend operations */ | 2120 | radeon_pm_fini(rdev); |
1704 | r600_suspend(rdev); | 2121 | r600_audio_fini(rdev); |
1705 | |||
1706 | r600_blit_fini(rdev); | 2122 | r600_blit_fini(rdev); |
1707 | radeon_ring_fini(rdev); | 2123 | r600_cp_fini(rdev); |
1708 | r600_wb_fini(rdev); | 2124 | r600_wb_fini(rdev); |
2125 | r600_irq_fini(rdev); | ||
2126 | radeon_irq_kms_fini(rdev); | ||
1709 | r600_pcie_gart_fini(rdev); | 2127 | r600_pcie_gart_fini(rdev); |
2128 | radeon_agp_fini(rdev); | ||
1710 | radeon_gem_fini(rdev); | 2129 | radeon_gem_fini(rdev); |
1711 | radeon_fence_driver_fini(rdev); | 2130 | radeon_fence_driver_fini(rdev); |
1712 | radeon_clocks_fini(rdev); | 2131 | radeon_clocks_fini(rdev); |
1713 | if (rdev->flags & RADEON_IS_AGP) | 2132 | radeon_bo_fini(rdev); |
1714 | radeon_agp_fini(rdev); | ||
1715 | radeon_object_fini(rdev); | ||
1716 | radeon_atombios_fini(rdev); | 2133 | radeon_atombios_fini(rdev); |
1717 | kfree(rdev->bios); | 2134 | kfree(rdev->bios); |
1718 | rdev->bios = NULL; | 2135 | rdev->bios = NULL; |
@@ -1798,8 +2215,672 @@ int r600_ib_test(struct radeon_device *rdev) | |||
1798 | return r; | 2215 | return r; |
1799 | } | 2216 | } |
1800 | 2217 | ||
2218 | /* | ||
2219 | * Interrupts | ||
2220 | * | ||
2221 | * Interrupts use a ring buffer on r6xx/r7xx hardware. It works pretty | ||
2222 | * the same as the CP ring buffer, but in reverse. Rather than the CPU | ||
2223 | * writing to the ring and the GPU consuming, the GPU writes to the ring | ||
2224 | * and host consumes. As the host irq handler processes interrupts, it | ||
2225 | * increments the rptr. When the rptr catches up with the wptr, all the | ||
2226 | * current interrupts have been processed. | ||
2227 | */ | ||
2228 | |||
2229 | void r600_ih_ring_init(struct radeon_device *rdev, unsigned ring_size) | ||
2230 | { | ||
2231 | u32 rb_bufsz; | ||
2232 | |||
2233 | /* Align ring size */ | ||
2234 | rb_bufsz = drm_order(ring_size / 4); | ||
2235 | ring_size = (1 << rb_bufsz) * 4; | ||
2236 | rdev->ih.ring_size = ring_size; | ||
2237 | rdev->ih.ptr_mask = rdev->ih.ring_size - 1; | ||
2238 | rdev->ih.rptr = 0; | ||
2239 | } | ||
2240 | |||
2241 | static int r600_ih_ring_alloc(struct radeon_device *rdev) | ||
2242 | { | ||
2243 | int r; | ||
2244 | |||
2245 | /* Allocate ring buffer */ | ||
2246 | if (rdev->ih.ring_obj == NULL) { | ||
2247 | r = radeon_bo_create(rdev, NULL, rdev->ih.ring_size, | ||
2248 | true, | ||
2249 | RADEON_GEM_DOMAIN_GTT, | ||
2250 | &rdev->ih.ring_obj); | ||
2251 | if (r) { | ||
2252 | DRM_ERROR("radeon: failed to create ih ring buffer (%d).\n", r); | ||
2253 | return r; | ||
2254 | } | ||
2255 | r = radeon_bo_reserve(rdev->ih.ring_obj, false); | ||
2256 | if (unlikely(r != 0)) | ||
2257 | return r; | ||
2258 | r = radeon_bo_pin(rdev->ih.ring_obj, | ||
2259 | RADEON_GEM_DOMAIN_GTT, | ||
2260 | &rdev->ih.gpu_addr); | ||
2261 | if (r) { | ||
2262 | radeon_bo_unreserve(rdev->ih.ring_obj); | ||
2263 | DRM_ERROR("radeon: failed to pin ih ring buffer (%d).\n", r); | ||
2264 | return r; | ||
2265 | } | ||
2266 | r = radeon_bo_kmap(rdev->ih.ring_obj, | ||
2267 | (void **)&rdev->ih.ring); | ||
2268 | radeon_bo_unreserve(rdev->ih.ring_obj); | ||
2269 | if (r) { | ||
2270 | DRM_ERROR("radeon: failed to map ih ring buffer (%d).\n", r); | ||
2271 | return r; | ||
2272 | } | ||
2273 | } | ||
2274 | return 0; | ||
2275 | } | ||
2276 | |||
2277 | static void r600_ih_ring_fini(struct radeon_device *rdev) | ||
2278 | { | ||
2279 | int r; | ||
2280 | if (rdev->ih.ring_obj) { | ||
2281 | r = radeon_bo_reserve(rdev->ih.ring_obj, false); | ||
2282 | if (likely(r == 0)) { | ||
2283 | radeon_bo_kunmap(rdev->ih.ring_obj); | ||
2284 | radeon_bo_unpin(rdev->ih.ring_obj); | ||
2285 | radeon_bo_unreserve(rdev->ih.ring_obj); | ||
2286 | } | ||
2287 | radeon_bo_unref(&rdev->ih.ring_obj); | ||
2288 | rdev->ih.ring = NULL; | ||
2289 | rdev->ih.ring_obj = NULL; | ||
2290 | } | ||
2291 | } | ||
2292 | |||
2293 | static void r600_rlc_stop(struct radeon_device *rdev) | ||
2294 | { | ||
2295 | |||
2296 | if (rdev->family >= CHIP_RV770) { | ||
2297 | /* r7xx asics need to soft reset RLC before halting */ | ||
2298 | WREG32(SRBM_SOFT_RESET, SOFT_RESET_RLC); | ||
2299 | RREG32(SRBM_SOFT_RESET); | ||
2300 | udelay(15000); | ||
2301 | WREG32(SRBM_SOFT_RESET, 0); | ||
2302 | RREG32(SRBM_SOFT_RESET); | ||
2303 | } | ||
2304 | |||
2305 | WREG32(RLC_CNTL, 0); | ||
2306 | } | ||
2307 | |||
2308 | static void r600_rlc_start(struct radeon_device *rdev) | ||
2309 | { | ||
2310 | WREG32(RLC_CNTL, RLC_ENABLE); | ||
2311 | } | ||
2312 | |||
2313 | static int r600_rlc_init(struct radeon_device *rdev) | ||
2314 | { | ||
2315 | u32 i; | ||
2316 | const __be32 *fw_data; | ||
2317 | |||
2318 | if (!rdev->rlc_fw) | ||
2319 | return -EINVAL; | ||
2320 | |||
2321 | r600_rlc_stop(rdev); | ||
2322 | |||
2323 | WREG32(RLC_HB_BASE, 0); | ||
2324 | WREG32(RLC_HB_CNTL, 0); | ||
2325 | WREG32(RLC_HB_RPTR, 0); | ||
2326 | WREG32(RLC_HB_WPTR, 0); | ||
2327 | WREG32(RLC_HB_WPTR_LSB_ADDR, 0); | ||
2328 | WREG32(RLC_HB_WPTR_MSB_ADDR, 0); | ||
2329 | WREG32(RLC_MC_CNTL, 0); | ||
2330 | WREG32(RLC_UCODE_CNTL, 0); | ||
2331 | |||
2332 | fw_data = (const __be32 *)rdev->rlc_fw->data; | ||
2333 | if (rdev->family >= CHIP_RV770) { | ||
2334 | for (i = 0; i < R700_RLC_UCODE_SIZE; i++) { | ||
2335 | WREG32(RLC_UCODE_ADDR, i); | ||
2336 | WREG32(RLC_UCODE_DATA, be32_to_cpup(fw_data++)); | ||
2337 | } | ||
2338 | } else { | ||
2339 | for (i = 0; i < RLC_UCODE_SIZE; i++) { | ||
2340 | WREG32(RLC_UCODE_ADDR, i); | ||
2341 | WREG32(RLC_UCODE_DATA, be32_to_cpup(fw_data++)); | ||
2342 | } | ||
2343 | } | ||
2344 | WREG32(RLC_UCODE_ADDR, 0); | ||
2345 | |||
2346 | r600_rlc_start(rdev); | ||
2347 | |||
2348 | return 0; | ||
2349 | } | ||
2350 | |||
2351 | static void r600_enable_interrupts(struct radeon_device *rdev) | ||
2352 | { | ||
2353 | u32 ih_cntl = RREG32(IH_CNTL); | ||
2354 | u32 ih_rb_cntl = RREG32(IH_RB_CNTL); | ||
2355 | |||
2356 | ih_cntl |= ENABLE_INTR; | ||
2357 | ih_rb_cntl |= IH_RB_ENABLE; | ||
2358 | WREG32(IH_CNTL, ih_cntl); | ||
2359 | WREG32(IH_RB_CNTL, ih_rb_cntl); | ||
2360 | rdev->ih.enabled = true; | ||
2361 | } | ||
2362 | |||
2363 | static void r600_disable_interrupts(struct radeon_device *rdev) | ||
2364 | { | ||
2365 | u32 ih_rb_cntl = RREG32(IH_RB_CNTL); | ||
2366 | u32 ih_cntl = RREG32(IH_CNTL); | ||
2367 | |||
2368 | ih_rb_cntl &= ~IH_RB_ENABLE; | ||
2369 | ih_cntl &= ~ENABLE_INTR; | ||
2370 | WREG32(IH_RB_CNTL, ih_rb_cntl); | ||
2371 | WREG32(IH_CNTL, ih_cntl); | ||
2372 | /* set rptr, wptr to 0 */ | ||
2373 | WREG32(IH_RB_RPTR, 0); | ||
2374 | WREG32(IH_RB_WPTR, 0); | ||
2375 | rdev->ih.enabled = false; | ||
2376 | rdev->ih.wptr = 0; | ||
2377 | rdev->ih.rptr = 0; | ||
2378 | } | ||
2379 | |||
2380 | static void r600_disable_interrupt_state(struct radeon_device *rdev) | ||
2381 | { | ||
2382 | u32 tmp; | ||
2383 | |||
2384 | WREG32(CP_INT_CNTL, 0); | ||
2385 | WREG32(GRBM_INT_CNTL, 0); | ||
2386 | WREG32(DxMODE_INT_MASK, 0); | ||
2387 | if (ASIC_IS_DCE3(rdev)) { | ||
2388 | WREG32(DCE3_DACA_AUTODETECT_INT_CONTROL, 0); | ||
2389 | WREG32(DCE3_DACB_AUTODETECT_INT_CONTROL, 0); | ||
2390 | tmp = RREG32(DC_HPD1_INT_CONTROL) & DC_HPDx_INT_POLARITY; | ||
2391 | WREG32(DC_HPD1_INT_CONTROL, tmp); | ||
2392 | tmp = RREG32(DC_HPD2_INT_CONTROL) & DC_HPDx_INT_POLARITY; | ||
2393 | WREG32(DC_HPD2_INT_CONTROL, tmp); | ||
2394 | tmp = RREG32(DC_HPD3_INT_CONTROL) & DC_HPDx_INT_POLARITY; | ||
2395 | WREG32(DC_HPD3_INT_CONTROL, tmp); | ||
2396 | tmp = RREG32(DC_HPD4_INT_CONTROL) & DC_HPDx_INT_POLARITY; | ||
2397 | WREG32(DC_HPD4_INT_CONTROL, tmp); | ||
2398 | if (ASIC_IS_DCE32(rdev)) { | ||
2399 | tmp = RREG32(DC_HPD5_INT_CONTROL) & DC_HPDx_INT_POLARITY; | ||
2400 | WREG32(DC_HPD5_INT_CONTROL, tmp); | ||
2401 | tmp = RREG32(DC_HPD6_INT_CONTROL) & DC_HPDx_INT_POLARITY; | ||
2402 | WREG32(DC_HPD6_INT_CONTROL, tmp); | ||
2403 | } | ||
2404 | } else { | ||
2405 | WREG32(DACA_AUTODETECT_INT_CONTROL, 0); | ||
2406 | WREG32(DACB_AUTODETECT_INT_CONTROL, 0); | ||
2407 | tmp = RREG32(DC_HOT_PLUG_DETECT1_INT_CONTROL) & DC_HOT_PLUG_DETECTx_INT_POLARITY; | ||
2408 | WREG32(DC_HOT_PLUG_DETECT1_INT_CONTROL, tmp); | ||
2409 | tmp = RREG32(DC_HOT_PLUG_DETECT2_INT_CONTROL) & DC_HOT_PLUG_DETECTx_INT_POLARITY; | ||
2410 | WREG32(DC_HOT_PLUG_DETECT2_INT_CONTROL, tmp); | ||
2411 | tmp = RREG32(DC_HOT_PLUG_DETECT3_INT_CONTROL) & DC_HOT_PLUG_DETECTx_INT_POLARITY; | ||
2412 | WREG32(DC_HOT_PLUG_DETECT3_INT_CONTROL, tmp); | ||
2413 | } | ||
2414 | } | ||
2415 | |||
2416 | int r600_irq_init(struct radeon_device *rdev) | ||
2417 | { | ||
2418 | int ret = 0; | ||
2419 | int rb_bufsz; | ||
2420 | u32 interrupt_cntl, ih_cntl, ih_rb_cntl; | ||
2421 | |||
2422 | /* allocate ring */ | ||
2423 | ret = r600_ih_ring_alloc(rdev); | ||
2424 | if (ret) | ||
2425 | return ret; | ||
2426 | |||
2427 | /* disable irqs */ | ||
2428 | r600_disable_interrupts(rdev); | ||
2429 | |||
2430 | /* init rlc */ | ||
2431 | ret = r600_rlc_init(rdev); | ||
2432 | if (ret) { | ||
2433 | r600_ih_ring_fini(rdev); | ||
2434 | return ret; | ||
2435 | } | ||
2436 | |||
2437 | /* setup interrupt control */ | ||
2438 | /* set dummy read address to ring address */ | ||
2439 | WREG32(INTERRUPT_CNTL2, rdev->ih.gpu_addr >> 8); | ||
2440 | interrupt_cntl = RREG32(INTERRUPT_CNTL); | ||
2441 | /* IH_DUMMY_RD_OVERRIDE=0 - dummy read disabled with msi, enabled without msi | ||
2442 | * IH_DUMMY_RD_OVERRIDE=1 - dummy read controlled by IH_DUMMY_RD_EN | ||
2443 | */ | ||
2444 | interrupt_cntl &= ~IH_DUMMY_RD_OVERRIDE; | ||
2445 | /* IH_REQ_NONSNOOP_EN=1 if ring is in non-cacheable memory, e.g., vram */ | ||
2446 | interrupt_cntl &= ~IH_REQ_NONSNOOP_EN; | ||
2447 | WREG32(INTERRUPT_CNTL, interrupt_cntl); | ||
2448 | |||
2449 | WREG32(IH_RB_BASE, rdev->ih.gpu_addr >> 8); | ||
2450 | rb_bufsz = drm_order(rdev->ih.ring_size / 4); | ||
2451 | |||
2452 | ih_rb_cntl = (IH_WPTR_OVERFLOW_ENABLE | | ||
2453 | IH_WPTR_OVERFLOW_CLEAR | | ||
2454 | (rb_bufsz << 1)); | ||
2455 | /* WPTR writeback, not yet */ | ||
2456 | /*ih_rb_cntl |= IH_WPTR_WRITEBACK_ENABLE;*/ | ||
2457 | WREG32(IH_RB_WPTR_ADDR_LO, 0); | ||
2458 | WREG32(IH_RB_WPTR_ADDR_HI, 0); | ||
2459 | |||
2460 | WREG32(IH_RB_CNTL, ih_rb_cntl); | ||
2461 | |||
2462 | /* set rptr, wptr to 0 */ | ||
2463 | WREG32(IH_RB_RPTR, 0); | ||
2464 | WREG32(IH_RB_WPTR, 0); | ||
2465 | |||
2466 | /* Default settings for IH_CNTL (disabled at first) */ | ||
2467 | ih_cntl = MC_WRREQ_CREDIT(0x10) | MC_WR_CLEAN_CNT(0x10); | ||
2468 | /* RPTR_REARM only works if msi's are enabled */ | ||
2469 | if (rdev->msi_enabled) | ||
2470 | ih_cntl |= RPTR_REARM; | ||
2471 | |||
2472 | #ifdef __BIG_ENDIAN | ||
2473 | ih_cntl |= IH_MC_SWAP(IH_MC_SWAP_32BIT); | ||
2474 | #endif | ||
2475 | WREG32(IH_CNTL, ih_cntl); | ||
2476 | |||
2477 | /* force the active interrupt state to all disabled */ | ||
2478 | r600_disable_interrupt_state(rdev); | ||
2479 | |||
2480 | /* enable irqs */ | ||
2481 | r600_enable_interrupts(rdev); | ||
2482 | |||
2483 | return ret; | ||
2484 | } | ||
2485 | |||
2486 | void r600_irq_suspend(struct radeon_device *rdev) | ||
2487 | { | ||
2488 | r600_disable_interrupts(rdev); | ||
2489 | r600_rlc_stop(rdev); | ||
2490 | } | ||
2491 | |||
2492 | void r600_irq_fini(struct radeon_device *rdev) | ||
2493 | { | ||
2494 | r600_irq_suspend(rdev); | ||
2495 | r600_ih_ring_fini(rdev); | ||
2496 | } | ||
2497 | |||
2498 | int r600_irq_set(struct radeon_device *rdev) | ||
2499 | { | ||
2500 | u32 cp_int_cntl = CNTX_BUSY_INT_ENABLE | CNTX_EMPTY_INT_ENABLE; | ||
2501 | u32 mode_int = 0; | ||
2502 | u32 hpd1, hpd2, hpd3, hpd4 = 0, hpd5 = 0, hpd6 = 0; | ||
2503 | |||
2504 | if (!rdev->irq.installed) { | ||
2505 | WARN(1, "Can't enable IRQ/MSI because no handler is installed.\n"); | ||
2506 | return -EINVAL; | ||
2507 | } | ||
2508 | /* don't enable anything if the ih is disabled */ | ||
2509 | if (!rdev->ih.enabled) { | ||
2510 | r600_disable_interrupts(rdev); | ||
2511 | /* force the active interrupt state to all disabled */ | ||
2512 | r600_disable_interrupt_state(rdev); | ||
2513 | return 0; | ||
2514 | } | ||
2515 | |||
2516 | if (ASIC_IS_DCE3(rdev)) { | ||
2517 | hpd1 = RREG32(DC_HPD1_INT_CONTROL) & ~DC_HPDx_INT_EN; | ||
2518 | hpd2 = RREG32(DC_HPD2_INT_CONTROL) & ~DC_HPDx_INT_EN; | ||
2519 | hpd3 = RREG32(DC_HPD3_INT_CONTROL) & ~DC_HPDx_INT_EN; | ||
2520 | hpd4 = RREG32(DC_HPD4_INT_CONTROL) & ~DC_HPDx_INT_EN; | ||
2521 | if (ASIC_IS_DCE32(rdev)) { | ||
2522 | hpd5 = RREG32(DC_HPD5_INT_CONTROL) & ~DC_HPDx_INT_EN; | ||
2523 | hpd6 = RREG32(DC_HPD6_INT_CONTROL) & ~DC_HPDx_INT_EN; | ||
2524 | } | ||
2525 | } else { | ||
2526 | hpd1 = RREG32(DC_HOT_PLUG_DETECT1_INT_CONTROL) & ~DC_HPDx_INT_EN; | ||
2527 | hpd2 = RREG32(DC_HOT_PLUG_DETECT2_INT_CONTROL) & ~DC_HPDx_INT_EN; | ||
2528 | hpd3 = RREG32(DC_HOT_PLUG_DETECT3_INT_CONTROL) & ~DC_HPDx_INT_EN; | ||
2529 | } | ||
2530 | |||
2531 | if (rdev->irq.sw_int) { | ||
2532 | DRM_DEBUG("r600_irq_set: sw int\n"); | ||
2533 | cp_int_cntl |= RB_INT_ENABLE; | ||
2534 | } | ||
2535 | if (rdev->irq.crtc_vblank_int[0]) { | ||
2536 | DRM_DEBUG("r600_irq_set: vblank 0\n"); | ||
2537 | mode_int |= D1MODE_VBLANK_INT_MASK; | ||
2538 | } | ||
2539 | if (rdev->irq.crtc_vblank_int[1]) { | ||
2540 | DRM_DEBUG("r600_irq_set: vblank 1\n"); | ||
2541 | mode_int |= D2MODE_VBLANK_INT_MASK; | ||
2542 | } | ||
2543 | if (rdev->irq.hpd[0]) { | ||
2544 | DRM_DEBUG("r600_irq_set: hpd 1\n"); | ||
2545 | hpd1 |= DC_HPDx_INT_EN; | ||
2546 | } | ||
2547 | if (rdev->irq.hpd[1]) { | ||
2548 | DRM_DEBUG("r600_irq_set: hpd 2\n"); | ||
2549 | hpd2 |= DC_HPDx_INT_EN; | ||
2550 | } | ||
2551 | if (rdev->irq.hpd[2]) { | ||
2552 | DRM_DEBUG("r600_irq_set: hpd 3\n"); | ||
2553 | hpd3 |= DC_HPDx_INT_EN; | ||
2554 | } | ||
2555 | if (rdev->irq.hpd[3]) { | ||
2556 | DRM_DEBUG("r600_irq_set: hpd 4\n"); | ||
2557 | hpd4 |= DC_HPDx_INT_EN; | ||
2558 | } | ||
2559 | if (rdev->irq.hpd[4]) { | ||
2560 | DRM_DEBUG("r600_irq_set: hpd 5\n"); | ||
2561 | hpd5 |= DC_HPDx_INT_EN; | ||
2562 | } | ||
2563 | if (rdev->irq.hpd[5]) { | ||
2564 | DRM_DEBUG("r600_irq_set: hpd 6\n"); | ||
2565 | hpd6 |= DC_HPDx_INT_EN; | ||
2566 | } | ||
2567 | |||
2568 | WREG32(CP_INT_CNTL, cp_int_cntl); | ||
2569 | WREG32(DxMODE_INT_MASK, mode_int); | ||
2570 | if (ASIC_IS_DCE3(rdev)) { | ||
2571 | WREG32(DC_HPD1_INT_CONTROL, hpd1); | ||
2572 | WREG32(DC_HPD2_INT_CONTROL, hpd2); | ||
2573 | WREG32(DC_HPD3_INT_CONTROL, hpd3); | ||
2574 | WREG32(DC_HPD4_INT_CONTROL, hpd4); | ||
2575 | if (ASIC_IS_DCE32(rdev)) { | ||
2576 | WREG32(DC_HPD5_INT_CONTROL, hpd5); | ||
2577 | WREG32(DC_HPD6_INT_CONTROL, hpd6); | ||
2578 | } | ||
2579 | } else { | ||
2580 | WREG32(DC_HOT_PLUG_DETECT1_INT_CONTROL, hpd1); | ||
2581 | WREG32(DC_HOT_PLUG_DETECT2_INT_CONTROL, hpd2); | ||
2582 | WREG32(DC_HOT_PLUG_DETECT3_INT_CONTROL, hpd3); | ||
2583 | } | ||
2584 | |||
2585 | return 0; | ||
2586 | } | ||
2587 | |||
2588 | static inline void r600_irq_ack(struct radeon_device *rdev, | ||
2589 | u32 *disp_int, | ||
2590 | u32 *disp_int_cont, | ||
2591 | u32 *disp_int_cont2) | ||
2592 | { | ||
2593 | u32 tmp; | ||
2594 | |||
2595 | if (ASIC_IS_DCE3(rdev)) { | ||
2596 | *disp_int = RREG32(DCE3_DISP_INTERRUPT_STATUS); | ||
2597 | *disp_int_cont = RREG32(DCE3_DISP_INTERRUPT_STATUS_CONTINUE); | ||
2598 | *disp_int_cont2 = RREG32(DCE3_DISP_INTERRUPT_STATUS_CONTINUE2); | ||
2599 | } else { | ||
2600 | *disp_int = RREG32(DISP_INTERRUPT_STATUS); | ||
2601 | *disp_int_cont = RREG32(DISP_INTERRUPT_STATUS_CONTINUE); | ||
2602 | *disp_int_cont2 = 0; | ||
2603 | } | ||
2604 | |||
2605 | if (*disp_int & LB_D1_VBLANK_INTERRUPT) | ||
2606 | WREG32(D1MODE_VBLANK_STATUS, DxMODE_VBLANK_ACK); | ||
2607 | if (*disp_int & LB_D1_VLINE_INTERRUPT) | ||
2608 | WREG32(D1MODE_VLINE_STATUS, DxMODE_VLINE_ACK); | ||
2609 | if (*disp_int & LB_D2_VBLANK_INTERRUPT) | ||
2610 | WREG32(D2MODE_VBLANK_STATUS, DxMODE_VBLANK_ACK); | ||
2611 | if (*disp_int & LB_D2_VLINE_INTERRUPT) | ||
2612 | WREG32(D2MODE_VLINE_STATUS, DxMODE_VLINE_ACK); | ||
2613 | if (*disp_int & DC_HPD1_INTERRUPT) { | ||
2614 | if (ASIC_IS_DCE3(rdev)) { | ||
2615 | tmp = RREG32(DC_HPD1_INT_CONTROL); | ||
2616 | tmp |= DC_HPDx_INT_ACK; | ||
2617 | WREG32(DC_HPD1_INT_CONTROL, tmp); | ||
2618 | } else { | ||
2619 | tmp = RREG32(DC_HOT_PLUG_DETECT1_INT_CONTROL); | ||
2620 | tmp |= DC_HPDx_INT_ACK; | ||
2621 | WREG32(DC_HOT_PLUG_DETECT1_INT_CONTROL, tmp); | ||
2622 | } | ||
2623 | } | ||
2624 | if (*disp_int & DC_HPD2_INTERRUPT) { | ||
2625 | if (ASIC_IS_DCE3(rdev)) { | ||
2626 | tmp = RREG32(DC_HPD2_INT_CONTROL); | ||
2627 | tmp |= DC_HPDx_INT_ACK; | ||
2628 | WREG32(DC_HPD2_INT_CONTROL, tmp); | ||
2629 | } else { | ||
2630 | tmp = RREG32(DC_HOT_PLUG_DETECT2_INT_CONTROL); | ||
2631 | tmp |= DC_HPDx_INT_ACK; | ||
2632 | WREG32(DC_HOT_PLUG_DETECT2_INT_CONTROL, tmp); | ||
2633 | } | ||
2634 | } | ||
2635 | if (*disp_int_cont & DC_HPD3_INTERRUPT) { | ||
2636 | if (ASIC_IS_DCE3(rdev)) { | ||
2637 | tmp = RREG32(DC_HPD3_INT_CONTROL); | ||
2638 | tmp |= DC_HPDx_INT_ACK; | ||
2639 | WREG32(DC_HPD3_INT_CONTROL, tmp); | ||
2640 | } else { | ||
2641 | tmp = RREG32(DC_HOT_PLUG_DETECT3_INT_CONTROL); | ||
2642 | tmp |= DC_HPDx_INT_ACK; | ||
2643 | WREG32(DC_HOT_PLUG_DETECT3_INT_CONTROL, tmp); | ||
2644 | } | ||
2645 | } | ||
2646 | if (*disp_int_cont & DC_HPD4_INTERRUPT) { | ||
2647 | tmp = RREG32(DC_HPD4_INT_CONTROL); | ||
2648 | tmp |= DC_HPDx_INT_ACK; | ||
2649 | WREG32(DC_HPD4_INT_CONTROL, tmp); | ||
2650 | } | ||
2651 | if (ASIC_IS_DCE32(rdev)) { | ||
2652 | if (*disp_int_cont2 & DC_HPD5_INTERRUPT) { | ||
2653 | tmp = RREG32(DC_HPD5_INT_CONTROL); | ||
2654 | tmp |= DC_HPDx_INT_ACK; | ||
2655 | WREG32(DC_HPD5_INT_CONTROL, tmp); | ||
2656 | } | ||
2657 | if (*disp_int_cont2 & DC_HPD6_INTERRUPT) { | ||
2658 | tmp = RREG32(DC_HPD5_INT_CONTROL); | ||
2659 | tmp |= DC_HPDx_INT_ACK; | ||
2660 | WREG32(DC_HPD6_INT_CONTROL, tmp); | ||
2661 | } | ||
2662 | } | ||
2663 | } | ||
2664 | |||
2665 | void r600_irq_disable(struct radeon_device *rdev) | ||
2666 | { | ||
2667 | u32 disp_int, disp_int_cont, disp_int_cont2; | ||
2668 | |||
2669 | r600_disable_interrupts(rdev); | ||
2670 | /* Wait and acknowledge irq */ | ||
2671 | mdelay(1); | ||
2672 | r600_irq_ack(rdev, &disp_int, &disp_int_cont, &disp_int_cont2); | ||
2673 | r600_disable_interrupt_state(rdev); | ||
2674 | } | ||
2675 | |||
2676 | static inline u32 r600_get_ih_wptr(struct radeon_device *rdev) | ||
2677 | { | ||
2678 | u32 wptr, tmp; | ||
1801 | 2679 | ||
2680 | /* XXX use writeback */ | ||
2681 | wptr = RREG32(IH_RB_WPTR); | ||
1802 | 2682 | ||
2683 | if (wptr & RB_OVERFLOW) { | ||
2684 | /* When a ring buffer overflow happen start parsing interrupt | ||
2685 | * from the last not overwritten vector (wptr + 16). Hopefully | ||
2686 | * this should allow us to catchup. | ||
2687 | */ | ||
2688 | dev_warn(rdev->dev, "IH ring buffer overflow (0x%08X, %d, %d)\n", | ||
2689 | wptr, rdev->ih.rptr, (wptr + 16) + rdev->ih.ptr_mask); | ||
2690 | rdev->ih.rptr = (wptr + 16) & rdev->ih.ptr_mask; | ||
2691 | tmp = RREG32(IH_RB_CNTL); | ||
2692 | tmp |= IH_WPTR_OVERFLOW_CLEAR; | ||
2693 | WREG32(IH_RB_CNTL, tmp); | ||
2694 | } | ||
2695 | return (wptr & rdev->ih.ptr_mask); | ||
2696 | } | ||
2697 | |||
2698 | /* r600 IV Ring | ||
2699 | * Each IV ring entry is 128 bits: | ||
2700 | * [7:0] - interrupt source id | ||
2701 | * [31:8] - reserved | ||
2702 | * [59:32] - interrupt source data | ||
2703 | * [127:60] - reserved | ||
2704 | * | ||
2705 | * The basic interrupt vector entries | ||
2706 | * are decoded as follows: | ||
2707 | * src_id src_data description | ||
2708 | * 1 0 D1 Vblank | ||
2709 | * 1 1 D1 Vline | ||
2710 | * 5 0 D2 Vblank | ||
2711 | * 5 1 D2 Vline | ||
2712 | * 19 0 FP Hot plug detection A | ||
2713 | * 19 1 FP Hot plug detection B | ||
2714 | * 19 2 DAC A auto-detection | ||
2715 | * 19 3 DAC B auto-detection | ||
2716 | * 176 - CP_INT RB | ||
2717 | * 177 - CP_INT IB1 | ||
2718 | * 178 - CP_INT IB2 | ||
2719 | * 181 - EOP Interrupt | ||
2720 | * 233 - GUI Idle | ||
2721 | * | ||
2722 | * Note, these are based on r600 and may need to be | ||
2723 | * adjusted or added to on newer asics | ||
2724 | */ | ||
2725 | |||
2726 | int r600_irq_process(struct radeon_device *rdev) | ||
2727 | { | ||
2728 | u32 wptr = r600_get_ih_wptr(rdev); | ||
2729 | u32 rptr = rdev->ih.rptr; | ||
2730 | u32 src_id, src_data; | ||
2731 | u32 ring_index, disp_int, disp_int_cont, disp_int_cont2; | ||
2732 | unsigned long flags; | ||
2733 | bool queue_hotplug = false; | ||
2734 | |||
2735 | DRM_DEBUG("r600_irq_process start: rptr %d, wptr %d\n", rptr, wptr); | ||
2736 | if (!rdev->ih.enabled) | ||
2737 | return IRQ_NONE; | ||
2738 | |||
2739 | spin_lock_irqsave(&rdev->ih.lock, flags); | ||
2740 | |||
2741 | if (rptr == wptr) { | ||
2742 | spin_unlock_irqrestore(&rdev->ih.lock, flags); | ||
2743 | return IRQ_NONE; | ||
2744 | } | ||
2745 | if (rdev->shutdown) { | ||
2746 | spin_unlock_irqrestore(&rdev->ih.lock, flags); | ||
2747 | return IRQ_NONE; | ||
2748 | } | ||
2749 | |||
2750 | restart_ih: | ||
2751 | /* display interrupts */ | ||
2752 | r600_irq_ack(rdev, &disp_int, &disp_int_cont, &disp_int_cont2); | ||
2753 | |||
2754 | rdev->ih.wptr = wptr; | ||
2755 | while (rptr != wptr) { | ||
2756 | /* wptr/rptr are in bytes! */ | ||
2757 | ring_index = rptr / 4; | ||
2758 | src_id = rdev->ih.ring[ring_index] & 0xff; | ||
2759 | src_data = rdev->ih.ring[ring_index + 1] & 0xfffffff; | ||
2760 | |||
2761 | switch (src_id) { | ||
2762 | case 1: /* D1 vblank/vline */ | ||
2763 | switch (src_data) { | ||
2764 | case 0: /* D1 vblank */ | ||
2765 | if (disp_int & LB_D1_VBLANK_INTERRUPT) { | ||
2766 | drm_handle_vblank(rdev->ddev, 0); | ||
2767 | rdev->pm.vblank_sync = true; | ||
2768 | wake_up(&rdev->irq.vblank_queue); | ||
2769 | disp_int &= ~LB_D1_VBLANK_INTERRUPT; | ||
2770 | DRM_DEBUG("IH: D1 vblank\n"); | ||
2771 | } | ||
2772 | break; | ||
2773 | case 1: /* D1 vline */ | ||
2774 | if (disp_int & LB_D1_VLINE_INTERRUPT) { | ||
2775 | disp_int &= ~LB_D1_VLINE_INTERRUPT; | ||
2776 | DRM_DEBUG("IH: D1 vline\n"); | ||
2777 | } | ||
2778 | break; | ||
2779 | default: | ||
2780 | DRM_DEBUG("Unhandled interrupt: %d %d\n", src_id, src_data); | ||
2781 | break; | ||
2782 | } | ||
2783 | break; | ||
2784 | case 5: /* D2 vblank/vline */ | ||
2785 | switch (src_data) { | ||
2786 | case 0: /* D2 vblank */ | ||
2787 | if (disp_int & LB_D2_VBLANK_INTERRUPT) { | ||
2788 | drm_handle_vblank(rdev->ddev, 1); | ||
2789 | rdev->pm.vblank_sync = true; | ||
2790 | wake_up(&rdev->irq.vblank_queue); | ||
2791 | disp_int &= ~LB_D2_VBLANK_INTERRUPT; | ||
2792 | DRM_DEBUG("IH: D2 vblank\n"); | ||
2793 | } | ||
2794 | break; | ||
2795 | case 1: /* D1 vline */ | ||
2796 | if (disp_int & LB_D2_VLINE_INTERRUPT) { | ||
2797 | disp_int &= ~LB_D2_VLINE_INTERRUPT; | ||
2798 | DRM_DEBUG("IH: D2 vline\n"); | ||
2799 | } | ||
2800 | break; | ||
2801 | default: | ||
2802 | DRM_DEBUG("Unhandled interrupt: %d %d\n", src_id, src_data); | ||
2803 | break; | ||
2804 | } | ||
2805 | break; | ||
2806 | case 19: /* HPD/DAC hotplug */ | ||
2807 | switch (src_data) { | ||
2808 | case 0: | ||
2809 | if (disp_int & DC_HPD1_INTERRUPT) { | ||
2810 | disp_int &= ~DC_HPD1_INTERRUPT; | ||
2811 | queue_hotplug = true; | ||
2812 | DRM_DEBUG("IH: HPD1\n"); | ||
2813 | } | ||
2814 | break; | ||
2815 | case 1: | ||
2816 | if (disp_int & DC_HPD2_INTERRUPT) { | ||
2817 | disp_int &= ~DC_HPD2_INTERRUPT; | ||
2818 | queue_hotplug = true; | ||
2819 | DRM_DEBUG("IH: HPD2\n"); | ||
2820 | } | ||
2821 | break; | ||
2822 | case 4: | ||
2823 | if (disp_int_cont & DC_HPD3_INTERRUPT) { | ||
2824 | disp_int_cont &= ~DC_HPD3_INTERRUPT; | ||
2825 | queue_hotplug = true; | ||
2826 | DRM_DEBUG("IH: HPD3\n"); | ||
2827 | } | ||
2828 | break; | ||
2829 | case 5: | ||
2830 | if (disp_int_cont & DC_HPD4_INTERRUPT) { | ||
2831 | disp_int_cont &= ~DC_HPD4_INTERRUPT; | ||
2832 | queue_hotplug = true; | ||
2833 | DRM_DEBUG("IH: HPD4\n"); | ||
2834 | } | ||
2835 | break; | ||
2836 | case 10: | ||
2837 | if (disp_int_cont2 & DC_HPD5_INTERRUPT) { | ||
2838 | disp_int_cont2 &= ~DC_HPD5_INTERRUPT; | ||
2839 | queue_hotplug = true; | ||
2840 | DRM_DEBUG("IH: HPD5\n"); | ||
2841 | } | ||
2842 | break; | ||
2843 | case 12: | ||
2844 | if (disp_int_cont2 & DC_HPD6_INTERRUPT) { | ||
2845 | disp_int_cont2 &= ~DC_HPD6_INTERRUPT; | ||
2846 | queue_hotplug = true; | ||
2847 | DRM_DEBUG("IH: HPD6\n"); | ||
2848 | } | ||
2849 | break; | ||
2850 | default: | ||
2851 | DRM_DEBUG("Unhandled interrupt: %d %d\n", src_id, src_data); | ||
2852 | break; | ||
2853 | } | ||
2854 | break; | ||
2855 | case 176: /* CP_INT in ring buffer */ | ||
2856 | case 177: /* CP_INT in IB1 */ | ||
2857 | case 178: /* CP_INT in IB2 */ | ||
2858 | DRM_DEBUG("IH: CP int: 0x%08x\n", src_data); | ||
2859 | radeon_fence_process(rdev); | ||
2860 | break; | ||
2861 | case 181: /* CP EOP event */ | ||
2862 | DRM_DEBUG("IH: CP EOP\n"); | ||
2863 | break; | ||
2864 | default: | ||
2865 | DRM_DEBUG("Unhandled interrupt: %d %d\n", src_id, src_data); | ||
2866 | break; | ||
2867 | } | ||
2868 | |||
2869 | /* wptr/rptr are in bytes! */ | ||
2870 | rptr += 16; | ||
2871 | rptr &= rdev->ih.ptr_mask; | ||
2872 | } | ||
2873 | /* make sure wptr hasn't changed while processing */ | ||
2874 | wptr = r600_get_ih_wptr(rdev); | ||
2875 | if (wptr != rdev->ih.wptr) | ||
2876 | goto restart_ih; | ||
2877 | if (queue_hotplug) | ||
2878 | queue_work(rdev->wq, &rdev->hotplug_work); | ||
2879 | rdev->ih.rptr = rptr; | ||
2880 | WREG32(IH_RB_RPTR, rdev->ih.rptr); | ||
2881 | spin_unlock_irqrestore(&rdev->ih.lock, flags); | ||
2882 | return IRQ_HANDLED; | ||
2883 | } | ||
1803 | 2884 | ||
1804 | /* | 2885 | /* |
1805 | * Debugfs info | 2886 | * Debugfs info |
@@ -1811,21 +2892,21 @@ static int r600_debugfs_cp_ring_info(struct seq_file *m, void *data) | |||
1811 | struct drm_info_node *node = (struct drm_info_node *) m->private; | 2892 | struct drm_info_node *node = (struct drm_info_node *) m->private; |
1812 | struct drm_device *dev = node->minor->dev; | 2893 | struct drm_device *dev = node->minor->dev; |
1813 | struct radeon_device *rdev = dev->dev_private; | 2894 | struct radeon_device *rdev = dev->dev_private; |
1814 | uint32_t rdp, wdp; | ||
1815 | unsigned count, i, j; | 2895 | unsigned count, i, j; |
1816 | 2896 | ||
1817 | radeon_ring_free_size(rdev); | 2897 | radeon_ring_free_size(rdev); |
1818 | rdp = RREG32(CP_RB_RPTR); | 2898 | count = (rdev->cp.ring_size / 4) - rdev->cp.ring_free_dw; |
1819 | wdp = RREG32(CP_RB_WPTR); | ||
1820 | count = (rdp + rdev->cp.ring_size - wdp) & rdev->cp.ptr_mask; | ||
1821 | seq_printf(m, "CP_STAT 0x%08x\n", RREG32(CP_STAT)); | 2899 | seq_printf(m, "CP_STAT 0x%08x\n", RREG32(CP_STAT)); |
1822 | seq_printf(m, "CP_RB_WPTR 0x%08x\n", wdp); | 2900 | seq_printf(m, "CP_RB_WPTR 0x%08x\n", RREG32(CP_RB_WPTR)); |
1823 | seq_printf(m, "CP_RB_RPTR 0x%08x\n", rdp); | 2901 | seq_printf(m, "CP_RB_RPTR 0x%08x\n", RREG32(CP_RB_RPTR)); |
2902 | seq_printf(m, "driver's copy of the CP_RB_WPTR 0x%08x\n", rdev->cp.wptr); | ||
2903 | seq_printf(m, "driver's copy of the CP_RB_RPTR 0x%08x\n", rdev->cp.rptr); | ||
1824 | seq_printf(m, "%u free dwords in ring\n", rdev->cp.ring_free_dw); | 2904 | seq_printf(m, "%u free dwords in ring\n", rdev->cp.ring_free_dw); |
1825 | seq_printf(m, "%u dwords in ring\n", count); | 2905 | seq_printf(m, "%u dwords in ring\n", count); |
2906 | i = rdev->cp.rptr; | ||
1826 | for (j = 0; j <= count; j++) { | 2907 | for (j = 0; j <= count; j++) { |
1827 | i = (rdp + j) & rdev->cp.ptr_mask; | ||
1828 | seq_printf(m, "r[%04d]=0x%08x\n", i, rdev->cp.ring[i]); | 2908 | seq_printf(m, "r[%04d]=0x%08x\n", i, rdev->cp.ring[i]); |
2909 | i = (i + 1) & rdev->cp.ptr_mask; | ||
1829 | } | 2910 | } |
1830 | return 0; | 2911 | return 0; |
1831 | } | 2912 | } |
@@ -1855,3 +2936,18 @@ int r600_debugfs_mc_info_init(struct radeon_device *rdev) | |||
1855 | return 0; | 2936 | return 0; |
1856 | #endif | 2937 | #endif |
1857 | } | 2938 | } |
2939 | |||
2940 | /** | ||
2941 | * r600_ioctl_wait_idle - flush host path cache on wait idle ioctl | ||
2942 | * rdev: radeon device structure | ||
2943 | * bo: buffer object struct which userspace is waiting for idle | ||
2944 | * | ||
2945 | * Some R6XX/R7XX doesn't seems to take into account HDP flush performed | ||
2946 | * through ring buffer, this leads to corruption in rendering, see | ||
2947 | * http://bugzilla.kernel.org/show_bug.cgi?id=15186 to avoid this we | ||
2948 | * directly perform HDP flush by writing register through MMIO. | ||
2949 | */ | ||
2950 | void r600_ioctl_wait_idle(struct radeon_device *rdev, struct radeon_bo *bo) | ||
2951 | { | ||
2952 | WREG32(R_005480_HDP_MEM_COHERENCY_FLUSH_CNTL, 0x1); | ||
2953 | } | ||