Rev 1179 | Rev 1246 | Go to most recent revision | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 1179 | Rev 1221 | ||
---|---|---|---|
Line 27... | Line 27... | ||
27 | */ |
27 | */ |
28 | #include |
28 | #include |
29 | #include "drmP.h" |
29 | #include "drmP.h" |
30 | #include "drm.h" |
30 | #include "drm.h" |
31 | #include "radeon_drm.h" |
31 | #include "radeon_drm.h" |
32 | #include "radeon_microcode.h" |
- | |
33 | #include "radeon_reg.h" |
32 | #include "radeon_reg.h" |
34 | #include "radeon.h" |
33 | #include "radeon.h" |
35 | #include "r100d.h" |
34 | #include "r100d.h" |
- | 35 | #include "rs100d.h" |
|
- | 36 | #include "rv200d.h" |
|
- | 37 | #include "rv250d.h" |
|
- | 38 | ||
- | 39 | #include |
|
Line 36... | Line 40... | ||
36 | 40 | ||
37 | #include "r100_reg_safe.h" |
41 | #include "r100_reg_safe.h" |
- | 42 | #include "rn50_reg_safe.h" |
|
- | 43 | ||
- | 44 | /* Firmware Names */ |
|
- | 45 | #define FIRMWARE_R100 "radeon/R100_cp.bin" |
|
- | 46 | #define FIRMWARE_R200 "radeon/R200_cp.bin" |
|
- | 47 | #define FIRMWARE_R300 "radeon/R300_cp.bin" |
|
- | 48 | #define FIRMWARE_R420 "radeon/R420_cp.bin" |
|
- | 49 | #define FIRMWARE_RS690 "radeon/RS690_cp.bin" |
|
- | 50 | #define FIRMWARE_RS600 "radeon/RS600_cp.bin" |
|
- | 51 | #define FIRMWARE_R520 "radeon/R520_cp.bin" |
|
- | 52 | ||
- | 53 | MODULE_FIRMWARE(FIRMWARE_R100); |
|
- | 54 | MODULE_FIRMWARE(FIRMWARE_R200); |
|
- | 55 | MODULE_FIRMWARE(FIRMWARE_R300); |
|
- | 56 | MODULE_FIRMWARE(FIRMWARE_R420); |
|
- | 57 | MODULE_FIRMWARE(FIRMWARE_RS690); |
|
- | 58 | MODULE_FIRMWARE(FIRMWARE_RS600); |
|
- | 59 | MODULE_FIRMWARE(FIRMWARE_R520); |
|
- | 60 | ||
38 | #include "rn50_reg_safe.h" |
61 | |
39 | /* This files gather functions specifics to: |
62 | /* This files gather functions specifics to: |
40 | * r100,rv100,rs100,rv200,rs200,r200,rv250,rs300,rv280 |
- | |
41 | * |
- | |
42 | * Some of these functions might be used by newer ASICs. |
63 | * r100,rv100,rs100,rv200,rs200,r200,rv250,rs300,rv280 |
43 | */ |
- | |
44 | int r200_init(struct radeon_device *rdev); |
- | |
45 | void r100_hdp_reset(struct radeon_device *rdev); |
- | |
46 | void r100_gpu_init(struct radeon_device *rdev); |
- | |
47 | int r100_gui_wait_for_idle(struct radeon_device *rdev); |
- | |
48 | int r100_mc_wait_for_idle(struct radeon_device *rdev); |
- | |
49 | void r100_gpu_wait_for_vsync(struct radeon_device *rdev); |
- | |
50 | void r100_gpu_wait_for_vsync2(struct radeon_device *rdev); |
- | |
51 | int r100_debugfs_mc_info_init(struct radeon_device *rdev); |
- | |
Line 52... | Line 64... | ||
52 | 64 | */ |
|
53 | 65 | ||
54 | /* |
66 | /* |
55 | * PCI GART |
67 | * PCI GART |
Line 129... | Line 141... | ||
129 | radeon_gart_table_ram_free(rdev); |
141 | radeon_gart_table_ram_free(rdev); |
130 | radeon_gart_fini(rdev); |
142 | radeon_gart_fini(rdev); |
131 | } |
143 | } |
Line 132... | Line -... | ||
132 | - | ||
133 | - | ||
134 | /* |
- | |
135 | * MC |
144 | |
136 | */ |
145 | |
137 | void r100_mc_disable_clients(struct radeon_device *rdev) |
- | |
138 | { |
- | |
139 | uint32_t ov0_scale_cntl, crtc_ext_cntl, crtc_gen_cntl, crtc2_gen_cntl; |
- | |
140 | - | ||
141 | /* FIXME: is this function correct for rs100,rs200,rs300 ? */ |
- | |
142 | if (r100_gui_wait_for_idle(rdev)) { |
- | |
143 | printk(KERN_WARNING "Failed to wait GUI idle while " |
- | |
144 | "programming pipes. Bad things might happen.\n"); |
- | |
145 | } |
- | |
146 | - | ||
147 | /* stop display and memory access */ |
- | |
148 | ov0_scale_cntl = RREG32(RADEON_OV0_SCALE_CNTL); |
- | |
149 | WREG32(RADEON_OV0_SCALE_CNTL, ov0_scale_cntl & ~RADEON_SCALER_ENABLE); |
- | |
150 | crtc_ext_cntl = RREG32(RADEON_CRTC_EXT_CNTL); |
- | |
151 | WREG32(RADEON_CRTC_EXT_CNTL, crtc_ext_cntl | RADEON_CRTC_DISPLAY_DIS); |
- | |
152 | crtc_gen_cntl = RREG32(RADEON_CRTC_GEN_CNTL); |
- | |
153 | - | ||
154 | r100_gpu_wait_for_vsync(rdev); |
- | |
155 | - | ||
156 | WREG32(RADEON_CRTC_GEN_CNTL, |
- | |
157 | (crtc_gen_cntl & ~(RADEON_CRTC_CUR_EN | RADEON_CRTC_ICON_EN)) | |
- | |
158 | RADEON_CRTC_DISP_REQ_EN_B | RADEON_CRTC_EXT_DISP_EN); |
- | |
159 | - | ||
160 | if (!(rdev->flags & RADEON_SINGLE_CRTC)) { |
- | |
161 | crtc2_gen_cntl = RREG32(RADEON_CRTC2_GEN_CNTL); |
- | |
162 | - | ||
163 | r100_gpu_wait_for_vsync2(rdev); |
- | |
164 | WREG32(RADEON_CRTC2_GEN_CNTL, |
- | |
165 | (crtc2_gen_cntl & |
- | |
166 | ~(RADEON_CRTC2_CUR_EN | RADEON_CRTC2_ICON_EN)) | |
- | |
167 | RADEON_CRTC2_DISP_REQ_EN_B); |
- | |
168 | } |
- | |
169 | - | ||
170 | udelay(500); |
- | |
171 | } |
- | |
172 | - | ||
173 | void r100_mc_setup(struct radeon_device *rdev) |
146 | void r100_irq_disable(struct radeon_device *rdev) |
174 | { |
- | |
175 | uint32_t tmp; |
- | |
176 | int r; |
- | |
177 | - | ||
178 | r = r100_debugfs_mc_info_init(rdev); |
- | |
179 | if (r) { |
- | |
180 | DRM_ERROR("Failed to register debugfs file for R100 MC !\n"); |
- | |
181 | } |
- | |
182 | /* Write VRAM size in case we are limiting it */ |
- | |
183 | WREG32(RADEON_CONFIG_MEMSIZE, rdev->mc.real_vram_size); |
- | |
184 | /* Novell bug 204882 for RN50/M6/M7 with 8/16/32MB VRAM, |
- | |
185 | * if the aperture is 64MB but we have 32MB VRAM |
- | |
186 | * we report only 32MB VRAM but we have to set MC_FB_LOCATION |
- | |
187 | * to 64MB, otherwise the gpu accidentially dies */ |
- | |
188 | tmp = rdev->mc.vram_location + rdev->mc.mc_vram_size - 1; |
- | |
189 | tmp = REG_SET(RADEON_MC_FB_TOP, tmp >> 16); |
- | |
190 | tmp |= REG_SET(RADEON_MC_FB_START, rdev->mc.vram_location >> 16); |
- | |
191 | WREG32(RADEON_MC_FB_LOCATION, tmp); |
- | |
192 | - | ||
193 | /* Enable bus mastering */ |
- | |
194 | tmp = RREG32(RADEON_BUS_CNTL) & ~RADEON_BUS_MASTER_DIS; |
- | |
195 | WREG32(RADEON_BUS_CNTL, tmp); |
- | |
196 | - | ||
197 | if (rdev->flags & RADEON_IS_AGP) { |
- | |
198 | tmp = rdev->mc.gtt_location + rdev->mc.gtt_size - 1; |
- | |
199 | tmp = REG_SET(RADEON_MC_AGP_TOP, tmp >> 16); |
- | |
200 | tmp |= REG_SET(RADEON_MC_AGP_START, rdev->mc.gtt_location >> 16); |
- | |
201 | WREG32(RADEON_MC_AGP_LOCATION, tmp); |
- | |
202 | WREG32(RADEON_AGP_BASE, rdev->mc.agp_base); |
- | |
203 | } else { |
- | |
204 | WREG32(RADEON_MC_AGP_LOCATION, 0x0FFFFFFF); |
- | |
Line 205... | Line 147... | ||
205 | WREG32(RADEON_AGP_BASE, 0); |
147 | { |
- | 148 | u32 tmp; |
|
206 | } |
149 | |
207 | - | ||
208 | tmp = RREG32(RADEON_HOST_PATH_CNTL) & RADEON_HDP_APER_CNTL; |
150 | WREG32(R_000040_GEN_INT_CNTL, 0); |
209 | tmp |= (7 << 28); |
151 | /* Wait and acknowledge irq */ |
210 | WREG32(RADEON_HOST_PATH_CNTL, tmp | RADEON_HDP_SOFT_RESET | RADEON_HDP_READ_BUFFER_INVALIDATE); |
- | |
211 | (void)RREG32(RADEON_HOST_PATH_CNTL); |
152 | mdelay(1); |
Line 212... | Line 153... | ||
212 | WREG32(RADEON_HOST_PATH_CNTL, tmp); |
153 | tmp = RREG32(R_000044_GEN_INT_STATUS); |
213 | (void)RREG32(RADEON_HOST_PATH_CNTL); |
154 | WREG32(R_000044_GEN_INT_STATUS, tmp); |
214 | } |
- | |
215 | - | ||
216 | int r100_mc_init(struct radeon_device *rdev) |
155 | } |
217 | { |
156 | |
218 | int r; |
- | |
219 | - | ||
220 | if (r100_debugfs_rbbm_init(rdev)) { |
- | |
221 | DRM_ERROR("Failed to register debugfs file for RBBM !\n"); |
- | |
222 | } |
157 | static inline uint32_t r100_irq_ack(struct radeon_device *rdev) |
Line 223... | Line -... | ||
223 | - | ||
224 | r100_gpu_init(rdev); |
- | |
225 | /* Disable gart which also disable out of gart access */ |
- | |
226 | r100_pci_gart_disable(rdev); |
158 | { |
227 | 159 | uint32_t irqs = RREG32(RADEON_GEN_INT_STATUS); |
|
228 | /* Setup GPU memory space */ |
160 | uint32_t irq_mask = RADEON_SW_INT_TEST | RADEON_CRTC_VBLANK_STAT | |
229 | rdev->mc.gtt_location = 0xFFFFFFFFUL; |
- | |
230 | r = radeon_mc_setup(rdev); |
161 | RADEON_CRTC2_VBLANK_STAT; |
231 | if (r) { |
- | |
232 | return r; |
- | |
233 | } |
- | |
234 | 162 | ||
Line 235... | Line -... | ||
235 | r100_mc_disable_clients(rdev); |
- | |
236 | if (r100_mc_wait_for_idle(rdev)) { |
- | |
237 | printk(KERN_WARNING "Failed to wait MC idle while " |
- | |
238 | "programming pipes. Bad things might happen.\n"); |
- | |
239 | } |
- | |
240 | - | ||
241 | r100_mc_setup(rdev); |
- | |
Line 242... | Line -... | ||
242 | return 0; |
- | |
243 | } |
- | |
244 | - | ||
245 | void r100_mc_fini(struct radeon_device *rdev) |
- | |
246 | { |
- | |
247 | } |
- | |
248 | - | ||
Line 249... | Line -... | ||
249 | u32 r100_get_vblank_counter(struct radeon_device *rdev, int crtc) |
- | |
250 | { |
- | |
251 | if (crtc == 0) |
- | |
252 | return RREG32(RADEON_CRTC_CRNT_FRAME); |
- | |
253 | else |
163 | if (irqs) { |
254 | return RREG32(RADEON_CRTC2_CRNT_FRAME); |
164 | WREG32(RADEON_GEN_INT_STATUS, irqs); |
255 | } |
165 | } |
256 | 166 | return irqs & irq_mask; |
|
257 | 167 | } |
|
Line 400... | Line 310... | ||
400 | return r; |
310 | return r; |
401 | } |
311 | } |
Line 402... | Line 312... | ||
402 | 312 | ||
Line 403... | Line 313... | ||
403 | #endif |
313 | #endif |
404 | - | ||
405 | /* |
- | |
406 | * CP |
314 | |
407 | */ |
315 | |
408 | static int r100_cp_wait_for_idle(struct radeon_device *rdev) |
316 | static int r100_cp_wait_for_idle(struct radeon_device *rdev) |
409 | { |
317 | { |
Line 435... | Line 343... | ||
435 | RADEON_ISYNC_WAIT_IDLEGUI | |
343 | RADEON_ISYNC_WAIT_IDLEGUI | |
436 | RADEON_ISYNC_CPSCRATCH_IDLEGUI); |
344 | RADEON_ISYNC_CPSCRATCH_IDLEGUI); |
437 | radeon_ring_unlock_commit(rdev); |
345 | radeon_ring_unlock_commit(rdev); |
438 | } |
346 | } |
Line 439... | Line -... | ||
439 | - | ||
440 | static void r100_cp_load_microcode(struct radeon_device *rdev) |
- | |
441 | { |
- | |
442 | int i; |
- | |
443 | - | ||
444 | if (r100_gui_wait_for_idle(rdev)) { |
- | |
445 | printk(KERN_WARNING "Failed to wait GUI idle while " |
- | |
446 | "programming pipes. Bad things might happen.\n"); |
- | |
Line -... | Line 347... | ||
- | 347 | ||
- | 348 | ||
- | 349 | /* Load the microcode for the CP */ |
|
447 | } |
350 | static int r100_cp_init_microcode(struct radeon_device *rdev) |
- | 351 | { |
|
- | 352 | struct platform_device *pdev; |
|
- | 353 | const char *fw_name = NULL; |
|
- | 354 | int err; |
|
- | 355 | ||
- | 356 | DRM_DEBUG("\n"); |
|
- | 357 | ||
- | 358 | // pdev = platform_device_register_simple("radeon_cp", 0, NULL, 0); |
|
- | 359 | // err = IS_ERR(pdev); |
|
- | 360 | // if (err) { |
|
- | 361 | // printk(KERN_ERR "radeon_cp: Failed to register firmware\n"); |
|
448 | 362 | // return -EINVAL; |
|
449 | WREG32(RADEON_CP_ME_RAM_ADDR, 0); |
363 | // } |
450 | if ((rdev->family == CHIP_R100) || (rdev->family == CHIP_RV100) || |
364 | if ((rdev->family == CHIP_R100) || (rdev->family == CHIP_RV100) || |
451 | (rdev->family == CHIP_RV200) || (rdev->family == CHIP_RS100) || |
365 | (rdev->family == CHIP_RV200) || (rdev->family == CHIP_RS100) || |
452 | (rdev->family == CHIP_RS200)) { |
366 | (rdev->family == CHIP_RS200)) { |
453 | DRM_INFO("Loading R100 Microcode\n"); |
- | |
454 | for (i = 0; i < 256; i++) { |
- | |
455 | WREG32(RADEON_CP_ME_RAM_DATAH, R100_cp_microcode[i][1]); |
- | |
456 | WREG32(RADEON_CP_ME_RAM_DATAL, R100_cp_microcode[i][0]); |
367 | DRM_INFO("Loading R100 Microcode\n"); |
457 | } |
368 | fw_name = FIRMWARE_R100; |
458 | } else if ((rdev->family == CHIP_R200) || |
369 | } else if ((rdev->family == CHIP_R200) || |
459 | (rdev->family == CHIP_RV250) || |
370 | (rdev->family == CHIP_RV250) || |
460 | (rdev->family == CHIP_RV280) || |
371 | (rdev->family == CHIP_RV280) || |
461 | (rdev->family == CHIP_RS300)) { |
372 | (rdev->family == CHIP_RS300)) { |
462 | DRM_INFO("Loading R200 Microcode\n"); |
- | |
463 | for (i = 0; i < 256; i++) { |
- | |
464 | WREG32(RADEON_CP_ME_RAM_DATAH, R200_cp_microcode[i][1]); |
- | |
465 | WREG32(RADEON_CP_ME_RAM_DATAL, R200_cp_microcode[i][0]); |
373 | DRM_INFO("Loading R200 Microcode\n"); |
466 | } |
374 | fw_name = FIRMWARE_R200; |
467 | } else if ((rdev->family == CHIP_R300) || |
375 | } else if ((rdev->family == CHIP_R300) || |
468 | (rdev->family == CHIP_R350) || |
376 | (rdev->family == CHIP_R350) || |
469 | (rdev->family == CHIP_RV350) || |
377 | (rdev->family == CHIP_RV350) || |
470 | (rdev->family == CHIP_RV380) || |
378 | (rdev->family == CHIP_RV380) || |
471 | (rdev->family == CHIP_RS400) || |
379 | (rdev->family == CHIP_RS400) || |
472 | (rdev->family == CHIP_RS480)) { |
380 | (rdev->family == CHIP_RS480)) { |
473 | DRM_INFO("Loading R300 Microcode\n"); |
- | |
474 | for (i = 0; i < 256; i++) { |
- | |
475 | WREG32(RADEON_CP_ME_RAM_DATAH, R300_cp_microcode[i][1]); |
- | |
476 | WREG32(RADEON_CP_ME_RAM_DATAL, R300_cp_microcode[i][0]); |
381 | DRM_INFO("Loading R300 Microcode\n"); |
477 | } |
382 | fw_name = FIRMWARE_R300; |
478 | } else if ((rdev->family == CHIP_R420) || |
383 | } else if ((rdev->family == CHIP_R420) || |
479 | (rdev->family == CHIP_R423) || |
384 | (rdev->family == CHIP_R423) || |
480 | (rdev->family == CHIP_RV410)) { |
385 | (rdev->family == CHIP_RV410)) { |
481 | DRM_INFO("Loading R400 Microcode\n"); |
- | |
482 | for (i = 0; i < 256; i++) { |
- | |
483 | WREG32(RADEON_CP_ME_RAM_DATAH, R420_cp_microcode[i][1]); |
- | |
484 | WREG32(RADEON_CP_ME_RAM_DATAL, R420_cp_microcode[i][0]); |
386 | DRM_INFO("Loading R400 Microcode\n"); |
485 | } |
387 | fw_name = FIRMWARE_R420; |
486 | } else if ((rdev->family == CHIP_RS690) || |
388 | } else if ((rdev->family == CHIP_RS690) || |
487 | (rdev->family == CHIP_RS740)) { |
389 | (rdev->family == CHIP_RS740)) { |
488 | DRM_INFO("Loading RS690/RS740 Microcode\n"); |
- | |
489 | for (i = 0; i < 256; i++) { |
- | |
490 | WREG32(RADEON_CP_ME_RAM_DATAH, RS690_cp_microcode[i][1]); |
- | |
491 | WREG32(RADEON_CP_ME_RAM_DATAL, RS690_cp_microcode[i][0]); |
390 | DRM_INFO("Loading RS690/RS740 Microcode\n"); |
492 | } |
391 | fw_name = FIRMWARE_RS690; |
493 | } else if (rdev->family == CHIP_RS600) { |
392 | } else if (rdev->family == CHIP_RS600) { |
494 | DRM_INFO("Loading RS600 Microcode\n"); |
- | |
495 | for (i = 0; i < 256; i++) { |
- | |
496 | WREG32(RADEON_CP_ME_RAM_DATAH, RS600_cp_microcode[i][1]); |
- | |
497 | WREG32(RADEON_CP_ME_RAM_DATAL, RS600_cp_microcode[i][0]); |
393 | DRM_INFO("Loading RS600 Microcode\n"); |
498 | } |
394 | fw_name = FIRMWARE_RS600; |
499 | } else if ((rdev->family == CHIP_RV515) || |
395 | } else if ((rdev->family == CHIP_RV515) || |
500 | (rdev->family == CHIP_R520) || |
396 | (rdev->family == CHIP_R520) || |
501 | (rdev->family == CHIP_RV530) || |
397 | (rdev->family == CHIP_RV530) || |
502 | (rdev->family == CHIP_R580) || |
398 | (rdev->family == CHIP_R580) || |
503 | (rdev->family == CHIP_RV560) || |
399 | (rdev->family == CHIP_RV560) || |
504 | (rdev->family == CHIP_RV570)) { |
400 | (rdev->family == CHIP_RV570)) { |
505 | DRM_INFO("Loading R500 Microcode\n"); |
- | |
506 | for (i = 0; i < 256; i++) { |
- | |
507 | WREG32(RADEON_CP_ME_RAM_DATAH, R520_cp_microcode[i][1]); |
401 | DRM_INFO("Loading R500 Microcode\n"); |
- | 402 | fw_name = FIRMWARE_R520; |
|
- | 403 | } |
|
- | 404 | ||
- | 405 | // err = request_firmware(&rdev->me_fw, fw_name, &pdev->dev); |
|
- | 406 | // platform_device_unregister(pdev); |
|
- | 407 | if (err) { |
|
- | 408 | printk(KERN_ERR "radeon_cp: Failed to load firmware \"%s\"\n", |
|
- | 409 | fw_name); |
|
- | 410 | } else if (rdev->me_fw->size % 8) { |
|
- | 411 | printk(KERN_ERR |
|
- | 412 | "radeon_cp: Bogus length %zu in firmware \"%s\"\n", |
|
- | 413 | rdev->me_fw->size, fw_name); |
|
- | 414 | err = -EINVAL; |
|
508 | WREG32(RADEON_CP_ME_RAM_DATAL, R520_cp_microcode[i][0]); |
415 | release_firmware(rdev->me_fw); |
- | 416 | rdev->me_fw = NULL; |
|
509 | } |
417 | } |
Line 510... | Line 418... | ||
510 | } |
418 | return err; |
511 | } |
419 | } |
- | 420 | ||
- | 421 | static inline __u32 __swab32(__u32 x) |
|
- | 422 | { |
|
512 | 423 | asm("bswapl %0" : |
|
- | 424 | "=&r" (x) |
|
- | 425 | :"r" (x)); |
|
- | 426 | return x; |
|
- | 427 | } |
|
- | 428 | ||
- | 429 | static inline __u32 be32_to_cpup(const __be32 *p) |
|
- | 430 | { |
|
- | 431 | return __swab32(*(__u32 *)p); |
|
- | 432 | } |
|
- | 433 | ||
- | 434 | ||
- | 435 | static void r100_cp_load_microcode(struct radeon_device *rdev) |
|
- | 436 | { |
|
- | 437 | const __be32 *fw_data; |
|
- | 438 | int i, size; |
|
- | 439 | ||
513 | static int r100_cp_init_microcode(struct radeon_device *rdev) |
440 | if (r100_gui_wait_for_idle(rdev)) { |
Line -... | Line 441... | ||
- | 441 | printk(KERN_WARNING "Failed to wait GUI idle while " |
|
- | 442 | "programming pipes. Bad things might happen.\n"); |
|
- | 443 | } |
|
- | 444 | ||
- | 445 | if (rdev->me_fw) { |
|
- | 446 | size = rdev->me_fw->size / 4; |
|
- | 447 | fw_data = (const __be32 *)&rdev->me_fw->data[0]; |
|
- | 448 | WREG32(RADEON_CP_ME_RAM_ADDR, 0); |
|
- | 449 | for (i = 0; i < size; i += 2) { |
|
- | 450 | WREG32(RADEON_CP_ME_RAM_DATAH, |
|
- | 451 | be32_to_cpup(&fw_data[i])); |
|
- | 452 | WREG32(RADEON_CP_ME_RAM_DATAL, |
|
Line 514... | Line 453... | ||
514 | { |
453 | be32_to_cpup(&fw_data[i + 1])); |
515 | return 0; |
454 | } |
516 | } |
455 | } |
517 | 456 | } |
|
Line 745... | Line 684... | ||
745 | } |
684 | } |
Line 746... | Line 685... | ||
746 | 685 | ||
747 | void r100_cs_dump_packet(struct radeon_cs_parser *p, |
686 | void r100_cs_dump_packet(struct radeon_cs_parser *p, |
748 | struct radeon_cs_packet *pkt) |
687 | struct radeon_cs_packet *pkt) |
749 | { |
- | |
750 | struct radeon_cs_chunk *ib_chunk; |
688 | { |
751 | volatile uint32_t *ib; |
689 | volatile uint32_t *ib; |
752 | unsigned i; |
690 | unsigned i; |
Line 753... | Line 691... | ||
753 | unsigned idx; |
691 | unsigned idx; |
754 | - | ||
755 | ib = p->ib->ptr; |
692 | |
756 | ib_chunk = &p->chunks[p->chunk_ib_idx]; |
693 | ib = p->ib->ptr; |
757 | idx = pkt->idx; |
694 | idx = pkt->idx; |
758 | for (i = 0; i <= (pkt->count + 1); i++, idx++) { |
695 | for (i = 0; i <= (pkt->count + 1); i++, idx++) { |
759 | DRM_INFO("ib[%d]=0x%08X\n", idx, ib[idx]); |
696 | DRM_INFO("ib[%d]=0x%08X\n", idx, ib[idx]); |
Line 778... | Line 715... | ||
778 | if (idx >= ib_chunk->length_dw) { |
715 | if (idx >= ib_chunk->length_dw) { |
779 | DRM_ERROR("Can not parse packet at %d after CS end %d !\n", |
716 | DRM_ERROR("Can not parse packet at %d after CS end %d !\n", |
780 | idx, ib_chunk->length_dw); |
717 | idx, ib_chunk->length_dw); |
781 | return -EINVAL; |
718 | return -EINVAL; |
782 | } |
719 | } |
783 | header = ib_chunk->kdata[idx]; |
720 | header = radeon_get_ib_value(p, idx); |
784 | pkt->idx = idx; |
721 | pkt->idx = idx; |
785 | pkt->type = CP_PACKET_GET_TYPE(header); |
722 | pkt->type = CP_PACKET_GET_TYPE(header); |
786 | pkt->count = CP_PACKET_GET_COUNT(header); |
723 | pkt->count = CP_PACKET_GET_COUNT(header); |
787 | switch (pkt->type) { |
724 | switch (pkt->type) { |
788 | case PACKET_TYPE0: |
725 | case PACKET_TYPE0: |
Line 821... | Line 758... | ||
821 | * It also detects a switched off crtc and nulls out the |
758 | * It also detects a switched off crtc and nulls out the |
822 | * wait in that case. |
759 | * wait in that case. |
823 | */ |
760 | */ |
824 | int r100_cs_packet_parse_vline(struct radeon_cs_parser *p) |
761 | int r100_cs_packet_parse_vline(struct radeon_cs_parser *p) |
825 | { |
762 | { |
826 | struct radeon_cs_chunk *ib_chunk; |
- | |
827 | struct drm_mode_object *obj; |
763 | struct drm_mode_object *obj; |
828 | struct drm_crtc *crtc; |
764 | struct drm_crtc *crtc; |
829 | struct radeon_crtc *radeon_crtc; |
765 | struct radeon_crtc *radeon_crtc; |
830 | struct radeon_cs_packet p3reloc, waitreloc; |
766 | struct radeon_cs_packet p3reloc, waitreloc; |
831 | int crtc_id; |
767 | int crtc_id; |
832 | int r; |
768 | int r; |
833 | uint32_t header, h_idx, reg; |
769 | uint32_t header, h_idx, reg; |
- | 770 | volatile uint32_t *ib; |
|
Line 834... | Line 771... | ||
834 | 771 | ||
Line 835... | Line 772... | ||
835 | ib_chunk = &p->chunks[p->chunk_ib_idx]; |
772 | ib = p->ib->ptr; |
836 | 773 | ||
837 | /* parse the wait until */ |
774 | /* parse the wait until */ |
838 | r = r100_cs_packet_parse(p, &waitreloc, p->idx); |
775 | r = r100_cs_packet_parse(p, &waitreloc, p->idx); |
Line 845... | Line 782... | ||
845 | DRM_ERROR("vline wait had illegal wait until segment\n"); |
782 | DRM_ERROR("vline wait had illegal wait until segment\n"); |
846 | r = -EINVAL; |
783 | r = -EINVAL; |
847 | return r; |
784 | return r; |
848 | } |
785 | } |
Line 849... | Line 786... | ||
849 | 786 | ||
850 | if (ib_chunk->kdata[waitreloc.idx + 1] != RADEON_WAIT_CRTC_VLINE) { |
787 | if (radeon_get_ib_value(p, waitreloc.idx + 1) != RADEON_WAIT_CRTC_VLINE) { |
851 | DRM_ERROR("vline wait had illegal wait until\n"); |
788 | DRM_ERROR("vline wait had illegal wait until\n"); |
852 | r = -EINVAL; |
789 | r = -EINVAL; |
853 | return r; |
790 | return r; |
Line 854... | Line 791... | ||
854 | } |
791 | } |
855 | 792 | ||
856 | /* jump over the NOP */ |
793 | /* jump over the NOP */ |
857 | r = r100_cs_packet_parse(p, &p3reloc, p->idx); |
794 | r = r100_cs_packet_parse(p, &p3reloc, p->idx + waitreloc.count + 2); |
Line 858... | Line 795... | ||
858 | if (r) |
795 | if (r) |
859 | return r; |
796 | return r; |
860 | 797 | ||
Line 861... | Line 798... | ||
861 | h_idx = p->idx - 2; |
798 | h_idx = p->idx - 2; |
862 | p->idx += waitreloc.count; |
799 | p->idx += waitreloc.count + 2; |
863 | p->idx += p3reloc.count; |
800 | p->idx += p3reloc.count + 2; |
864 | 801 | ||
865 | header = ib_chunk->kdata[h_idx]; |
802 | header = radeon_get_ib_value(p, h_idx); |
866 | crtc_id = ib_chunk->kdata[h_idx + 5]; |
803 | crtc_id = radeon_get_ib_value(p, h_idx + 5); |
867 | reg = ib_chunk->kdata[h_idx] >> 2; |
804 | reg = CP_PACKET0_GET_REG(header); |
868 | mutex_lock(&p->rdev->ddev->mode_config.mutex); |
805 | mutex_lock(&p->rdev->ddev->mode_config.mutex); |
Line 876... | Line 813... | ||
876 | radeon_crtc = to_radeon_crtc(crtc); |
813 | radeon_crtc = to_radeon_crtc(crtc); |
877 | crtc_id = radeon_crtc->crtc_id; |
814 | crtc_id = radeon_crtc->crtc_id; |
Line 878... | Line 815... | ||
878 | 815 | ||
879 | if (!crtc->enabled) { |
816 | if (!crtc->enabled) { |
880 | /* if the CRTC isn't enabled - we need to nop out the wait until */ |
817 | /* if the CRTC isn't enabled - we need to nop out the wait until */ |
881 | ib_chunk->kdata[h_idx + 2] = PACKET2(0); |
818 | ib[h_idx + 2] = PACKET2(0); |
882 | ib_chunk->kdata[h_idx + 3] = PACKET2(0); |
819 | ib[h_idx + 3] = PACKET2(0); |
883 | } else if (crtc_id == 1) { |
820 | } else if (crtc_id == 1) { |
884 | switch (reg) { |
821 | switch (reg) { |
885 | case AVIVO_D1MODE_VLINE_START_END: |
822 | case AVIVO_D1MODE_VLINE_START_END: |
886 | header &= R300_CP_PACKET0_REG_MASK; |
823 | header &= ~R300_CP_PACKET0_REG_MASK; |
887 | header |= AVIVO_D2MODE_VLINE_START_END >> 2; |
824 | header |= AVIVO_D2MODE_VLINE_START_END >> 2; |
888 | break; |
825 | break; |
889 | case RADEON_CRTC_GUI_TRIG_VLINE: |
826 | case RADEON_CRTC_GUI_TRIG_VLINE: |
890 | header &= R300_CP_PACKET0_REG_MASK; |
827 | header &= ~R300_CP_PACKET0_REG_MASK; |
891 | header |= RADEON_CRTC2_GUI_TRIG_VLINE >> 2; |
828 | header |= RADEON_CRTC2_GUI_TRIG_VLINE >> 2; |
892 | break; |
829 | break; |
893 | default: |
830 | default: |
894 | DRM_ERROR("unknown crtc reloc\n"); |
831 | DRM_ERROR("unknown crtc reloc\n"); |
895 | r = -EINVAL; |
832 | r = -EINVAL; |
896 | goto out; |
833 | goto out; |
897 | } |
834 | } |
898 | ib_chunk->kdata[h_idx] = header; |
835 | ib[h_idx] = header; |
899 | ib_chunk->kdata[h_idx + 3] |= RADEON_ENG_DISPLAY_SELECT_CRTC1; |
836 | ib[h_idx + 3] |= RADEON_ENG_DISPLAY_SELECT_CRTC1; |
900 | } |
837 | } |
901 | out: |
838 | out: |
902 | mutex_unlock(&p->rdev->ddev->mode_config.mutex); |
839 | mutex_unlock(&p->rdev->ddev->mode_config.mutex); |
903 | return r; |
840 | return r; |
Line 915... | Line 852... | ||
915 | * GPU offset using the provided start. |
852 | * GPU offset using the provided start. |
916 | **/ |
853 | **/ |
917 | int r100_cs_packet_next_reloc(struct radeon_cs_parser *p, |
854 | int r100_cs_packet_next_reloc(struct radeon_cs_parser *p, |
918 | struct radeon_cs_reloc **cs_reloc) |
855 | struct radeon_cs_reloc **cs_reloc) |
919 | { |
856 | { |
920 | struct radeon_cs_chunk *ib_chunk; |
- | |
921 | struct radeon_cs_chunk *relocs_chunk; |
857 | struct radeon_cs_chunk *relocs_chunk; |
922 | struct radeon_cs_packet p3reloc; |
858 | struct radeon_cs_packet p3reloc; |
923 | unsigned idx; |
859 | unsigned idx; |
924 | int r; |
860 | int r; |
Line 925... | Line 861... | ||
925 | 861 | ||
926 | if (p->chunk_relocs_idx == -1) { |
862 | if (p->chunk_relocs_idx == -1) { |
927 | DRM_ERROR("No relocation chunk !\n"); |
863 | DRM_ERROR("No relocation chunk !\n"); |
928 | return -EINVAL; |
864 | return -EINVAL; |
929 | } |
865 | } |
930 | *cs_reloc = NULL; |
- | |
931 | ib_chunk = &p->chunks[p->chunk_ib_idx]; |
866 | *cs_reloc = NULL; |
932 | relocs_chunk = &p->chunks[p->chunk_relocs_idx]; |
867 | relocs_chunk = &p->chunks[p->chunk_relocs_idx]; |
933 | r = r100_cs_packet_parse(p, &p3reloc, p->idx); |
868 | r = r100_cs_packet_parse(p, &p3reloc, p->idx); |
934 | if (r) { |
869 | if (r) { |
935 | return r; |
870 | return r; |
Line 939... | Line 874... | ||
939 | DRM_ERROR("No packet3 for relocation for packet at %d.\n", |
874 | DRM_ERROR("No packet3 for relocation for packet at %d.\n", |
940 | p3reloc.idx); |
875 | p3reloc.idx); |
941 | r100_cs_dump_packet(p, &p3reloc); |
876 | r100_cs_dump_packet(p, &p3reloc); |
942 | return -EINVAL; |
877 | return -EINVAL; |
943 | } |
878 | } |
944 | idx = ib_chunk->kdata[p3reloc.idx + 1]; |
879 | idx = radeon_get_ib_value(p, p3reloc.idx + 1); |
945 | if (idx >= relocs_chunk->length_dw) { |
880 | if (idx >= relocs_chunk->length_dw) { |
946 | DRM_ERROR("Relocs at %d after relocations chunk end %d !\n", |
881 | DRM_ERROR("Relocs at %d after relocations chunk end %d !\n", |
947 | idx, relocs_chunk->length_dw); |
882 | idx, relocs_chunk->length_dw); |
948 | r100_cs_dump_packet(p, &p3reloc); |
883 | r100_cs_dump_packet(p, &p3reloc); |
949 | return -EINVAL; |
884 | return -EINVAL; |
Line 1008... | Line 943... | ||
1008 | 943 | ||
1009 | static int r100_packet0_check(struct radeon_cs_parser *p, |
944 | static int r100_packet0_check(struct radeon_cs_parser *p, |
1010 | struct radeon_cs_packet *pkt, |
945 | struct radeon_cs_packet *pkt, |
1011 | unsigned idx, unsigned reg) |
946 | unsigned idx, unsigned reg) |
1012 | { |
- | |
1013 | struct radeon_cs_chunk *ib_chunk; |
947 | { |
1014 | struct radeon_cs_reloc *reloc; |
948 | struct radeon_cs_reloc *reloc; |
1015 | struct r100_cs_track *track; |
949 | struct r100_cs_track *track; |
1016 | volatile uint32_t *ib; |
950 | volatile uint32_t *ib; |
1017 | uint32_t tmp; |
951 | uint32_t tmp; |
1018 | int r; |
952 | int r; |
1019 | int i, face; |
953 | int i, face; |
- | 954 | u32 tile_flags = 0; |
|
Line 1020... | Line 955... | ||
1020 | u32 tile_flags = 0; |
955 | u32 idx_value; |
1021 | - | ||
1022 | ib = p->ib->ptr; |
956 | |
Line -... | Line 957... | ||
- | 957 | ib = p->ib->ptr; |
|
- | 958 | track = (struct r100_cs_track *)p->track; |
|
1023 | ib_chunk = &p->chunks[p->chunk_ib_idx]; |
959 | |
1024 | track = (struct r100_cs_track *)p->track; |
960 | idx_value = radeon_get_ib_value(p, idx); |
1025 | 961 | ||
1026 | switch (reg) { |
962 | switch (reg) { |
1027 | case RADEON_CRTC_GUI_TRIG_VLINE: |
963 | case RADEON_CRTC_GUI_TRIG_VLINE: |
Line 1048... | Line 984... | ||
1048 | idx, reg); |
984 | idx, reg); |
1049 | r100_cs_dump_packet(p, pkt); |
985 | r100_cs_dump_packet(p, pkt); |
1050 | return r; |
986 | return r; |
1051 | } |
987 | } |
1052 | track->zb.robj = reloc->robj; |
988 | track->zb.robj = reloc->robj; |
1053 | track->zb.offset = ib_chunk->kdata[idx]; |
989 | track->zb.offset = idx_value; |
1054 | ib[idx] = ib_chunk->kdata[idx] + ((u32)reloc->lobj.gpu_offset); |
990 | ib[idx] = idx_value + ((u32)reloc->lobj.gpu_offset); |
1055 | break; |
991 | break; |
1056 | case RADEON_RB3D_COLOROFFSET: |
992 | case RADEON_RB3D_COLOROFFSET: |
1057 | r = r100_cs_packet_next_reloc(p, &reloc); |
993 | r = r100_cs_packet_next_reloc(p, &reloc); |
1058 | if (r) { |
994 | if (r) { |
1059 | DRM_ERROR("No reloc for ib[%d]=0x%04X\n", |
995 | DRM_ERROR("No reloc for ib[%d]=0x%04X\n", |
1060 | idx, reg); |
996 | idx, reg); |
1061 | r100_cs_dump_packet(p, pkt); |
997 | r100_cs_dump_packet(p, pkt); |
1062 | return r; |
998 | return r; |
1063 | } |
999 | } |
1064 | track->cb[0].robj = reloc->robj; |
1000 | track->cb[0].robj = reloc->robj; |
1065 | track->cb[0].offset = ib_chunk->kdata[idx]; |
1001 | track->cb[0].offset = idx_value; |
1066 | ib[idx] = ib_chunk->kdata[idx] + ((u32)reloc->lobj.gpu_offset); |
1002 | ib[idx] = idx_value + ((u32)reloc->lobj.gpu_offset); |
1067 | break; |
1003 | break; |
1068 | case RADEON_PP_TXOFFSET_0: |
1004 | case RADEON_PP_TXOFFSET_0: |
1069 | case RADEON_PP_TXOFFSET_1: |
1005 | case RADEON_PP_TXOFFSET_1: |
1070 | case RADEON_PP_TXOFFSET_2: |
1006 | case RADEON_PP_TXOFFSET_2: |
1071 | i = (reg - RADEON_PP_TXOFFSET_0) / 24; |
1007 | i = (reg - RADEON_PP_TXOFFSET_0) / 24; |
Line 1074... | Line 1010... | ||
1074 | DRM_ERROR("No reloc for ib[%d]=0x%04X\n", |
1010 | DRM_ERROR("No reloc for ib[%d]=0x%04X\n", |
1075 | idx, reg); |
1011 | idx, reg); |
1076 | r100_cs_dump_packet(p, pkt); |
1012 | r100_cs_dump_packet(p, pkt); |
1077 | return r; |
1013 | return r; |
1078 | } |
1014 | } |
1079 | ib[idx] = ib_chunk->kdata[idx] + ((u32)reloc->lobj.gpu_offset); |
1015 | ib[idx] = idx_value + ((u32)reloc->lobj.gpu_offset); |
1080 | track->textures[i].robj = reloc->robj; |
1016 | track->textures[i].robj = reloc->robj; |
1081 | break; |
1017 | break; |
1082 | case RADEON_PP_CUBIC_OFFSET_T0_0: |
1018 | case RADEON_PP_CUBIC_OFFSET_T0_0: |
1083 | case RADEON_PP_CUBIC_OFFSET_T0_1: |
1019 | case RADEON_PP_CUBIC_OFFSET_T0_1: |
1084 | case RADEON_PP_CUBIC_OFFSET_T0_2: |
1020 | case RADEON_PP_CUBIC_OFFSET_T0_2: |
Line 1090... | Line 1026... | ||
1090 | DRM_ERROR("No reloc for ib[%d]=0x%04X\n", |
1026 | DRM_ERROR("No reloc for ib[%d]=0x%04X\n", |
1091 | idx, reg); |
1027 | idx, reg); |
1092 | r100_cs_dump_packet(p, pkt); |
1028 | r100_cs_dump_packet(p, pkt); |
1093 | return r; |
1029 | return r; |
1094 | } |
1030 | } |
1095 | track->textures[0].cube_info[i].offset = ib_chunk->kdata[idx]; |
1031 | track->textures[0].cube_info[i].offset = idx_value; |
1096 | ib[idx] = ib_chunk->kdata[idx] + ((u32)reloc->lobj.gpu_offset); |
1032 | ib[idx] = idx_value + ((u32)reloc->lobj.gpu_offset); |
1097 | track->textures[0].cube_info[i].robj = reloc->robj; |
1033 | track->textures[0].cube_info[i].robj = reloc->robj; |
1098 | break; |
1034 | break; |
1099 | case RADEON_PP_CUBIC_OFFSET_T1_0: |
1035 | case RADEON_PP_CUBIC_OFFSET_T1_0: |
1100 | case RADEON_PP_CUBIC_OFFSET_T1_1: |
1036 | case RADEON_PP_CUBIC_OFFSET_T1_1: |
1101 | case RADEON_PP_CUBIC_OFFSET_T1_2: |
1037 | case RADEON_PP_CUBIC_OFFSET_T1_2: |
Line 1107... | Line 1043... | ||
1107 | DRM_ERROR("No reloc for ib[%d]=0x%04X\n", |
1043 | DRM_ERROR("No reloc for ib[%d]=0x%04X\n", |
1108 | idx, reg); |
1044 | idx, reg); |
1109 | r100_cs_dump_packet(p, pkt); |
1045 | r100_cs_dump_packet(p, pkt); |
1110 | return r; |
1046 | return r; |
1111 | } |
1047 | } |
1112 | track->textures[1].cube_info[i].offset = ib_chunk->kdata[idx]; |
1048 | track->textures[1].cube_info[i].offset = idx_value; |
1113 | ib[idx] = ib_chunk->kdata[idx] + ((u32)reloc->lobj.gpu_offset); |
1049 | ib[idx] = idx_value + ((u32)reloc->lobj.gpu_offset); |
1114 | track->textures[1].cube_info[i].robj = reloc->robj; |
1050 | track->textures[1].cube_info[i].robj = reloc->robj; |
1115 | break; |
1051 | break; |
1116 | case RADEON_PP_CUBIC_OFFSET_T2_0: |
1052 | case RADEON_PP_CUBIC_OFFSET_T2_0: |
1117 | case RADEON_PP_CUBIC_OFFSET_T2_1: |
1053 | case RADEON_PP_CUBIC_OFFSET_T2_1: |
1118 | case RADEON_PP_CUBIC_OFFSET_T2_2: |
1054 | case RADEON_PP_CUBIC_OFFSET_T2_2: |
Line 1124... | Line 1060... | ||
1124 | DRM_ERROR("No reloc for ib[%d]=0x%04X\n", |
1060 | DRM_ERROR("No reloc for ib[%d]=0x%04X\n", |
1125 | idx, reg); |
1061 | idx, reg); |
1126 | r100_cs_dump_packet(p, pkt); |
1062 | r100_cs_dump_packet(p, pkt); |
1127 | return r; |
1063 | return r; |
1128 | } |
1064 | } |
1129 | track->textures[2].cube_info[i].offset = ib_chunk->kdata[idx]; |
1065 | track->textures[2].cube_info[i].offset = idx_value; |
1130 | ib[idx] = ib_chunk->kdata[idx] + ((u32)reloc->lobj.gpu_offset); |
1066 | ib[idx] = idx_value + ((u32)reloc->lobj.gpu_offset); |
1131 | track->textures[2].cube_info[i].robj = reloc->robj; |
1067 | track->textures[2].cube_info[i].robj = reloc->robj; |
1132 | break; |
1068 | break; |
1133 | case RADEON_RE_WIDTH_HEIGHT: |
1069 | case RADEON_RE_WIDTH_HEIGHT: |
1134 | track->maxy = ((ib_chunk->kdata[idx] >> 16) & 0x7FF); |
1070 | track->maxy = ((idx_value >> 16) & 0x7FF); |
1135 | break; |
1071 | break; |
1136 | case RADEON_RB3D_COLORPITCH: |
1072 | case RADEON_RB3D_COLORPITCH: |
1137 | r = r100_cs_packet_next_reloc(p, &reloc); |
1073 | r = r100_cs_packet_next_reloc(p, &reloc); |
1138 | if (r) { |
1074 | if (r) { |
1139 | DRM_ERROR("No reloc for ib[%d]=0x%04X\n", |
1075 | DRM_ERROR("No reloc for ib[%d]=0x%04X\n", |
Line 1145... | Line 1081... | ||
1145 | if (reloc->lobj.tiling_flags & RADEON_TILING_MACRO) |
1081 | if (reloc->lobj.tiling_flags & RADEON_TILING_MACRO) |
1146 | tile_flags |= RADEON_COLOR_TILE_ENABLE; |
1082 | tile_flags |= RADEON_COLOR_TILE_ENABLE; |
1147 | if (reloc->lobj.tiling_flags & RADEON_TILING_MICRO) |
1083 | if (reloc->lobj.tiling_flags & RADEON_TILING_MICRO) |
1148 | tile_flags |= RADEON_COLOR_MICROTILE_ENABLE; |
1084 | tile_flags |= RADEON_COLOR_MICROTILE_ENABLE; |
Line 1149... | Line 1085... | ||
1149 | 1085 | ||
1150 | tmp = ib_chunk->kdata[idx] & ~(0x7 << 16); |
1086 | tmp = idx_value & ~(0x7 << 16); |
1151 | tmp |= tile_flags; |
1087 | tmp |= tile_flags; |
Line 1152... | Line 1088... | ||
1152 | ib[idx] = tmp; |
1088 | ib[idx] = tmp; |
1153 | 1089 | ||
1154 | track->cb[0].pitch = ib_chunk->kdata[idx] & RADEON_COLORPITCH_MASK; |
1090 | track->cb[0].pitch = idx_value & RADEON_COLORPITCH_MASK; |
1155 | break; |
1091 | break; |
1156 | case RADEON_RB3D_DEPTHPITCH: |
1092 | case RADEON_RB3D_DEPTHPITCH: |
1157 | track->zb.pitch = ib_chunk->kdata[idx] & RADEON_DEPTHPITCH_MASK; |
1093 | track->zb.pitch = idx_value & RADEON_DEPTHPITCH_MASK; |
1158 | break; |
1094 | break; |
1159 | case RADEON_RB3D_CNTL: |
1095 | case RADEON_RB3D_CNTL: |
1160 | switch ((ib_chunk->kdata[idx] >> RADEON_RB3D_COLOR_FORMAT_SHIFT) & 0x1f) { |
1096 | switch ((idx_value >> RADEON_RB3D_COLOR_FORMAT_SHIFT) & 0x1f) { |
1161 | case 7: |
1097 | case 7: |
1162 | case 8: |
1098 | case 8: |
1163 | case 9: |
1099 | case 9: |
Line 1173... | Line 1109... | ||
1173 | case 6: |
1109 | case 6: |
1174 | track->cb[0].cpp = 4; |
1110 | track->cb[0].cpp = 4; |
1175 | break; |
1111 | break; |
1176 | default: |
1112 | default: |
1177 | DRM_ERROR("Invalid color buffer format (%d) !\n", |
1113 | DRM_ERROR("Invalid color buffer format (%d) !\n", |
1178 | ((ib_chunk->kdata[idx] >> RADEON_RB3D_COLOR_FORMAT_SHIFT) & 0x1f)); |
1114 | ((idx_value >> RADEON_RB3D_COLOR_FORMAT_SHIFT) & 0x1f)); |
1179 | return -EINVAL; |
1115 | return -EINVAL; |
1180 | } |
1116 | } |
1181 | track->z_enabled = !!(ib_chunk->kdata[idx] & RADEON_Z_ENABLE); |
1117 | track->z_enabled = !!(idx_value & RADEON_Z_ENABLE); |
1182 | break; |
1118 | break; |
1183 | case RADEON_RB3D_ZSTENCILCNTL: |
1119 | case RADEON_RB3D_ZSTENCILCNTL: |
1184 | switch (ib_chunk->kdata[idx] & 0xf) { |
1120 | switch (idx_value & 0xf) { |
1185 | case 0: |
1121 | case 0: |
1186 | track->zb.cpp = 2; |
1122 | track->zb.cpp = 2; |
1187 | break; |
1123 | break; |
1188 | case 2: |
1124 | case 2: |
1189 | case 3: |
1125 | case 3: |
Line 1203... | Line 1139... | ||
1203 | DRM_ERROR("No reloc for ib[%d]=0x%04X\n", |
1139 | DRM_ERROR("No reloc for ib[%d]=0x%04X\n", |
1204 | idx, reg); |
1140 | idx, reg); |
1205 | r100_cs_dump_packet(p, pkt); |
1141 | r100_cs_dump_packet(p, pkt); |
1206 | return r; |
1142 | return r; |
1207 | } |
1143 | } |
1208 | ib[idx] = ib_chunk->kdata[idx] + ((u32)reloc->lobj.gpu_offset); |
1144 | ib[idx] = idx_value + ((u32)reloc->lobj.gpu_offset); |
1209 | break; |
1145 | break; |
1210 | case RADEON_PP_CNTL: |
1146 | case RADEON_PP_CNTL: |
1211 | { |
1147 | { |
1212 | uint32_t temp = ib_chunk->kdata[idx] >> 4; |
1148 | uint32_t temp = idx_value >> 4; |
1213 | for (i = 0; i < track->num_texture; i++) |
1149 | for (i = 0; i < track->num_texture; i++) |
1214 | track->textures[i].enabled = !!(temp & (1 << i)); |
1150 | track->textures[i].enabled = !!(temp & (1 << i)); |
1215 | } |
1151 | } |
1216 | break; |
1152 | break; |
1217 | case RADEON_SE_VF_CNTL: |
1153 | case RADEON_SE_VF_CNTL: |
1218 | track->vap_vf_cntl = ib_chunk->kdata[idx]; |
1154 | track->vap_vf_cntl = idx_value; |
1219 | break; |
1155 | break; |
1220 | case RADEON_SE_VTX_FMT: |
1156 | case RADEON_SE_VTX_FMT: |
1221 | track->vtx_size = r100_get_vtx_size(ib_chunk->kdata[idx]); |
1157 | track->vtx_size = r100_get_vtx_size(idx_value); |
1222 | break; |
1158 | break; |
1223 | case RADEON_PP_TEX_SIZE_0: |
1159 | case RADEON_PP_TEX_SIZE_0: |
1224 | case RADEON_PP_TEX_SIZE_1: |
1160 | case RADEON_PP_TEX_SIZE_1: |
1225 | case RADEON_PP_TEX_SIZE_2: |
1161 | case RADEON_PP_TEX_SIZE_2: |
1226 | i = (reg - RADEON_PP_TEX_SIZE_0) / 8; |
1162 | i = (reg - RADEON_PP_TEX_SIZE_0) / 8; |
1227 | track->textures[i].width = (ib_chunk->kdata[idx] & RADEON_TEX_USIZE_MASK) + 1; |
1163 | track->textures[i].width = (idx_value & RADEON_TEX_USIZE_MASK) + 1; |
1228 | track->textures[i].height = ((ib_chunk->kdata[idx] & RADEON_TEX_VSIZE_MASK) >> RADEON_TEX_VSIZE_SHIFT) + 1; |
1164 | track->textures[i].height = ((idx_value & RADEON_TEX_VSIZE_MASK) >> RADEON_TEX_VSIZE_SHIFT) + 1; |
1229 | break; |
1165 | break; |
1230 | case RADEON_PP_TEX_PITCH_0: |
1166 | case RADEON_PP_TEX_PITCH_0: |
1231 | case RADEON_PP_TEX_PITCH_1: |
1167 | case RADEON_PP_TEX_PITCH_1: |
1232 | case RADEON_PP_TEX_PITCH_2: |
1168 | case RADEON_PP_TEX_PITCH_2: |
1233 | i = (reg - RADEON_PP_TEX_PITCH_0) / 8; |
1169 | i = (reg - RADEON_PP_TEX_PITCH_0) / 8; |
1234 | track->textures[i].pitch = ib_chunk->kdata[idx] + 32; |
1170 | track->textures[i].pitch = idx_value + 32; |
1235 | break; |
1171 | break; |
1236 | case RADEON_PP_TXFILTER_0: |
1172 | case RADEON_PP_TXFILTER_0: |
1237 | case RADEON_PP_TXFILTER_1: |
1173 | case RADEON_PP_TXFILTER_1: |
1238 | case RADEON_PP_TXFILTER_2: |
1174 | case RADEON_PP_TXFILTER_2: |
1239 | i = (reg - RADEON_PP_TXFILTER_0) / 24; |
1175 | i = (reg - RADEON_PP_TXFILTER_0) / 24; |
1240 | track->textures[i].num_levels = ((ib_chunk->kdata[idx] & RADEON_MAX_MIP_LEVEL_MASK) |
1176 | track->textures[i].num_levels = ((idx_value & RADEON_MAX_MIP_LEVEL_MASK) |
1241 | >> RADEON_MAX_MIP_LEVEL_SHIFT); |
1177 | >> RADEON_MAX_MIP_LEVEL_SHIFT); |
1242 | tmp = (ib_chunk->kdata[idx] >> 23) & 0x7; |
1178 | tmp = (idx_value >> 23) & 0x7; |
1243 | if (tmp == 2 || tmp == 6) |
1179 | if (tmp == 2 || tmp == 6) |
1244 | track->textures[i].roundup_w = false; |
1180 | track->textures[i].roundup_w = false; |
1245 | tmp = (ib_chunk->kdata[idx] >> 27) & 0x7; |
1181 | tmp = (idx_value >> 27) & 0x7; |
1246 | if (tmp == 2 || tmp == 6) |
1182 | if (tmp == 2 || tmp == 6) |
1247 | track->textures[i].roundup_h = false; |
1183 | track->textures[i].roundup_h = false; |
1248 | break; |
1184 | break; |
1249 | case RADEON_PP_TXFORMAT_0: |
1185 | case RADEON_PP_TXFORMAT_0: |
1250 | case RADEON_PP_TXFORMAT_1: |
1186 | case RADEON_PP_TXFORMAT_1: |
1251 | case RADEON_PP_TXFORMAT_2: |
1187 | case RADEON_PP_TXFORMAT_2: |
1252 | i = (reg - RADEON_PP_TXFORMAT_0) / 24; |
1188 | i = (reg - RADEON_PP_TXFORMAT_0) / 24; |
1253 | if (ib_chunk->kdata[idx] & RADEON_TXFORMAT_NON_POWER2) { |
1189 | if (idx_value & RADEON_TXFORMAT_NON_POWER2) { |
1254 | track->textures[i].use_pitch = 1; |
1190 | track->textures[i].use_pitch = 1; |
1255 | } else { |
1191 | } else { |
1256 | track->textures[i].use_pitch = 0; |
1192 | track->textures[i].use_pitch = 0; |
1257 | track->textures[i].width = 1 << ((ib_chunk->kdata[idx] >> RADEON_TXFORMAT_WIDTH_SHIFT) & RADEON_TXFORMAT_WIDTH_MASK); |
1193 | track->textures[i].width = 1 << ((idx_value >> RADEON_TXFORMAT_WIDTH_SHIFT) & RADEON_TXFORMAT_WIDTH_MASK); |
1258 | track->textures[i].height = 1 << ((ib_chunk->kdata[idx] >> RADEON_TXFORMAT_HEIGHT_SHIFT) & RADEON_TXFORMAT_HEIGHT_MASK); |
1194 | track->textures[i].height = 1 << ((idx_value >> RADEON_TXFORMAT_HEIGHT_SHIFT) & RADEON_TXFORMAT_HEIGHT_MASK); |
1259 | } |
1195 | } |
1260 | if (ib_chunk->kdata[idx] & RADEON_TXFORMAT_CUBIC_MAP_ENABLE) |
1196 | if (idx_value & RADEON_TXFORMAT_CUBIC_MAP_ENABLE) |
1261 | track->textures[i].tex_coord_type = 2; |
1197 | track->textures[i].tex_coord_type = 2; |
1262 | switch ((ib_chunk->kdata[idx] & RADEON_TXFORMAT_FORMAT_MASK)) { |
1198 | switch ((idx_value & RADEON_TXFORMAT_FORMAT_MASK)) { |
1263 | case RADEON_TXFORMAT_I8: |
1199 | case RADEON_TXFORMAT_I8: |
1264 | case RADEON_TXFORMAT_RGB332: |
1200 | case RADEON_TXFORMAT_RGB332: |
1265 | case RADEON_TXFORMAT_Y8: |
1201 | case RADEON_TXFORMAT_Y8: |
1266 | track->textures[i].cpp = 1; |
1202 | track->textures[i].cpp = 1; |
1267 | break; |
1203 | break; |
Line 1284... | Line 1220... | ||
1284 | case RADEON_TXFORMAT_SHADOW32: |
1220 | case RADEON_TXFORMAT_SHADOW32: |
1285 | case RADEON_TXFORMAT_LDUDUV8888: |
1221 | case RADEON_TXFORMAT_LDUDUV8888: |
1286 | track->textures[i].cpp = 4; |
1222 | track->textures[i].cpp = 4; |
1287 | break; |
1223 | break; |
1288 | } |
1224 | } |
1289 | track->textures[i].cube_info[4].width = 1 << ((ib_chunk->kdata[idx] >> 16) & 0xf); |
1225 | track->textures[i].cube_info[4].width = 1 << ((idx_value >> 16) & 0xf); |
1290 | track->textures[i].cube_info[4].height = 1 << ((ib_chunk->kdata[idx] >> 20) & 0xf); |
1226 | track->textures[i].cube_info[4].height = 1 << ((idx_value >> 20) & 0xf); |
1291 | break; |
1227 | break; |
1292 | case RADEON_PP_CUBIC_FACES_0: |
1228 | case RADEON_PP_CUBIC_FACES_0: |
1293 | case RADEON_PP_CUBIC_FACES_1: |
1229 | case RADEON_PP_CUBIC_FACES_1: |
1294 | case RADEON_PP_CUBIC_FACES_2: |
1230 | case RADEON_PP_CUBIC_FACES_2: |
1295 | tmp = ib_chunk->kdata[idx]; |
1231 | tmp = idx_value; |
1296 | i = (reg - RADEON_PP_CUBIC_FACES_0) / 4; |
1232 | i = (reg - RADEON_PP_CUBIC_FACES_0) / 4; |
1297 | for (face = 0; face < 4; face++) { |
1233 | for (face = 0; face < 4; face++) { |
1298 | track->textures[i].cube_info[face].width = 1 << ((tmp >> (face * 8)) & 0xf); |
1234 | track->textures[i].cube_info[face].width = 1 << ((tmp >> (face * 8)) & 0xf); |
1299 | track->textures[i].cube_info[face].height = 1 << ((tmp >> ((face * 8) + 4)) & 0xf); |
1235 | track->textures[i].cube_info[face].height = 1 << ((tmp >> ((face * 8) + 4)) & 0xf); |
1300 | } |
1236 | } |
Line 1309... | Line 1245... | ||
1309 | 1245 | ||
1310 | int r100_cs_track_check_pkt3_indx_buffer(struct radeon_cs_parser *p, |
1246 | int r100_cs_track_check_pkt3_indx_buffer(struct radeon_cs_parser *p, |
1311 | struct radeon_cs_packet *pkt, |
1247 | struct radeon_cs_packet *pkt, |
1312 | struct radeon_object *robj) |
1248 | struct radeon_object *robj) |
1313 | { |
- | |
1314 | struct radeon_cs_chunk *ib_chunk; |
1249 | { |
1315 | unsigned idx; |
- | |
1316 | 1250 | unsigned idx; |
|
1317 | ib_chunk = &p->chunks[p->chunk_ib_idx]; |
1251 | u32 value; |
- | 1252 | idx = pkt->idx + 1; |
|
1318 | idx = pkt->idx + 1; |
1253 | value = radeon_get_ib_value(p, idx + 2); |
1319 | if ((ib_chunk->kdata[idx+2] + 1) > radeon_object_size(robj)) { |
1254 | if ((value + 1) > radeon_object_size(robj)) { |
1320 | DRM_ERROR("[drm] Buffer too small for PACKET3 INDX_BUFFER " |
1255 | DRM_ERROR("[drm] Buffer too small for PACKET3 INDX_BUFFER " |
1321 | "(need %u have %lu) !\n", |
1256 | "(need %u have %lu) !\n", |
1322 | ib_chunk->kdata[idx+2] + 1, |
1257 | value + 1, |
1323 | radeon_object_size(robj)); |
1258 | radeon_object_size(robj)); |
1324 | return -EINVAL; |
1259 | return -EINVAL; |
1325 | } |
1260 | } |
1326 | return 0; |
1261 | return 0; |
Line 1327... | Line 1262... | ||
1327 | } |
1262 | } |
1328 | 1263 | ||
1329 | static int r100_packet3_check(struct radeon_cs_parser *p, |
1264 | static int r100_packet3_check(struct radeon_cs_parser *p, |
1330 | struct radeon_cs_packet *pkt) |
- | |
1331 | { |
1265 | struct radeon_cs_packet *pkt) |
1332 | struct radeon_cs_chunk *ib_chunk; |
1266 | { |
1333 | struct radeon_cs_reloc *reloc; |
1267 | struct radeon_cs_reloc *reloc; |
1334 | struct r100_cs_track *track; |
- | |
1335 | unsigned idx; |
1268 | struct r100_cs_track *track; |
1336 | unsigned i, c; |
1269 | unsigned idx; |
Line 1337... | Line 1270... | ||
1337 | volatile uint32_t *ib; |
1270 | volatile uint32_t *ib; |
1338 | int r; |
- | |
1339 | 1271 | int r; |
|
1340 | ib = p->ib->ptr; |
1272 | |
1341 | ib_chunk = &p->chunks[p->chunk_ib_idx]; |
1273 | ib = p->ib->ptr; |
1342 | idx = pkt->idx + 1; |
1274 | idx = pkt->idx + 1; |
1343 | track = (struct r100_cs_track *)p->track; |
- | |
1344 | switch (pkt->opcode) { |
- | |
1345 | case PACKET3_3D_LOAD_VBPNTR: |
- | |
1346 | c = ib_chunk->kdata[idx++]; |
1275 | track = (struct r100_cs_track *)p->track; |
1347 | track->num_arrays = c; |
- | |
1348 | for (i = 0; i < (c - 1); i += 2, idx += 3) { |
- | |
1349 | r = r100_cs_packet_next_reloc(p, &reloc); |
- | |
1350 | if (r) { |
- | |
1351 | DRM_ERROR("No reloc for packet3 %d\n", |
- | |
1352 | pkt->opcode); |
- | |
1353 | r100_cs_dump_packet(p, pkt); |
- | |
1354 | return r; |
- | |
1355 | } |
- | |
1356 | ib[idx+1] = ib_chunk->kdata[idx+1] + ((u32)reloc->lobj.gpu_offset); |
- | |
1357 | track->arrays[i + 0].robj = reloc->robj; |
- | |
1358 | track->arrays[i + 0].esize = ib_chunk->kdata[idx] >> 8; |
- | |
1359 | track->arrays[i + 0].esize &= 0x7F; |
- | |
1360 | r = r100_cs_packet_next_reloc(p, &reloc); |
- | |
1361 | if (r) { |
- | |
1362 | DRM_ERROR("No reloc for packet3 %d\n", |
- | |
1363 | pkt->opcode); |
- | |
1364 | r100_cs_dump_packet(p, pkt); |
- | |
1365 | return r; |
- | |
1366 | } |
- | |
1367 | ib[idx+2] = ib_chunk->kdata[idx+2] + ((u32)reloc->lobj.gpu_offset); |
- | |
1368 | track->arrays[i + 1].robj = reloc->robj; |
- | |
1369 | track->arrays[i + 1].esize = ib_chunk->kdata[idx] >> 24; |
- | |
1370 | track->arrays[i + 1].esize &= 0x7F; |
- | |
1371 | } |
1276 | switch (pkt->opcode) { |
1372 | if (c & 1) { |
- | |
1373 | r = r100_cs_packet_next_reloc(p, &reloc); |
- | |
1374 | if (r) { |
- | |
1375 | DRM_ERROR("No reloc for packet3 %d\n", |
1277 | case PACKET3_3D_LOAD_VBPNTR: |
1376 | pkt->opcode); |
- | |
1377 | r100_cs_dump_packet(p, pkt); |
- | |
1378 | return r; |
- | |
1379 | } |
- | |
1380 | ib[idx+1] = ib_chunk->kdata[idx+1] + ((u32)reloc->lobj.gpu_offset); |
- | |
1381 | track->arrays[i + 0].robj = reloc->robj; |
- | |
1382 | track->arrays[i + 0].esize = ib_chunk->kdata[idx] >> 8; |
1278 | r = r100_packet3_load_vbpntr(p, pkt, idx); |
1383 | track->arrays[i + 0].esize &= 0x7F; |
1279 | if (r) |
1384 | } |
1280 | return r; |
1385 | break; |
1281 | break; |
1386 | case PACKET3_INDX_BUFFER: |
1282 | case PACKET3_INDX_BUFFER: |
1387 | r = r100_cs_packet_next_reloc(p, &reloc); |
1283 | r = r100_cs_packet_next_reloc(p, &reloc); |
1388 | if (r) { |
1284 | if (r) { |
1389 | DRM_ERROR("No reloc for packet3 %d\n", pkt->opcode); |
1285 | DRM_ERROR("No reloc for packet3 %d\n", pkt->opcode); |
1390 | r100_cs_dump_packet(p, pkt); |
1286 | r100_cs_dump_packet(p, pkt); |
1391 | return r; |
1287 | return r; |
1392 | } |
1288 | } |
1393 | ib[idx+1] = ib_chunk->kdata[idx+1] + ((u32)reloc->lobj.gpu_offset); |
1289 | ib[idx+1] = radeon_get_ib_value(p, idx+1) + ((u32)reloc->lobj.gpu_offset); |
1394 | r = r100_cs_track_check_pkt3_indx_buffer(p, pkt, reloc->robj); |
1290 | r = r100_cs_track_check_pkt3_indx_buffer(p, pkt, reloc->robj); |
1395 | if (r) { |
1291 | if (r) { |
Line 1402... | Line 1298... | ||
1402 | if (r) { |
1298 | if (r) { |
1403 | DRM_ERROR("No reloc for packet3 %d\n", pkt->opcode); |
1299 | DRM_ERROR("No reloc for packet3 %d\n", pkt->opcode); |
1404 | r100_cs_dump_packet(p, pkt); |
1300 | r100_cs_dump_packet(p, pkt); |
1405 | return r; |
1301 | return r; |
1406 | } |
1302 | } |
1407 | ib[idx] = ib_chunk->kdata[idx] + ((u32)reloc->lobj.gpu_offset); |
1303 | ib[idx] = radeon_get_ib_value(p, idx) + ((u32)reloc->lobj.gpu_offset); |
1408 | track->num_arrays = 1; |
1304 | track->num_arrays = 1; |
1409 | track->vtx_size = r100_get_vtx_size(ib_chunk->kdata[idx+2]); |
1305 | track->vtx_size = r100_get_vtx_size(radeon_get_ib_value(p, idx + 2)); |
Line 1410... | Line 1306... | ||
1410 | 1306 | ||
1411 | track->arrays[0].robj = reloc->robj; |
1307 | track->arrays[0].robj = reloc->robj; |
Line 1412... | Line 1308... | ||
1412 | track->arrays[0].esize = track->vtx_size; |
1308 | track->arrays[0].esize = track->vtx_size; |
Line 1413... | Line 1309... | ||
1413 | 1309 | ||
1414 | track->max_indx = ib_chunk->kdata[idx+1]; |
1310 | track->max_indx = radeon_get_ib_value(p, idx+1); |
1415 | 1311 | ||
1416 | track->vap_vf_cntl = ib_chunk->kdata[idx+3]; |
1312 | track->vap_vf_cntl = radeon_get_ib_value(p, idx+3); |
1417 | track->immd_dwords = pkt->count - 1; |
1313 | track->immd_dwords = pkt->count - 1; |
1418 | r = r100_cs_track_check(p->rdev, track); |
1314 | r = r100_cs_track_check(p->rdev, track); |
1419 | if (r) |
1315 | if (r) |
1420 | return r; |
1316 | return r; |
1421 | break; |
1317 | break; |
1422 | case PACKET3_3D_DRAW_IMMD: |
1318 | case PACKET3_3D_DRAW_IMMD: |
1423 | if (((ib_chunk->kdata[idx+1] >> 4) & 0x3) != 3) { |
1319 | if (((radeon_get_ib_value(p, idx + 1) >> 4) & 0x3) != 3) { |
1424 | DRM_ERROR("PRIM_WALK must be 3 for IMMD draw\n"); |
1320 | DRM_ERROR("PRIM_WALK must be 3 for IMMD draw\n"); |
1425 | return -EINVAL; |
1321 | return -EINVAL; |
1426 | } |
1322 | } |
1427 | track->vap_vf_cntl = ib_chunk->kdata[idx+1]; |
1323 | track->vap_vf_cntl = radeon_get_ib_value(p, idx + 1); |
1428 | track->immd_dwords = pkt->count - 1; |
1324 | track->immd_dwords = pkt->count - 1; |
1429 | r = r100_cs_track_check(p->rdev, track); |
1325 | r = r100_cs_track_check(p->rdev, track); |
1430 | if (r) |
1326 | if (r) |
1431 | return r; |
1327 | return r; |
1432 | break; |
1328 | break; |
1433 | /* triggers drawing using in-packet vertex data */ |
1329 | /* triggers drawing using in-packet vertex data */ |
1434 | case PACKET3_3D_DRAW_IMMD_2: |
1330 | case PACKET3_3D_DRAW_IMMD_2: |
1435 | if (((ib_chunk->kdata[idx] >> 4) & 0x3) != 3) { |
1331 | if (((radeon_get_ib_value(p, idx) >> 4) & 0x3) != 3) { |
1436 | DRM_ERROR("PRIM_WALK must be 3 for IMMD draw\n"); |
1332 | DRM_ERROR("PRIM_WALK must be 3 for IMMD draw\n"); |
1437 | return -EINVAL; |
1333 | return -EINVAL; |
1438 | } |
1334 | } |
1439 | track->vap_vf_cntl = ib_chunk->kdata[idx]; |
1335 | track->vap_vf_cntl = radeon_get_ib_value(p, idx); |
1440 | track->immd_dwords = pkt->count; |
1336 | track->immd_dwords = pkt->count; |
1441 | r = r100_cs_track_check(p->rdev, track); |
1337 | r = r100_cs_track_check(p->rdev, track); |
1442 | if (r) |
1338 | if (r) |
1443 | return r; |
1339 | return r; |
1444 | break; |
1340 | break; |
1445 | /* triggers drawing using in-packet vertex data */ |
1341 | /* triggers drawing using in-packet vertex data */ |
1446 | case PACKET3_3D_DRAW_VBUF_2: |
1342 | case PACKET3_3D_DRAW_VBUF_2: |
1447 | track->vap_vf_cntl = ib_chunk->kdata[idx]; |
1343 | track->vap_vf_cntl = radeon_get_ib_value(p, idx); |
1448 | r = r100_cs_track_check(p->rdev, track); |
1344 | r = r100_cs_track_check(p->rdev, track); |
1449 | if (r) |
1345 | if (r) |
1450 | return r; |
1346 | return r; |
1451 | break; |
1347 | break; |
1452 | /* triggers drawing of vertex buffers setup elsewhere */ |
1348 | /* triggers drawing of vertex buffers setup elsewhere */ |
1453 | case PACKET3_3D_DRAW_INDX_2: |
1349 | case PACKET3_3D_DRAW_INDX_2: |
1454 | track->vap_vf_cntl = ib_chunk->kdata[idx]; |
1350 | track->vap_vf_cntl = radeon_get_ib_value(p, idx); |
1455 | r = r100_cs_track_check(p->rdev, track); |
1351 | r = r100_cs_track_check(p->rdev, track); |
1456 | if (r) |
1352 | if (r) |
1457 | return r; |
1353 | return r; |
1458 | break; |
1354 | break; |
1459 | /* triggers drawing using indices to vertex buffer */ |
1355 | /* triggers drawing using indices to vertex buffer */ |
1460 | case PACKET3_3D_DRAW_VBUF: |
1356 | case PACKET3_3D_DRAW_VBUF: |
1461 | track->vap_vf_cntl = ib_chunk->kdata[idx + 1]; |
1357 | track->vap_vf_cntl = radeon_get_ib_value(p, idx + 1); |
1462 | r = r100_cs_track_check(p->rdev, track); |
1358 | r = r100_cs_track_check(p->rdev, track); |
1463 | if (r) |
1359 | if (r) |
1464 | return r; |
1360 | return r; |
1465 | break; |
1361 | break; |
1466 | /* triggers drawing of vertex buffers setup elsewhere */ |
1362 | /* triggers drawing of vertex buffers setup elsewhere */ |
1467 | case PACKET3_3D_DRAW_INDX: |
1363 | case PACKET3_3D_DRAW_INDX: |
1468 | track->vap_vf_cntl = ib_chunk->kdata[idx + 1]; |
1364 | track->vap_vf_cntl = radeon_get_ib_value(p, idx + 1); |
1469 | r = r100_cs_track_check(p->rdev, track); |
1365 | r = r100_cs_track_check(p->rdev, track); |
1470 | if (r) |
1366 | if (r) |
Line 1920... | Line 1816... | ||
1920 | r100_pll_errata_after_index(rdev); |
1816 | r100_pll_errata_after_index(rdev); |
1921 | WREG32(RADEON_CLOCK_CNTL_DATA, v); |
1817 | WREG32(RADEON_CLOCK_CNTL_DATA, v); |
1922 | r100_pll_errata_after_data(rdev); |
1818 | r100_pll_errata_after_data(rdev); |
1923 | } |
1819 | } |
Line 1924... | Line 1820... | ||
1924 | 1820 | ||
1925 | int r100_init(struct radeon_device *rdev) |
1821 | void r100_set_safe_registers(struct radeon_device *rdev) |
1926 | { |
1822 | { |
1927 | if (ASIC_IS_RN50(rdev)) { |
1823 | if (ASIC_IS_RN50(rdev)) { |
1928 | rdev->config.r100.reg_safe_bm = rn50_reg_safe_bm; |
1824 | rdev->config.r100.reg_safe_bm = rn50_reg_safe_bm; |
1929 | rdev->config.r100.reg_safe_bm_size = ARRAY_SIZE(rn50_reg_safe_bm); |
1825 | rdev->config.r100.reg_safe_bm_size = ARRAY_SIZE(rn50_reg_safe_bm); |
1930 | } else if (rdev->family < CHIP_R200) { |
1826 | } else if (rdev->family < CHIP_R200) { |
1931 | rdev->config.r100.reg_safe_bm = r100_reg_safe_bm; |
1827 | rdev->config.r100.reg_safe_bm = r100_reg_safe_bm; |
1932 | rdev->config.r100.reg_safe_bm_size = ARRAY_SIZE(r100_reg_safe_bm); |
1828 | rdev->config.r100.reg_safe_bm_size = ARRAY_SIZE(r100_reg_safe_bm); |
1933 | } else { |
1829 | } else { |
1934 | return r200_init(rdev); |
1830 | r200_set_safe_registers(rdev); |
1935 | } |
- | |
1936 | return 0; |
1831 | } |
Line 1937... | Line 1832... | ||
1937 | } |
1832 | } |
1938 | 1833 | ||
1939 | /* |
1834 | /* |
Line 2229... | Line 2124... | ||
2229 | 2124 | ||
2230 | if (rdev->mode_info.crtcs[0]->base.enabled) { |
2125 | if (rdev->mode_info.crtcs[0]->base.enabled) { |
2231 | mode1 = &rdev->mode_info.crtcs[0]->base.mode; |
2126 | mode1 = &rdev->mode_info.crtcs[0]->base.mode; |
2232 | pixel_bytes1 = rdev->mode_info.crtcs[0]->base.fb->bits_per_pixel / 8; |
2127 | pixel_bytes1 = rdev->mode_info.crtcs[0]->base.fb->bits_per_pixel / 8; |
- | 2128 | } |
|
2233 | } |
2129 | if (!(rdev->flags & RADEON_SINGLE_CRTC)) { |
2234 | if (rdev->mode_info.crtcs[1]->base.enabled) { |
2130 | if (rdev->mode_info.crtcs[1]->base.enabled) { |
2235 | mode2 = &rdev->mode_info.crtcs[1]->base.mode; |
2131 | mode2 = &rdev->mode_info.crtcs[1]->base.mode; |
2236 | pixel_bytes2 = rdev->mode_info.crtcs[1]->base.fb->bits_per_pixel / 8; |
2132 | pixel_bytes2 = rdev->mode_info.crtcs[1]->base.fb->bits_per_pixel / 8; |
- | 2133 | } |
|
Line 2237... | Line 2134... | ||
2237 | } |
2134 | } |
2238 | 2135 | ||
2239 | min_mem_eff.full = rfixed_const_8(0); |
2136 | min_mem_eff.full = rfixed_const_8(0); |
2240 | /* get modes */ |
2137 | /* get modes */ |
Line 2649... | Line 2546... | ||
2649 | */ |
2546 | */ |
2650 | rdev->cp.ready = false; |
2547 | rdev->cp.ready = false; |
2651 | WREG32(R_000740_CP_CSQ_CNTL, 0); |
2548 | WREG32(R_000740_CP_CSQ_CNTL, 0); |
Line 2652... | Line 2549... | ||
2652 | 2549 | ||
2653 | /* Save few CRTC registers */ |
2550 | /* Save few CRTC registers */ |
2654 | save->GENMO_WT = RREG32(R_0003C0_GENMO_WT); |
2551 | save->GENMO_WT = RREG8(R_0003C2_GENMO_WT); |
2655 | save->CRTC_EXT_CNTL = RREG32(R_000054_CRTC_EXT_CNTL); |
2552 | save->CRTC_EXT_CNTL = RREG32(R_000054_CRTC_EXT_CNTL); |
2656 | save->CRTC_GEN_CNTL = RREG32(R_000050_CRTC_GEN_CNTL); |
2553 | save->CRTC_GEN_CNTL = RREG32(R_000050_CRTC_GEN_CNTL); |
2657 | save->CUR_OFFSET = RREG32(R_000260_CUR_OFFSET); |
2554 | save->CUR_OFFSET = RREG32(R_000260_CUR_OFFSET); |
2658 | if (!(rdev->flags & RADEON_SINGLE_CRTC)) { |
2555 | if (!(rdev->flags & RADEON_SINGLE_CRTC)) { |
2659 | save->CRTC2_GEN_CNTL = RREG32(R_0003F8_CRTC2_GEN_CNTL); |
2556 | save->CRTC2_GEN_CNTL = RREG32(R_0003F8_CRTC2_GEN_CNTL); |
2660 | save->CUR2_OFFSET = RREG32(R_000360_CUR2_OFFSET); |
2557 | save->CUR2_OFFSET = RREG32(R_000360_CUR2_OFFSET); |
Line 2661... | Line 2558... | ||
2661 | } |
2558 | } |
2662 | 2559 | ||
2663 | /* Disable VGA aperture access */ |
2560 | /* Disable VGA aperture access */ |
2664 | WREG32(R_0003C0_GENMO_WT, C_0003C0_VGA_RAM_EN & save->GENMO_WT); |
2561 | WREG8(R_0003C2_GENMO_WT, C_0003C2_VGA_RAM_EN & save->GENMO_WT); |
2665 | /* Disable cursor, overlay, crtc */ |
2562 | /* Disable cursor, overlay, crtc */ |
2666 | WREG32(R_000260_CUR_OFFSET, save->CUR_OFFSET | S_000260_CUR_LOCK(1)); |
2563 | WREG32(R_000260_CUR_OFFSET, save->CUR_OFFSET | S_000260_CUR_LOCK(1)); |
2667 | WREG32(R_000054_CRTC_EXT_CNTL, save->CRTC_EXT_CNTL | |
2564 | WREG32(R_000054_CRTC_EXT_CNTL, save->CRTC_EXT_CNTL | |
Line 2691... | Line 2588... | ||
2691 | if (!(rdev->flags & RADEON_SINGLE_CRTC)) { |
2588 | if (!(rdev->flags & RADEON_SINGLE_CRTC)) { |
2692 | WREG32(R_00033C_CRTC2_DISPLAY_BASE_ADDR, |
2589 | WREG32(R_00033C_CRTC2_DISPLAY_BASE_ADDR, |
2693 | rdev->mc.vram_location); |
2590 | rdev->mc.vram_location); |
2694 | } |
2591 | } |
2695 | /* Restore CRTC registers */ |
2592 | /* Restore CRTC registers */ |
2696 | WREG32(R_0003C0_GENMO_WT, save->GENMO_WT); |
2593 | WREG8(R_0003C2_GENMO_WT, save->GENMO_WT); |
2697 | WREG32(R_000054_CRTC_EXT_CNTL, save->CRTC_EXT_CNTL); |
2594 | WREG32(R_000054_CRTC_EXT_CNTL, save->CRTC_EXT_CNTL); |
2698 | WREG32(R_000050_CRTC_GEN_CNTL, save->CRTC_GEN_CNTL); |
2595 | WREG32(R_000050_CRTC_GEN_CNTL, save->CRTC_GEN_CNTL); |
2699 | if (!(rdev->flags & RADEON_SINGLE_CRTC)) { |
2596 | if (!(rdev->flags & RADEON_SINGLE_CRTC)) { |
2700 | WREG32(R_0003F8_CRTC2_GEN_CNTL, save->CRTC2_GEN_CNTL); |
2597 | WREG32(R_0003F8_CRTC2_GEN_CNTL, save->CRTC2_GEN_CNTL); |
2701 | } |
2598 | } |
2702 | } |
2599 | } |
Line -... | Line 2600... | ||
- | 2600 | ||
- | 2601 | void r100_vga_render_disable(struct radeon_device *rdev) |
|
- | 2602 | { |
|
- | 2603 | u32 tmp; |
|
- | 2604 | ||
- | 2605 | tmp = RREG8(R_0003C2_GENMO_WT); |
|
- | 2606 | WREG8(R_0003C2_GENMO_WT, C_0003C2_VGA_RAM_EN & tmp); |
|
- | 2607 | } |
|
- | 2608 | ||
- | 2609 | static void r100_debugfs(struct radeon_device *rdev) |
|
- | 2610 | { |
|
- | 2611 | int r; |
|
- | 2612 | ||
- | 2613 | r = r100_debugfs_mc_info_init(rdev); |
|
- | 2614 | if (r) |
|
- | 2615 | dev_warn(rdev->dev, "Failed to create r100_mc debugfs file.\n"); |
|
- | 2616 | } |
|
- | 2617 | ||
2703 | 2618 | ||
2704 | int drm_order(unsigned long size) |
2619 | int drm_order(unsigned long size) |
2705 | { |
2620 | { |
2706 | int order; |
2621 | int order; |
Line 2712... | Line 2627... | ||
2712 | ++order; |
2627 | ++order; |
Line 2713... | Line 2628... | ||
2713 | 2628 | ||
2714 | return order; |
2629 | return order; |
Line -... | Line 2630... | ||
- | 2630 | } |
|
- | 2631 | ||
- | 2632 | static void r100_mc_program(struct radeon_device *rdev) |
|
- | 2633 | { |
|
- | 2634 | struct r100_mc_save save; |
|
- | 2635 | ||
- | 2636 | /* Stops all mc clients */ |
|
- | 2637 | r100_mc_stop(rdev, &save); |
|
- | 2638 | if (rdev->flags & RADEON_IS_AGP) { |
|
- | 2639 | WREG32(R_00014C_MC_AGP_LOCATION, |
|
- | 2640 | S_00014C_MC_AGP_START(rdev->mc.gtt_start >> 16) | |
|
- | 2641 | S_00014C_MC_AGP_TOP(rdev->mc.gtt_end >> 16)); |
|
- | 2642 | WREG32(R_000170_AGP_BASE, lower_32_bits(rdev->mc.agp_base)); |
|
- | 2643 | if (rdev->family > CHIP_RV200) |
|
- | 2644 | WREG32(R_00015C_AGP_BASE_2, |
|
- | 2645 | upper_32_bits(rdev->mc.agp_base) & 0xff); |
|
- | 2646 | } else { |
|
- | 2647 | WREG32(R_00014C_MC_AGP_LOCATION, 0x0FFFFFFF); |
|
- | 2648 | WREG32(R_000170_AGP_BASE, 0); |
|
- | 2649 | if (rdev->family > CHIP_RV200) |
|
- | 2650 | WREG32(R_00015C_AGP_BASE_2, 0); |
|
- | 2651 | } |
|
- | 2652 | /* Wait for mc idle */ |
|
- | 2653 | if (r100_mc_wait_for_idle(rdev)) |
|
- | 2654 | dev_warn(rdev->dev, "Wait for MC idle timeout.\n"); |
|
- | 2655 | /* Program MC, should be a 32bits limited address space */ |
|
- | 2656 | WREG32(R_000148_MC_FB_LOCATION, |
|
- | 2657 | S_000148_MC_FB_START(rdev->mc.vram_start >> 16) | |
|
- | 2658 | S_000148_MC_FB_TOP(rdev->mc.vram_end >> 16)); |
|
- | 2659 | r100_mc_resume(rdev, &save); |
|
- | 2660 | } |
|
- | 2661 | ||
- | 2662 | void r100_clock_startup(struct radeon_device *rdev) |
|
- | 2663 | { |
|
- | 2664 | u32 tmp; |
|
- | 2665 | ||
- | 2666 | if (radeon_dynclks != -1 && radeon_dynclks) |
|
- | 2667 | radeon_legacy_set_clock_gating(rdev, 1); |
|
- | 2668 | /* We need to force on some of the block */ |
|
- | 2669 | tmp = RREG32_PLL(R_00000D_SCLK_CNTL); |
|
- | 2670 | tmp |= S_00000D_FORCE_CP(1) | S_00000D_FORCE_VIP(1); |
|
- | 2671 | if ((rdev->family == CHIP_RV250) || (rdev->family == CHIP_RV280)) |
|
- | 2672 | tmp |= S_00000D_FORCE_DISP1(1) | S_00000D_FORCE_DISP2(1); |
|
- | 2673 | WREG32_PLL(R_00000D_SCLK_CNTL, tmp); |
|
- | 2674 | } |
|
- | 2675 | ||
- | 2676 | static int r100_startup(struct radeon_device *rdev) |
|
- | 2677 | { |
|
- | 2678 | int r; |
|
- | 2679 | ||
- | 2680 | r100_mc_program(rdev); |
|
- | 2681 | /* Resume clock */ |
|
- | 2682 | r100_clock_startup(rdev); |
|
- | 2683 | /* Initialize GPU configuration (# pipes, ...) */ |
|
- | 2684 | r100_gpu_init(rdev); |
|
- | 2685 | /* Initialize GART (initialize after TTM so we can allocate |
|
- | 2686 | * memory through TTM but finalize after TTM) */ |
|
- | 2687 | if (rdev->flags & RADEON_IS_PCI) { |
|
- | 2688 | r = r100_pci_gart_enable(rdev); |
|
- | 2689 | if (r) |
|
- | 2690 | return r; |
|
- | 2691 | } |
|
- | 2692 | /* Enable IRQ */ |
|
- | 2693 | // rdev->irq.sw_int = true; |
|
- | 2694 | // r100_irq_set(rdev); |
|
- | 2695 | /* 1M ring buffer */ |
|
- | 2696 | // r = r100_cp_init(rdev, 1024 * 1024); |
|
- | 2697 | // if (r) { |
|
- | 2698 | // dev_err(rdev->dev, "failled initializing CP (%d).\n", r); |
|
- | 2699 | // return r; |
|
- | 2700 | // } |
|
- | 2701 | // r = r100_wb_init(rdev); |
|
- | 2702 | // if (r) |
|
- | 2703 | // dev_err(rdev->dev, "failled initializing WB (%d).\n", r); |
|
- | 2704 | // r = r100_ib_init(rdev); |
|
- | 2705 | // if (r) { |
|
- | 2706 | // dev_err(rdev->dev, "failled initializing IB (%d).\n", r); |
|
- | 2707 | // return r; |
|
- | 2708 | // } |
|
- | 2709 | return 0; |
|
- | 2710 | } |
|
- | 2711 | ||
- | 2712 | ||
- | 2713 | int r100_mc_init(struct radeon_device *rdev) |
|
- | 2714 | { |
|
- | 2715 | int r; |
|
- | 2716 | u32 tmp; |
|
- | 2717 | ||
- | 2718 | /* Setup GPU memory space */ |
|
- | 2719 | rdev->mc.vram_location = 0xFFFFFFFFUL; |
|
- | 2720 | rdev->mc.gtt_location = 0xFFFFFFFFUL; |
|
- | 2721 | if (rdev->flags & RADEON_IS_IGP) { |
|
- | 2722 | tmp = G_00015C_MC_FB_START(RREG32(R_00015C_NB_TOM)); |
|
- | 2723 | rdev->mc.vram_location = tmp << 16; |
|
- | 2724 | } |
|
- | 2725 | if (rdev->flags & RADEON_IS_AGP) { |
|
- | 2726 | r = radeon_agp_init(rdev); |
|
- | 2727 | if (r) { |
|
- | 2728 | printk(KERN_WARNING "[drm] Disabling AGP\n"); |
|
- | 2729 | rdev->flags &= ~RADEON_IS_AGP; |
|
- | 2730 | rdev->mc.gtt_size = radeon_gart_size * 1024 * 1024; |
|
- | 2731 | } else { |
|
- | 2732 | rdev->mc.gtt_location = rdev->mc.agp_base; |
|
- | 2733 | } |
|
- | 2734 | } |
|
- | 2735 | r = radeon_mc_setup(rdev); |
|
- | 2736 | if (r) |
|
- | 2737 | return r; |
|
- | 2738 | return 0; |
|
- | 2739 | } |
|
- | 2740 | ||
- | 2741 | int r100_init(struct radeon_device *rdev) |
|
- | 2742 | { |
|
- | 2743 | int r; |
|
- | 2744 | ||
- | 2745 | /* Register debugfs file specific to this group of asics */ |
|
- | 2746 | r100_debugfs(rdev); |
|
- | 2747 | /* Disable VGA */ |
|
- | 2748 | r100_vga_render_disable(rdev); |
|
- | 2749 | /* Initialize scratch registers */ |
|
- | 2750 | radeon_scratch_init(rdev); |
|
- | 2751 | /* Initialize surface registers */ |
|
- | 2752 | radeon_surface_init(rdev); |
|
- | 2753 | /* TODO: disable VGA need to use VGA request */ |
|
- | 2754 | /* BIOS*/ |
|
- | 2755 | if (!radeon_get_bios(rdev)) { |
|
- | 2756 | if (ASIC_IS_AVIVO(rdev)) |
|
- | 2757 | return -EINVAL; |
|
- | 2758 | } |
|
- | 2759 | if (rdev->is_atom_bios) { |
|
- | 2760 | dev_err(rdev->dev, "Expecting combios for RS400/RS480 GPU\n"); |
|
- | 2761 | return -EINVAL; |
|
- | 2762 | } else { |
|
- | 2763 | r = radeon_combios_init(rdev); |
|
- | 2764 | if (r) |
|
- | 2765 | return r; |
|
- | 2766 | } |
|
- | 2767 | /* Reset gpu before posting otherwise ATOM will enter infinite loop */ |
|
- | 2768 | if (radeon_gpu_reset(rdev)) { |
|
- | 2769 | dev_warn(rdev->dev, |
|
- | 2770 | "GPU reset failed ! (0xE40=0x%08X, 0x7C0=0x%08X)\n", |
|
- | 2771 | RREG32(R_000E40_RBBM_STATUS), |
|
- | 2772 | RREG32(R_0007C0_CP_STAT)); |
|
- | 2773 | } |
|
- | 2774 | /* check if cards are posted or not */ |
|
- | 2775 | if (!radeon_card_posted(rdev) && rdev->bios) { |
|
- | 2776 | DRM_INFO("GPU not posted. posting now...\n"); |
|
- | 2777 | radeon_combios_asic_init(rdev->ddev); |
|
- | 2778 | } |
|
- | 2779 | /* Set asic errata */ |
|
- | 2780 | r100_errata(rdev); |
|
- | 2781 | /* Initialize clocks */ |
|
- | 2782 | radeon_get_clock_info(rdev->ddev); |
|
- | 2783 | /* Get vram informations */ |
|
- | 2784 | r100_vram_info(rdev); |
|
- | 2785 | /* Initialize memory controller (also test AGP) */ |
|
- | 2786 | r = r100_mc_init(rdev); |
|
- | 2787 | if (r) |
|
- | 2788 | return r; |
|
- | 2789 | /* Fence driver */ |
|
- | 2790 | // r = radeon_fence_driver_init(rdev); |
|
- | 2791 | // if (r) |
|
- | 2792 | // return r; |
|
- | 2793 | // r = radeon_irq_kms_init(rdev); |
|
- | 2794 | // if (r) |
|
- | 2795 | // return r; |
|
- | 2796 | /* Memory manager */ |
|
- | 2797 | r = radeon_object_init(rdev); |
|
- | 2798 | if (r) |
|
- | 2799 | return r; |
|
- | 2800 | if (rdev->flags & RADEON_IS_PCI) { |
|
- | 2801 | r = r100_pci_gart_init(rdev); |
|
- | 2802 | if (r) |
|
- | 2803 | return r; |
|
- | 2804 | } |
|
- | 2805 | r100_set_safe_registers(rdev); |
|
- | 2806 | rdev->accel_working = true; |
|
- | 2807 | r = r100_startup(rdev); |
|
- | 2808 | if (r) { |
|
- | 2809 | /* Somethings want wront with the accel init stop accel */ |
|
- | 2810 | dev_err(rdev->dev, "Disabling GPU acceleration\n"); |
|
- | 2811 | // r100_suspend(rdev); |
|
- | 2812 | // r100_cp_fini(rdev); |
|
- | 2813 | // r100_wb_fini(rdev); |
|
- | 2814 | // r100_ib_fini(rdev); |
|
- | 2815 | if (rdev->flags & RADEON_IS_PCI) |
|
- | 2816 | r100_pci_gart_fini(rdev); |
|
- | 2817 | // radeon_irq_kms_fini(rdev); |
|
- | 2818 | rdev->accel_working = false; |
|
- | 2819 | } |