aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/radeon/evergreen.c
diff options
context:
space:
mode:
authorAlex Deucher <alexander.deucher@amd.com>2013-01-18 14:28:41 -0500
committerAlex Deucher <alexander.deucher@amd.com>2013-01-31 16:24:50 -0500
commitb7630473def7dad61728c68b4f23d0f2294405bc (patch)
tree28b0834efd318f22b3d63492672f5d1788065634 /drivers/gpu/drm/radeon/evergreen.c
parentd3cb781e83b39561f717358e95d357e53a0da720 (diff)
drm/radeon: rework GPU reset on evergreen
Update the code to better match the recommended programming sequence for soft reset. Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
Diffstat (limited to 'drivers/gpu/drm/radeon/evergreen.c')
-rw-r--r--drivers/gpu/drm/radeon/evergreen.c161
1 files changed, 85 insertions, 76 deletions
diff --git a/drivers/gpu/drm/radeon/evergreen.c b/drivers/gpu/drm/radeon/evergreen.c
index dd1d188376bf..903cc544cedf 100644
--- a/drivers/gpu/drm/radeon/evergreen.c
+++ b/drivers/gpu/drm/radeon/evergreen.c
@@ -2327,54 +2327,8 @@ bool evergreen_gpu_is_lockup(struct radeon_device *rdev, struct radeon_ring *rin
2327 return radeon_ring_test_lockup(rdev, ring); 2327 return radeon_ring_test_lockup(rdev, ring);
2328} 2328}
2329 2329
2330static void evergreen_gpu_soft_reset_gfx(struct radeon_device *rdev) 2330static void evergreen_print_gpu_status_regs(struct radeon_device *rdev)
2331{ 2331{
2332 u32 grbm_reset = 0;
2333
2334 if (!(RREG32(GRBM_STATUS) & GUI_ACTIVE))
2335 return;
2336
2337 dev_info(rdev->dev, " GRBM_STATUS = 0x%08X\n",
2338 RREG32(GRBM_STATUS));
2339 dev_info(rdev->dev, " GRBM_STATUS_SE0 = 0x%08X\n",
2340 RREG32(GRBM_STATUS_SE0));
2341 dev_info(rdev->dev, " GRBM_STATUS_SE1 = 0x%08X\n",
2342 RREG32(GRBM_STATUS_SE1));
2343 dev_info(rdev->dev, " SRBM_STATUS = 0x%08X\n",
2344 RREG32(SRBM_STATUS));
2345 dev_info(rdev->dev, " R_008674_CP_STALLED_STAT1 = 0x%08X\n",
2346 RREG32(CP_STALLED_STAT1));
2347 dev_info(rdev->dev, " R_008678_CP_STALLED_STAT2 = 0x%08X\n",
2348 RREG32(CP_STALLED_STAT2));
2349 dev_info(rdev->dev, " R_00867C_CP_BUSY_STAT = 0x%08X\n",
2350 RREG32(CP_BUSY_STAT));
2351 dev_info(rdev->dev, " R_008680_CP_STAT = 0x%08X\n",
2352 RREG32(CP_STAT));
2353
2354 /* Disable CP parsing/prefetching */
2355 WREG32(CP_ME_CNTL, CP_ME_HALT | CP_PFP_HALT);
2356
2357 /* reset all the gfx blocks */
2358 grbm_reset = (SOFT_RESET_CP |
2359 SOFT_RESET_CB |
2360 SOFT_RESET_DB |
2361 SOFT_RESET_PA |
2362 SOFT_RESET_SC |
2363 SOFT_RESET_SPI |
2364 SOFT_RESET_SH |
2365 SOFT_RESET_SX |
2366 SOFT_RESET_TC |
2367 SOFT_RESET_TA |
2368 SOFT_RESET_VC |
2369 SOFT_RESET_VGT);
2370
2371 dev_info(rdev->dev, " GRBM_SOFT_RESET=0x%08X\n", grbm_reset);
2372 WREG32(GRBM_SOFT_RESET, grbm_reset);
2373 (void)RREG32(GRBM_SOFT_RESET);
2374 udelay(50);
2375 WREG32(GRBM_SOFT_RESET, 0);
2376 (void)RREG32(GRBM_SOFT_RESET);
2377
2378 dev_info(rdev->dev, " GRBM_STATUS = 0x%08X\n", 2332 dev_info(rdev->dev, " GRBM_STATUS = 0x%08X\n",
2379 RREG32(GRBM_STATUS)); 2333 RREG32(GRBM_STATUS));
2380 dev_info(rdev->dev, " GRBM_STATUS_SE0 = 0x%08X\n", 2334 dev_info(rdev->dev, " GRBM_STATUS_SE0 = 0x%08X\n",
@@ -2391,29 +2345,6 @@ static void evergreen_gpu_soft_reset_gfx(struct radeon_device *rdev)
2391 RREG32(CP_BUSY_STAT)); 2345 RREG32(CP_BUSY_STAT));
2392 dev_info(rdev->dev, " R_008680_CP_STAT = 0x%08X\n", 2346 dev_info(rdev->dev, " R_008680_CP_STAT = 0x%08X\n",
2393 RREG32(CP_STAT)); 2347 RREG32(CP_STAT));
2394}
2395
2396static void evergreen_gpu_soft_reset_dma(struct radeon_device *rdev)
2397{
2398 u32 tmp;
2399
2400 if (RREG32(DMA_STATUS_REG) & DMA_IDLE)
2401 return;
2402
2403 dev_info(rdev->dev, " R_00D034_DMA_STATUS_REG = 0x%08X\n",
2404 RREG32(DMA_STATUS_REG));
2405
2406 /* Disable DMA */
2407 tmp = RREG32(DMA_RB_CNTL);
2408 tmp &= ~DMA_RB_ENABLE;
2409 WREG32(DMA_RB_CNTL, tmp);
2410
2411 /* Reset dma */
2412 WREG32(SRBM_SOFT_RESET, SOFT_RESET_DMA);
2413 RREG32(SRBM_SOFT_RESET);
2414 udelay(50);
2415 WREG32(SRBM_SOFT_RESET, 0);
2416
2417 dev_info(rdev->dev, " R_00D034_DMA_STATUS_REG = 0x%08X\n", 2348 dev_info(rdev->dev, " R_00D034_DMA_STATUS_REG = 0x%08X\n",
2418 RREG32(DMA_STATUS_REG)); 2349 RREG32(DMA_STATUS_REG));
2419} 2350}
@@ -2421,9 +2352,12 @@ static void evergreen_gpu_soft_reset_dma(struct radeon_device *rdev)
2421static int evergreen_gpu_soft_reset(struct radeon_device *rdev, u32 reset_mask) 2352static int evergreen_gpu_soft_reset(struct radeon_device *rdev, u32 reset_mask)
2422{ 2353{
2423 struct evergreen_mc_save save; 2354 struct evergreen_mc_save save;
2355 u32 grbm_soft_reset = 0, srbm_soft_reset = 0;
2356 u32 tmp;
2357 int ret = 0;
2424 2358
2425 if (!(RREG32(GRBM_STATUS) & GUI_ACTIVE)) 2359 if (!(RREG32(GRBM_STATUS) & GUI_ACTIVE))
2426 reset_mask &= ~(RADEON_RESET_GFX | RADEON_RESET_COMPUTE); 2360 reset_mask &= ~(RADEON_RESET_GFX | RADEON_RESET_COMPUTE | RADEON_RESET_CP);
2427 2361
2428 if (RREG32(DMA_STATUS_REG) & DMA_IDLE) 2362 if (RREG32(DMA_STATUS_REG) & DMA_IDLE)
2429 reset_mask &= ~RADEON_RESET_DMA; 2363 reset_mask &= ~RADEON_RESET_DMA;
@@ -2433,6 +2367,8 @@ static int evergreen_gpu_soft_reset(struct radeon_device *rdev, u32 reset_mask)
2433 2367
2434 dev_info(rdev->dev, "GPU softreset: 0x%08X\n", reset_mask); 2368 dev_info(rdev->dev, "GPU softreset: 0x%08X\n", reset_mask);
2435 2369
2370 evergreen_print_gpu_status_regs(rdev);
2371
2436 r600_set_bios_scratch_engine_hung(rdev, true); 2372 r600_set_bios_scratch_engine_hung(rdev, true);
2437 2373
2438 evergreen_mc_stop(rdev, &save); 2374 evergreen_mc_stop(rdev, &save);
@@ -2440,18 +2376,90 @@ static int evergreen_gpu_soft_reset(struct radeon_device *rdev, u32 reset_mask)
2440 dev_warn(rdev->dev, "Wait for MC idle timedout !\n"); 2376 dev_warn(rdev->dev, "Wait for MC idle timedout !\n");
2441 } 2377 }
2442 2378
2443 if (reset_mask & (RADEON_RESET_GFX | RADEON_RESET_COMPUTE)) 2379 /* Disable CP parsing/prefetching */
2444 evergreen_gpu_soft_reset_gfx(rdev); 2380 WREG32(CP_ME_CNTL, CP_ME_HALT | CP_PFP_HALT);
2381
2382 if (reset_mask & RADEON_RESET_DMA) {
2383 /* Disable DMA */
2384 tmp = RREG32(DMA_RB_CNTL);
2385 tmp &= ~DMA_RB_ENABLE;
2386 WREG32(DMA_RB_CNTL, tmp);
2387 }
2388
2389 if (reset_mask & (RADEON_RESET_GFX | RADEON_RESET_COMPUTE)) {
2390 grbm_soft_reset |= SOFT_RESET_DB |
2391 SOFT_RESET_CB |
2392 SOFT_RESET_PA |
2393 SOFT_RESET_SC |
2394 SOFT_RESET_SPI |
2395 SOFT_RESET_SX |
2396 SOFT_RESET_SH |
2397 SOFT_RESET_TC |
2398 SOFT_RESET_TA |
2399 SOFT_RESET_VC |
2400 SOFT_RESET_VGT;
2401 }
2402
2403 if (reset_mask & RADEON_RESET_CP) {
2404 grbm_soft_reset |= SOFT_RESET_CP |
2405 SOFT_RESET_VGT;
2406
2407 srbm_soft_reset |= SOFT_RESET_GRBM;
2408 }
2445 2409
2446 if (reset_mask & RADEON_RESET_DMA) 2410 if (reset_mask & RADEON_RESET_DMA)
2447 evergreen_gpu_soft_reset_dma(rdev); 2411 srbm_soft_reset |= SOFT_RESET_DMA;
2412
2413 if (grbm_soft_reset) {
2414 tmp = RREG32(GRBM_SOFT_RESET);
2415 tmp |= grbm_soft_reset;
2416 dev_info(rdev->dev, "GRBM_SOFT_RESET=0x%08X\n", tmp);
2417 WREG32(GRBM_SOFT_RESET, tmp);
2418 tmp = RREG32(GRBM_SOFT_RESET);
2419
2420 udelay(50);
2421
2422 tmp &= ~grbm_soft_reset;
2423 WREG32(GRBM_SOFT_RESET, tmp);
2424 tmp = RREG32(GRBM_SOFT_RESET);
2425 }
2426
2427 if (srbm_soft_reset) {
2428 tmp = RREG32(SRBM_SOFT_RESET);
2429 tmp |= srbm_soft_reset;
2430 dev_info(rdev->dev, "SRBM_SOFT_RESET=0x%08X\n", tmp);
2431 WREG32(SRBM_SOFT_RESET, tmp);
2432 tmp = RREG32(SRBM_SOFT_RESET);
2433
2434 udelay(50);
2435
2436 tmp &= ~srbm_soft_reset;
2437 WREG32(SRBM_SOFT_RESET, tmp);
2438 tmp = RREG32(SRBM_SOFT_RESET);
2439 }
2448 2440
2449 /* Wait a little for things to settle down */ 2441 /* Wait a little for things to settle down */
2450 udelay(50); 2442 udelay(50);
2451 2443
2452 evergreen_mc_resume(rdev, &save); 2444 evergreen_mc_resume(rdev, &save);
2445 udelay(50);
2446
2447#if 0
2448 if (reset_mask & (RADEON_RESET_GFX | RADEON_RESET_COMPUTE | RADEON_RESET_CP)) {
2449 if (RREG32(GRBM_STATUS) & GUI_ACTIVE)
2450 ret = -EAGAIN;
2451 }
2452
2453 if (reset_mask & RADEON_RESET_DMA) {
2454 if (!(RREG32(DMA_STATUS_REG) & DMA_IDLE))
2455 ret = -EAGAIN;
2456 }
2457#endif
2458
2459 if (!ret)
2460 r600_set_bios_scratch_engine_hung(rdev, false);
2453 2461
2454 r600_set_bios_scratch_engine_hung(rdev, false); 2462 evergreen_print_gpu_status_regs(rdev);
2455 2463
2456 return 0; 2464 return 0;
2457} 2465}
@@ -2460,7 +2468,8 @@ int evergreen_asic_reset(struct radeon_device *rdev)
2460{ 2468{
2461 return evergreen_gpu_soft_reset(rdev, (RADEON_RESET_GFX | 2469 return evergreen_gpu_soft_reset(rdev, (RADEON_RESET_GFX |
2462 RADEON_RESET_COMPUTE | 2470 RADEON_RESET_COMPUTE |
2463 RADEON_RESET_DMA)); 2471 RADEON_RESET_DMA |
2472 RADEON_RESET_CP));
2464} 2473}
2465 2474
2466/* Interrupts */ 2475/* Interrupts */