aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu')
-rw-r--r--drivers/gpu/drm/radeon/evergreen.c80
-rw-r--r--drivers/gpu/drm/radeon/evergreend.h1
2 files changed, 56 insertions, 25 deletions
diff --git a/drivers/gpu/drm/radeon/evergreen.c b/drivers/gpu/drm/radeon/evergreen.c
index dcdff14dc13f..061fa0a28900 100644
--- a/drivers/gpu/drm/radeon/evergreen.c
+++ b/drivers/gpu/drm/radeon/evergreen.c
@@ -2306,15 +2306,13 @@ 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
2309static int evergreen_gpu_soft_reset(struct radeon_device *rdev) 2309static void evergreen_gpu_soft_reset_gfx(struct radeon_device *rdev)
2310{ 2310{
2311 struct evergreen_mc_save save; 2311 u32 grbm_reset = 0;
2312 u32 grbm_reset = 0, tmp;
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");
2318 dev_info(rdev->dev, " GRBM_STATUS = 0x%08X\n", 2316 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",
@@ -2331,27 +2329,10 @@ 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 dev_info(rdev->dev, " R_00D034_DMA_STATUS_REG = 0x%08X\n",
2335 RREG32(DMA_STATUS_REG));
2336 evergreen_mc_stop(rdev, &save);
2337 if (evergreen_mc_wait_for_idle(rdev)) {
2338 dev_warn(rdev->dev, "Wait for MC idle timedout !\n");
2339 }
2340 2332
2341 /* Disable CP parsing/prefetching */ 2333 /* Disable CP parsing/prefetching */
2342 WREG32(CP_ME_CNTL, CP_ME_HALT | CP_PFP_HALT); 2334 WREG32(CP_ME_CNTL, CP_ME_HALT | CP_PFP_HALT);
2343 2335
2344 /* Disable DMA */
2345 tmp = RREG32(DMA_RB_CNTL);
2346 tmp &= ~DMA_RB_ENABLE;
2347 WREG32(DMA_RB_CNTL, tmp);
2348
2349 /* Reset dma */
2350 WREG32(SRBM_SOFT_RESET, SOFT_RESET_DMA);
2351 RREG32(SRBM_SOFT_RESET);
2352 udelay(50);
2353 WREG32(SRBM_SOFT_RESET, 0);
2354
2355 /* reset all the gfx blocks */ 2336 /* reset all the gfx blocks */
2356 grbm_reset = (SOFT_RESET_CP | 2337 grbm_reset = (SOFT_RESET_CP |
2357 SOFT_RESET_CB | 2338 SOFT_RESET_CB |
@@ -2372,8 +2353,7 @@ static int evergreen_gpu_soft_reset(struct radeon_device *rdev)
2372 udelay(50); 2353 udelay(50);
2373 WREG32(GRBM_SOFT_RESET, 0); 2354 WREG32(GRBM_SOFT_RESET, 0);
2374 (void)RREG32(GRBM_SOFT_RESET); 2355 (void)RREG32(GRBM_SOFT_RESET);
2375 /* Wait a little for things to settle down */ 2356
2376 udelay(50);
2377 dev_info(rdev->dev, " GRBM_STATUS = 0x%08X\n", 2357 dev_info(rdev->dev, " GRBM_STATUS = 0x%08X\n",
2378 RREG32(GRBM_STATUS)); 2358 RREG32(GRBM_STATUS));
2379 dev_info(rdev->dev, " GRBM_STATUS_SE0 = 0x%08X\n", 2359 dev_info(rdev->dev, " GRBM_STATUS_SE0 = 0x%08X\n",
@@ -2390,15 +2370,65 @@ static int evergreen_gpu_soft_reset(struct radeon_device *rdev)
2390 RREG32(CP_BUSY_STAT)); 2370 RREG32(CP_BUSY_STAT));
2391 dev_info(rdev->dev, " R_008680_CP_STAT = 0x%08X\n", 2371 dev_info(rdev->dev, " R_008680_CP_STAT = 0x%08X\n",
2392 RREG32(CP_STAT)); 2372 RREG32(CP_STAT));
2373}
2374
2375static 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
2393 dev_info(rdev->dev, " R_00D034_DMA_STATUS_REG = 0x%08X\n", 2396 dev_info(rdev->dev, " R_00D034_DMA_STATUS_REG = 0x%08X\n",
2394 RREG32(DMA_STATUS_REG)); 2397 RREG32(DMA_STATUS_REG));
2398}
2399
2400static 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
2395 evergreen_mc_resume(rdev, &save); 2423 evergreen_mc_resume(rdev, &save);
2396 return 0; 2424 return 0;
2397} 2425}
2398 2426
2399int evergreen_asic_reset(struct radeon_device *rdev) 2427int evergreen_asic_reset(struct radeon_device *rdev)
2400{ 2428{
2401 return evergreen_gpu_soft_reset(rdev); 2429 return evergreen_gpu_soft_reset(rdev, (RADEON_RESET_GFX |
2430 RADEON_RESET_COMPUTE |
2431 RADEON_RESET_DMA));
2402} 2432}
2403 2433
2404/* Interrupts */ 2434/* Interrupts */
diff --git a/drivers/gpu/drm/radeon/evergreend.h b/drivers/gpu/drm/radeon/evergreend.h
index 5786a32e7bda..0bfd0e9e469b 100644
--- a/drivers/gpu/drm/radeon/evergreend.h
+++ b/drivers/gpu/drm/radeon/evergreend.h
@@ -2037,5 +2037,6 @@
2037# define DMA_RPTR_WRITEBACK_SWAP_ENABLE (1 << 13) /* 8IN32 */ 2037# define DMA_RPTR_WRITEBACK_SWAP_ENABLE (1 << 13) /* 8IN32 */
2038# define DMA_RPTR_WRITEBACK_TIMER(x) ((x) << 16) /* log2 */ 2038# define DMA_RPTR_WRITEBACK_TIMER(x) ((x) << 16) /* log2 */
2039#define DMA_STATUS_REG 0xd034 2039#define DMA_STATUS_REG 0xd034
2040# define DMA_IDLE (1 << 0)
2040 2041
2041#endif 2042#endif