diff options
Diffstat (limited to 'drivers/gpu/drm/radeon/evergreen.c')
-rw-r--r-- | drivers/gpu/drm/radeon/evergreen.c | 86 |
1 files changed, 66 insertions, 20 deletions
diff --git a/drivers/gpu/drm/radeon/evergreen.c b/drivers/gpu/drm/radeon/evergreen.c index f95d7fc1f5e..061fa0a2890 100644 --- a/drivers/gpu/drm/radeon/evergreen.c +++ b/drivers/gpu/drm/radeon/evergreen.c | |||
@@ -2306,22 +2306,20 @@ bool evergreen_gpu_is_lockup(struct radeon_device *rdev, struct radeon_ring *rin | |||
2306 | return radeon_ring_test_lockup(rdev, ring); | 2306 | return radeon_ring_test_lockup(rdev, ring); |
2307 | } | 2307 | } |
2308 | 2308 | ||
2309 | static int evergreen_gpu_soft_reset(struct radeon_device *rdev) | 2309 | static void evergreen_gpu_soft_reset_gfx(struct radeon_device *rdev) |
2310 | { | 2310 | { |
2311 | struct evergreen_mc_save save; | ||
2312 | u32 grbm_reset = 0; | 2311 | u32 grbm_reset = 0; |
2313 | 2312 | ||
2314 | if (!(RREG32(GRBM_STATUS) & GUI_ACTIVE)) | 2313 | if (!(RREG32(GRBM_STATUS) & GUI_ACTIVE)) |
2315 | return 0; | 2314 | return; |
2316 | 2315 | ||
2317 | dev_info(rdev->dev, "GPU softreset \n"); | 2316 | dev_info(rdev->dev, " GRBM_STATUS = 0x%08X\n", |
2318 | dev_info(rdev->dev, " GRBM_STATUS=0x%08X\n", | ||
2319 | RREG32(GRBM_STATUS)); | 2317 | RREG32(GRBM_STATUS)); |
2320 | dev_info(rdev->dev, " GRBM_STATUS_SE0=0x%08X\n", | 2318 | dev_info(rdev->dev, " GRBM_STATUS_SE0 = 0x%08X\n", |
2321 | RREG32(GRBM_STATUS_SE0)); | 2319 | RREG32(GRBM_STATUS_SE0)); |
2322 | dev_info(rdev->dev, " GRBM_STATUS_SE1=0x%08X\n", | 2320 | dev_info(rdev->dev, " GRBM_STATUS_SE1 = 0x%08X\n", |
2323 | RREG32(GRBM_STATUS_SE1)); | 2321 | RREG32(GRBM_STATUS_SE1)); |
2324 | dev_info(rdev->dev, " SRBM_STATUS=0x%08X\n", | 2322 | dev_info(rdev->dev, " SRBM_STATUS = 0x%08X\n", |
2325 | RREG32(SRBM_STATUS)); | 2323 | RREG32(SRBM_STATUS)); |
2326 | dev_info(rdev->dev, " R_008674_CP_STALLED_STAT1 = 0x%08X\n", | 2324 | dev_info(rdev->dev, " R_008674_CP_STALLED_STAT1 = 0x%08X\n", |
2327 | RREG32(CP_STALLED_STAT1)); | 2325 | RREG32(CP_STALLED_STAT1)); |
@@ -2331,10 +2329,7 @@ static int evergreen_gpu_soft_reset(struct radeon_device *rdev) | |||
2331 | RREG32(CP_BUSY_STAT)); | 2329 | RREG32(CP_BUSY_STAT)); |
2332 | dev_info(rdev->dev, " R_008680_CP_STAT = 0x%08X\n", | 2330 | dev_info(rdev->dev, " R_008680_CP_STAT = 0x%08X\n", |
2333 | RREG32(CP_STAT)); | 2331 | RREG32(CP_STAT)); |
2334 | evergreen_mc_stop(rdev, &save); | 2332 | |
2335 | if (evergreen_mc_wait_for_idle(rdev)) { | ||
2336 | dev_warn(rdev->dev, "Wait for MC idle timedout !\n"); | ||
2337 | } | ||
2338 | /* Disable CP parsing/prefetching */ | 2333 | /* Disable CP parsing/prefetching */ |
2339 | WREG32(CP_ME_CNTL, CP_ME_HALT | CP_PFP_HALT); | 2334 | WREG32(CP_ME_CNTL, CP_ME_HALT | CP_PFP_HALT); |
2340 | 2335 | ||
@@ -2358,15 +2353,14 @@ static int evergreen_gpu_soft_reset(struct radeon_device *rdev) | |||
2358 | udelay(50); | 2353 | udelay(50); |
2359 | WREG32(GRBM_SOFT_RESET, 0); | 2354 | WREG32(GRBM_SOFT_RESET, 0); |
2360 | (void)RREG32(GRBM_SOFT_RESET); | 2355 | (void)RREG32(GRBM_SOFT_RESET); |
2361 | /* Wait a little for things to settle down */ | 2356 | |
2362 | udelay(50); | 2357 | dev_info(rdev->dev, " GRBM_STATUS = 0x%08X\n", |
2363 | dev_info(rdev->dev, " GRBM_STATUS=0x%08X\n", | ||
2364 | RREG32(GRBM_STATUS)); | 2358 | RREG32(GRBM_STATUS)); |
2365 | dev_info(rdev->dev, " GRBM_STATUS_SE0=0x%08X\n", | 2359 | dev_info(rdev->dev, " GRBM_STATUS_SE0 = 0x%08X\n", |
2366 | RREG32(GRBM_STATUS_SE0)); | 2360 | RREG32(GRBM_STATUS_SE0)); |
2367 | dev_info(rdev->dev, " GRBM_STATUS_SE1=0x%08X\n", | 2361 | dev_info(rdev->dev, " GRBM_STATUS_SE1 = 0x%08X\n", |
2368 | RREG32(GRBM_STATUS_SE1)); | 2362 | RREG32(GRBM_STATUS_SE1)); |
2369 | dev_info(rdev->dev, " SRBM_STATUS=0x%08X\n", | 2363 | dev_info(rdev->dev, " SRBM_STATUS = 0x%08X\n", |
2370 | RREG32(SRBM_STATUS)); | 2364 | RREG32(SRBM_STATUS)); |
2371 | dev_info(rdev->dev, " R_008674_CP_STALLED_STAT1 = 0x%08X\n", | 2365 | dev_info(rdev->dev, " R_008674_CP_STALLED_STAT1 = 0x%08X\n", |
2372 | RREG32(CP_STALLED_STAT1)); | 2366 | RREG32(CP_STALLED_STAT1)); |
@@ -2376,13 +2370,65 @@ static int evergreen_gpu_soft_reset(struct radeon_device *rdev) | |||
2376 | RREG32(CP_BUSY_STAT)); | 2370 | RREG32(CP_BUSY_STAT)); |
2377 | dev_info(rdev->dev, " R_008680_CP_STAT = 0x%08X\n", | 2371 | dev_info(rdev->dev, " R_008680_CP_STAT = 0x%08X\n", |
2378 | RREG32(CP_STAT)); | 2372 | RREG32(CP_STAT)); |
2373 | } | ||
2374 | |||
2375 | static void evergreen_gpu_soft_reset_dma(struct radeon_device *rdev) | ||
2376 | { | ||
2377 | u32 tmp; | ||
2378 | |||
2379 | if (RREG32(DMA_STATUS_REG) & DMA_IDLE) | ||
2380 | return; | ||
2381 | |||
2382 | dev_info(rdev->dev, " R_00D034_DMA_STATUS_REG = 0x%08X\n", | ||
2383 | RREG32(DMA_STATUS_REG)); | ||
2384 | |||
2385 | /* Disable DMA */ | ||
2386 | tmp = RREG32(DMA_RB_CNTL); | ||
2387 | tmp &= ~DMA_RB_ENABLE; | ||
2388 | WREG32(DMA_RB_CNTL, tmp); | ||
2389 | |||
2390 | /* Reset dma */ | ||
2391 | WREG32(SRBM_SOFT_RESET, SOFT_RESET_DMA); | ||
2392 | RREG32(SRBM_SOFT_RESET); | ||
2393 | udelay(50); | ||
2394 | WREG32(SRBM_SOFT_RESET, 0); | ||
2395 | |||
2396 | dev_info(rdev->dev, " R_00D034_DMA_STATUS_REG = 0x%08X\n", | ||
2397 | RREG32(DMA_STATUS_REG)); | ||
2398 | } | ||
2399 | |||
2400 | static int evergreen_gpu_soft_reset(struct radeon_device *rdev, u32 reset_mask) | ||
2401 | { | ||
2402 | struct evergreen_mc_save save; | ||
2403 | |||
2404 | if (reset_mask == 0) | ||
2405 | return 0; | ||
2406 | |||
2407 | dev_info(rdev->dev, "GPU softreset: 0x%08X\n", reset_mask); | ||
2408 | |||
2409 | evergreen_mc_stop(rdev, &save); | ||
2410 | if (evergreen_mc_wait_for_idle(rdev)) { | ||
2411 | dev_warn(rdev->dev, "Wait for MC idle timedout !\n"); | ||
2412 | } | ||
2413 | |||
2414 | if (reset_mask & (RADEON_RESET_GFX | RADEON_RESET_COMPUTE)) | ||
2415 | evergreen_gpu_soft_reset_gfx(rdev); | ||
2416 | |||
2417 | if (reset_mask & RADEON_RESET_DMA) | ||
2418 | evergreen_gpu_soft_reset_dma(rdev); | ||
2419 | |||
2420 | /* Wait a little for things to settle down */ | ||
2421 | udelay(50); | ||
2422 | |||
2379 | evergreen_mc_resume(rdev, &save); | 2423 | evergreen_mc_resume(rdev, &save); |
2380 | return 0; | 2424 | return 0; |
2381 | } | 2425 | } |
2382 | 2426 | ||
2383 | int evergreen_asic_reset(struct radeon_device *rdev) | 2427 | int evergreen_asic_reset(struct radeon_device *rdev) |
2384 | { | 2428 | { |
2385 | return evergreen_gpu_soft_reset(rdev); | 2429 | return evergreen_gpu_soft_reset(rdev, (RADEON_RESET_GFX | |
2430 | RADEON_RESET_COMPUTE | | ||
2431 | RADEON_RESET_DMA)); | ||
2386 | } | 2432 | } |
2387 | 2433 | ||
2388 | /* Interrupts */ | 2434 | /* Interrupts */ |
@@ -3215,7 +3261,7 @@ void evergreen_dma_fence_ring_emit(struct radeon_device *rdev, | |||
3215 | radeon_ring_write(ring, DMA_PACKET(DMA_PACKET_TRAP, 0, 0, 0)); | 3261 | radeon_ring_write(ring, DMA_PACKET(DMA_PACKET_TRAP, 0, 0, 0)); |
3216 | /* flush HDP */ | 3262 | /* flush HDP */ |
3217 | radeon_ring_write(ring, DMA_PACKET(DMA_PACKET_SRBM_WRITE, 0, 0, 0)); | 3263 | radeon_ring_write(ring, DMA_PACKET(DMA_PACKET_SRBM_WRITE, 0, 0, 0)); |
3218 | radeon_ring_write(ring, (0xf << 16) | HDP_MEM_COHERENCY_FLUSH_CNTL); | 3264 | radeon_ring_write(ring, (0xf << 16) | (HDP_MEM_COHERENCY_FLUSH_CNTL >> 2)); |
3219 | radeon_ring_write(ring, 1); | 3265 | radeon_ring_write(ring, 1); |
3220 | } | 3266 | } |
3221 | 3267 | ||