aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/radeon/r600.c
diff options
context:
space:
mode:
authorJerome Glisse <jglisse@redhat.com>2009-10-01 12:02:13 -0400
committerDave Airlie <airlied@redhat.com>2009-10-01 19:34:03 -0400
commita3c1945aaf48a5893238d95139f202531994094d (patch)
tree369e87201ddb801f7d740fbc8a1777c65655f9f6 /drivers/gpu/drm/radeon/r600.c
parent81cc35bfc19ebe4b823396fe4fef67a923360916 (diff)
drm/radeon/kms: Fix R600/RV770 startup path & reset
We were calling reset unconditionaly in the startup path this is bad we need to call GPU reset for a good reason as after reset the GPU is in unknown states. To avoid any more bad things to happen we now also unconditionaly reinitialize the GPU after reset. This patch fix few issues reported by different people regarding KMS & R6XX/RV7XX hw. Signed-off-by: Jerome Glisse <jglisse@redhat.com> Signed-off-by: Dave Airlie <airlied@redhat.com>
Diffstat (limited to 'drivers/gpu/drm/radeon/r600.c')
-rw-r--r--drivers/gpu/drm/radeon/r600.c99
1 files changed, 31 insertions, 68 deletions
diff --git a/drivers/gpu/drm/radeon/r600.c b/drivers/gpu/drm/radeon/r600.c
index 11fa801a2c52..cf4be70c5041 100644
--- a/drivers/gpu/drm/radeon/r600.c
+++ b/drivers/gpu/drm/radeon/r600.c
@@ -240,14 +240,9 @@ int r600_mc_wait_for_idle(struct radeon_device *rdev)
240 return -1; 240 return -1;
241} 241}
242 242
243static void r600_mc_resume(struct radeon_device *rdev) 243static void r600_mc_program(struct radeon_device *rdev)
244{ 244{
245 u32 d1vga_control, d2vga_control; 245 struct rv515_mc_save save;
246 u32 vga_render_control, vga_hdp_control;
247 u32 d1crtc_control, d2crtc_control;
248 u32 new_d1grph_primary, new_d1grph_secondary;
249 u32 new_d2grph_primary, new_d2grph_secondary;
250 u64 old_vram_start;
251 u32 tmp; 246 u32 tmp;
252 int i, j; 247 int i, j;
253 248
@@ -261,41 +256,12 @@ static void r600_mc_resume(struct radeon_device *rdev)
261 } 256 }
262 WREG32(HDP_REG_COHERENCY_FLUSH_CNTL, 0); 257 WREG32(HDP_REG_COHERENCY_FLUSH_CNTL, 0);
263 258
264 d1vga_control = RREG32(D1VGA_CONTROL); 259 rv515_mc_stop(rdev, &save);
265 d2vga_control = RREG32(D2VGA_CONTROL);
266 vga_render_control = RREG32(VGA_RENDER_CONTROL);
267 vga_hdp_control = RREG32(VGA_HDP_CONTROL);
268 d1crtc_control = RREG32(D1CRTC_CONTROL);
269 d2crtc_control = RREG32(D2CRTC_CONTROL);
270 old_vram_start = (u64)(RREG32(MC_VM_FB_LOCATION) & 0xFFFF) << 24;
271 new_d1grph_primary = RREG32(D1GRPH_PRIMARY_SURFACE_ADDRESS);
272 new_d1grph_secondary = RREG32(D1GRPH_SECONDARY_SURFACE_ADDRESS);
273 new_d1grph_primary += rdev->mc.vram_start - old_vram_start;
274 new_d1grph_secondary += rdev->mc.vram_start - old_vram_start;
275 new_d2grph_primary = RREG32(D2GRPH_PRIMARY_SURFACE_ADDRESS);
276 new_d2grph_secondary = RREG32(D2GRPH_SECONDARY_SURFACE_ADDRESS);
277 new_d2grph_primary += rdev->mc.vram_start - old_vram_start;
278 new_d2grph_secondary += rdev->mc.vram_start - old_vram_start;
279
280 /* Stop all video */
281 WREG32(D1VGA_CONTROL, 0);
282 WREG32(D2VGA_CONTROL, 0);
283 WREG32(VGA_RENDER_CONTROL, 0);
284 WREG32(D1CRTC_UPDATE_LOCK, 1);
285 WREG32(D2CRTC_UPDATE_LOCK, 1);
286 WREG32(D1CRTC_CONTROL, 0);
287 WREG32(D2CRTC_CONTROL, 0);
288 WREG32(D1CRTC_UPDATE_LOCK, 0);
289 WREG32(D2CRTC_UPDATE_LOCK, 0);
290
291 mdelay(1);
292 if (r600_mc_wait_for_idle(rdev)) { 260 if (r600_mc_wait_for_idle(rdev)) {
293 printk(KERN_WARNING "[drm] MC not idle !\n"); 261 dev_warn(rdev->dev, "Wait for MC idle timedout !\n");
294 } 262 }
295 263 /* Lockout access through VGA aperture (doesn't exist before R600) */
296 /* Lockout access through VGA aperture*/
297 WREG32(VGA_HDP_CONTROL, VGA_MEMORY_DISABLE); 264 WREG32(VGA_HDP_CONTROL, VGA_MEMORY_DISABLE);
298
299 /* Update configuration */ 265 /* Update configuration */
300 WREG32(MC_VM_SYSTEM_APERTURE_LOW_ADDR, rdev->mc.vram_start >> 12); 266 WREG32(MC_VM_SYSTEM_APERTURE_LOW_ADDR, rdev->mc.vram_start >> 12);
301 WREG32(MC_VM_SYSTEM_APERTURE_HIGH_ADDR, (rdev->mc.vram_end - 1) >> 12); 267 WREG32(MC_VM_SYSTEM_APERTURE_HIGH_ADDR, (rdev->mc.vram_end - 1) >> 12);
@@ -315,31 +281,10 @@ static void r600_mc_resume(struct radeon_device *rdev)
315 WREG32(MC_VM_AGP_TOP, 0x0FFFFFFF); 281 WREG32(MC_VM_AGP_TOP, 0x0FFFFFFF);
316 WREG32(MC_VM_AGP_BOT, 0x0FFFFFFF); 282 WREG32(MC_VM_AGP_BOT, 0x0FFFFFFF);
317 } 283 }
318 WREG32(D1GRPH_PRIMARY_SURFACE_ADDRESS, new_d1grph_primary);
319 WREG32(D1GRPH_SECONDARY_SURFACE_ADDRESS, new_d1grph_secondary);
320 WREG32(D2GRPH_PRIMARY_SURFACE_ADDRESS, new_d2grph_primary);
321 WREG32(D2GRPH_SECONDARY_SURFACE_ADDRESS, new_d2grph_secondary);
322 WREG32(VGA_MEMORY_BASE_ADDRESS, rdev->mc.vram_start);
323
324 /* Unlock host access */
325 WREG32(VGA_HDP_CONTROL, vga_hdp_control);
326
327 mdelay(1);
328 if (r600_mc_wait_for_idle(rdev)) { 284 if (r600_mc_wait_for_idle(rdev)) {
329 printk(KERN_WARNING "[drm] MC not idle !\n"); 285 dev_warn(rdev->dev, "Wait for MC idle timedout !\n");
330 } 286 }
331 287 rv515_mc_resume(rdev, &save);
332 /* Restore video state */
333 WREG32(D1CRTC_UPDATE_LOCK, 1);
334 WREG32(D2CRTC_UPDATE_LOCK, 1);
335 WREG32(D1CRTC_CONTROL, d1crtc_control);
336 WREG32(D2CRTC_CONTROL, d2crtc_control);
337 WREG32(D1CRTC_UPDATE_LOCK, 0);
338 WREG32(D2CRTC_UPDATE_LOCK, 0);
339 WREG32(D1VGA_CONTROL, d1vga_control);
340 WREG32(D2VGA_CONTROL, d2vga_control);
341 WREG32(VGA_RENDER_CONTROL, vga_render_control);
342
343 /* we need to own VRAM, so turn off the VGA renderer here 288 /* we need to own VRAM, so turn off the VGA renderer here
344 * to stop it overwriting our objects */ 289 * to stop it overwriting our objects */
345 rv515_vga_render_disable(rdev); 290 rv515_vga_render_disable(rdev);
@@ -463,6 +408,7 @@ int r600_mc_init(struct radeon_device *rdev)
463 */ 408 */
464int r600_gpu_soft_reset(struct radeon_device *rdev) 409int r600_gpu_soft_reset(struct radeon_device *rdev)
465{ 410{
411 struct rv515_mc_save save;
466 u32 grbm_busy_mask = S_008010_VC_BUSY(1) | S_008010_VGT_BUSY_NO_DMA(1) | 412 u32 grbm_busy_mask = S_008010_VC_BUSY(1) | S_008010_VGT_BUSY_NO_DMA(1) |
467 S_008010_VGT_BUSY(1) | S_008010_TA03_BUSY(1) | 413 S_008010_VGT_BUSY(1) | S_008010_TA03_BUSY(1) |
468 S_008010_TC_BUSY(1) | S_008010_SX_BUSY(1) | 414 S_008010_TC_BUSY(1) | S_008010_SX_BUSY(1) |
@@ -480,13 +426,21 @@ int r600_gpu_soft_reset(struct radeon_device *rdev)
480 S_008014_CB0_BUSY(1) | S_008014_CB1_BUSY(1) | 426 S_008014_CB0_BUSY(1) | S_008014_CB1_BUSY(1) |
481 S_008014_CB2_BUSY(1) | S_008014_CB3_BUSY(1); 427 S_008014_CB2_BUSY(1) | S_008014_CB3_BUSY(1);
482 u32 srbm_reset = 0; 428 u32 srbm_reset = 0;
429 u32 tmp;
483 430
431 dev_info(rdev->dev, "GPU softreset (R_008010_GRBM_STATUS=0x%08X "
432 "R_008014_GRBM_STATUS2=0x%08X)\n", RREG32(R_008010_GRBM_STATUS),
433 RREG32(R_008014_GRBM_STATUS2));
434 rv515_mc_stop(rdev, &save);
435 if (r600_mc_wait_for_idle(rdev)) {
436 dev_warn(rdev->dev, "Wait for MC idle timedout !\n");
437 }
484 /* Disable CP parsing/prefetching */ 438 /* Disable CP parsing/prefetching */
485 WREG32(R_0086D8_CP_ME_CNTL, S_0086D8_CP_ME_HALT(0xff)); 439 WREG32(R_0086D8_CP_ME_CNTL, S_0086D8_CP_ME_HALT(0xff));
486 /* Check if any of the rendering block is busy and reset it */ 440 /* Check if any of the rendering block is busy and reset it */
487 if ((RREG32(R_008010_GRBM_STATUS) & grbm_busy_mask) || 441 if ((RREG32(R_008010_GRBM_STATUS) & grbm_busy_mask) ||
488 (RREG32(R_008014_GRBM_STATUS2) & grbm2_busy_mask)) { 442 (RREG32(R_008014_GRBM_STATUS2) & grbm2_busy_mask)) {
489 WREG32(R_008020_GRBM_SOFT_RESET, S_008020_SOFT_RESET_CR(1) | 443 tmp = S_008020_SOFT_RESET_CR(1) |
490 S_008020_SOFT_RESET_DB(1) | 444 S_008020_SOFT_RESET_DB(1) |
491 S_008020_SOFT_RESET_CB(1) | 445 S_008020_SOFT_RESET_CB(1) |
492 S_008020_SOFT_RESET_PA(1) | 446 S_008020_SOFT_RESET_PA(1) |
@@ -498,14 +452,18 @@ int r600_gpu_soft_reset(struct radeon_device *rdev)
498 S_008020_SOFT_RESET_TC(1) | 452 S_008020_SOFT_RESET_TC(1) |
499 S_008020_SOFT_RESET_TA(1) | 453 S_008020_SOFT_RESET_TA(1) |
500 S_008020_SOFT_RESET_VC(1) | 454 S_008020_SOFT_RESET_VC(1) |
501 S_008020_SOFT_RESET_VGT(1)); 455 S_008020_SOFT_RESET_VGT(1);
456 dev_info(rdev->dev, "R_008020_GRBM_SOFT_RESET=0x%08X\n", tmp);
457 WREG32(R_008020_GRBM_SOFT_RESET, tmp);
502 (void)RREG32(R_008020_GRBM_SOFT_RESET); 458 (void)RREG32(R_008020_GRBM_SOFT_RESET);
503 udelay(50); 459 udelay(50);
504 WREG32(R_008020_GRBM_SOFT_RESET, 0); 460 WREG32(R_008020_GRBM_SOFT_RESET, 0);
505 (void)RREG32(R_008020_GRBM_SOFT_RESET); 461 (void)RREG32(R_008020_GRBM_SOFT_RESET);
506 } 462 }
507 /* Reset CP (we always reset CP) */ 463 /* Reset CP (we always reset CP) */
508 WREG32(R_008020_GRBM_SOFT_RESET, S_008020_SOFT_RESET_CP(1)); 464 tmp = S_008020_SOFT_RESET_CP(1);
465 dev_info(rdev->dev, "R_008020_GRBM_SOFT_RESET=0x%08X\n", tmp);
466 WREG32(R_008020_GRBM_SOFT_RESET, tmp);
509 (void)RREG32(R_008020_GRBM_SOFT_RESET); 467 (void)RREG32(R_008020_GRBM_SOFT_RESET);
510 udelay(50); 468 udelay(50);
511 WREG32(R_008020_GRBM_SOFT_RESET, 0); 469 WREG32(R_008020_GRBM_SOFT_RESET, 0);
@@ -533,6 +491,7 @@ int r600_gpu_soft_reset(struct radeon_device *rdev)
533 srbm_reset |= S_000E60_SOFT_RESET_RLC(1); 491 srbm_reset |= S_000E60_SOFT_RESET_RLC(1);
534 if (G_000E50_SEM_BUSY(RREG32(R_000E50_SRBM_STATUS))) 492 if (G_000E50_SEM_BUSY(RREG32(R_000E50_SRBM_STATUS)))
535 srbm_reset |= S_000E60_SOFT_RESET_SEM(1); 493 srbm_reset |= S_000E60_SOFT_RESET_SEM(1);
494 dev_info(rdev->dev, "R_000E60_SRBM_SOFT_RESET=0x%08X\n", srbm_reset);
536 WREG32(R_000E60_SRBM_SOFT_RESET, srbm_reset); 495 WREG32(R_000E60_SRBM_SOFT_RESET, srbm_reset);
537 (void)RREG32(R_000E60_SRBM_SOFT_RESET); 496 (void)RREG32(R_000E60_SRBM_SOFT_RESET);
538 udelay(50); 497 udelay(50);
@@ -540,6 +499,11 @@ int r600_gpu_soft_reset(struct radeon_device *rdev)
540 (void)RREG32(R_000E60_SRBM_SOFT_RESET); 499 (void)RREG32(R_000E60_SRBM_SOFT_RESET);
541 /* Wait a little for things to settle down */ 500 /* Wait a little for things to settle down */
542 udelay(50); 501 udelay(50);
502 /* After reset we need to reinit the asic as GPU often endup in an
503 * incoherent state.
504 */
505 atom_asic_init(rdev->mode_info.atom_context);
506 rv515_mc_resume(rdev, &save);
543 return 0; 507 return 0;
544} 508}
545 509
@@ -1477,8 +1441,7 @@ int r600_startup(struct radeon_device *rdev)
1477{ 1441{
1478 int r; 1442 int r;
1479 1443
1480 r600_gpu_reset(rdev); 1444 r600_mc_program(rdev);
1481 r600_mc_resume(rdev);
1482 r = r600_pcie_gart_enable(rdev); 1445 r = r600_pcie_gart_enable(rdev);
1483 if (r) 1446 if (r)
1484 return r; 1447 return r;
@@ -1509,7 +1472,7 @@ int r600_resume(struct radeon_device *rdev)
1509{ 1472{
1510 int r; 1473 int r;
1511 1474
1512 if (radeon_gpu_reset(rdev)) { 1475 if (r600_gpu_reset(rdev)) {
1513 /* FIXME: what do we want to do here ? */ 1476 /* FIXME: what do we want to do here ? */
1514 } 1477 }
1515 /* post card */ 1478 /* post card */