diff options
author | Alex Deucher <alexander.deucher@amd.com> | 2013-01-18 14:28:41 -0500 |
---|---|---|
committer | Alex Deucher <alexander.deucher@amd.com> | 2013-01-31 16:24:50 -0500 |
commit | b7630473def7dad61728c68b4f23d0f2294405bc (patch) | |
tree | 28b0834efd318f22b3d63492672f5d1788065634 /drivers/gpu/drm/radeon/evergreen.c | |
parent | d3cb781e83b39561f717358e95d357e53a0da720 (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.c | 161 |
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 | ||
2330 | static void evergreen_gpu_soft_reset_gfx(struct radeon_device *rdev) | 2330 | static 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 | |||
2396 | static 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) | |||
2421 | static int evergreen_gpu_soft_reset(struct radeon_device *rdev, u32 reset_mask) | 2352 | static 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 */ |