aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/radeon/ni.c
diff options
context:
space:
mode:
authorAlex Deucher <alexander.deucher@amd.com>2013-01-18 14:51:38 -0500
committerAlex Deucher <alexander.deucher@amd.com>2013-01-31 16:24:51 -0500
commit187e359311ac101c3a0c5078e161d64789ef16e0 (patch)
tree3139be3099cd69709386f61dcd34abdd04a74dc7 /drivers/gpu/drm/radeon/ni.c
parentb7630473def7dad61728c68b4f23d0f2294405bc (diff)
drm/radeon: rework GPU reset on cayman/TN
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/ni.c')
-rw-r--r--drivers/gpu/drm/radeon/ni.c198
1 files changed, 91 insertions, 107 deletions
diff --git a/drivers/gpu/drm/radeon/ni.c b/drivers/gpu/drm/radeon/ni.c
index af9e86d2fc07..88f6fbbe4be6 100644
--- a/drivers/gpu/drm/radeon/ni.c
+++ b/drivers/gpu/drm/radeon/ni.c
@@ -34,6 +34,7 @@
34#include "ni_reg.h" 34#include "ni_reg.h"
35#include "cayman_blit_shaders.h" 35#include "cayman_blit_shaders.h"
36 36
37extern void evergreen_print_gpu_status_regs(struct radeon_device *rdev);
37extern void evergreen_mc_stop(struct radeon_device *rdev, struct evergreen_mc_save *save); 38extern void evergreen_mc_stop(struct radeon_device *rdev, struct evergreen_mc_save *save);
38extern void evergreen_mc_resume(struct radeon_device *rdev, struct evergreen_mc_save *save); 39extern void evergreen_mc_resume(struct radeon_device *rdev, struct evergreen_mc_save *save);
39extern int evergreen_mc_wait_for_idle(struct radeon_device *rdev); 40extern int evergreen_mc_wait_for_idle(struct radeon_device *rdev);
@@ -1310,111 +1311,15 @@ void cayman_dma_fini(struct radeon_device *rdev)
1310 radeon_ring_fini(rdev, &rdev->ring[CAYMAN_RING_TYPE_DMA1_INDEX]); 1311 radeon_ring_fini(rdev, &rdev->ring[CAYMAN_RING_TYPE_DMA1_INDEX]);
1311} 1312}
1312 1313
1313static void cayman_gpu_soft_reset_gfx(struct radeon_device *rdev)
1314{
1315 u32 grbm_reset = 0;
1316
1317 if (!(RREG32(GRBM_STATUS) & GUI_ACTIVE))
1318 return;
1319
1320 dev_info(rdev->dev, " GRBM_STATUS = 0x%08X\n",
1321 RREG32(GRBM_STATUS));
1322 dev_info(rdev->dev, " GRBM_STATUS_SE0 = 0x%08X\n",
1323 RREG32(GRBM_STATUS_SE0));
1324 dev_info(rdev->dev, " GRBM_STATUS_SE1 = 0x%08X\n",
1325 RREG32(GRBM_STATUS_SE1));
1326 dev_info(rdev->dev, " SRBM_STATUS = 0x%08X\n",
1327 RREG32(SRBM_STATUS));
1328 dev_info(rdev->dev, " R_008674_CP_STALLED_STAT1 = 0x%08X\n",
1329 RREG32(CP_STALLED_STAT1));
1330 dev_info(rdev->dev, " R_008678_CP_STALLED_STAT2 = 0x%08X\n",
1331 RREG32(CP_STALLED_STAT2));
1332 dev_info(rdev->dev, " R_00867C_CP_BUSY_STAT = 0x%08X\n",
1333 RREG32(CP_BUSY_STAT));
1334 dev_info(rdev->dev, " R_008680_CP_STAT = 0x%08X\n",
1335 RREG32(CP_STAT));
1336
1337 /* Disable CP parsing/prefetching */
1338 WREG32(CP_ME_CNTL, CP_ME_HALT | CP_PFP_HALT);
1339
1340 /* reset all the gfx blocks */
1341 grbm_reset = (SOFT_RESET_CP |
1342 SOFT_RESET_CB |
1343 SOFT_RESET_DB |
1344 SOFT_RESET_GDS |
1345 SOFT_RESET_PA |
1346 SOFT_RESET_SC |
1347 SOFT_RESET_SPI |
1348 SOFT_RESET_SH |
1349 SOFT_RESET_SX |
1350 SOFT_RESET_TC |
1351 SOFT_RESET_TA |
1352 SOFT_RESET_VGT |
1353 SOFT_RESET_IA);
1354
1355 dev_info(rdev->dev, " GRBM_SOFT_RESET=0x%08X\n", grbm_reset);
1356 WREG32(GRBM_SOFT_RESET, grbm_reset);
1357 (void)RREG32(GRBM_SOFT_RESET);
1358 udelay(50);
1359 WREG32(GRBM_SOFT_RESET, 0);
1360 (void)RREG32(GRBM_SOFT_RESET);
1361
1362 dev_info(rdev->dev, " GRBM_STATUS = 0x%08X\n",
1363 RREG32(GRBM_STATUS));
1364 dev_info(rdev->dev, " GRBM_STATUS_SE0 = 0x%08X\n",
1365 RREG32(GRBM_STATUS_SE0));
1366 dev_info(rdev->dev, " GRBM_STATUS_SE1 = 0x%08X\n",
1367 RREG32(GRBM_STATUS_SE1));
1368 dev_info(rdev->dev, " SRBM_STATUS = 0x%08X\n",
1369 RREG32(SRBM_STATUS));
1370 dev_info(rdev->dev, " R_008674_CP_STALLED_STAT1 = 0x%08X\n",
1371 RREG32(CP_STALLED_STAT1));
1372 dev_info(rdev->dev, " R_008678_CP_STALLED_STAT2 = 0x%08X\n",
1373 RREG32(CP_STALLED_STAT2));
1374 dev_info(rdev->dev, " R_00867C_CP_BUSY_STAT = 0x%08X\n",
1375 RREG32(CP_BUSY_STAT));
1376 dev_info(rdev->dev, " R_008680_CP_STAT = 0x%08X\n",
1377 RREG32(CP_STAT));
1378
1379}
1380
1381static void cayman_gpu_soft_reset_dma(struct radeon_device *rdev)
1382{
1383 u32 tmp;
1384
1385 if (RREG32(DMA_STATUS_REG) & DMA_IDLE)
1386 return;
1387
1388 dev_info(rdev->dev, " R_00D034_DMA_STATUS_REG = 0x%08X\n",
1389 RREG32(DMA_STATUS_REG));
1390
1391 /* dma0 */
1392 tmp = RREG32(DMA_RB_CNTL + DMA0_REGISTER_OFFSET);
1393 tmp &= ~DMA_RB_ENABLE;
1394 WREG32(DMA_RB_CNTL + DMA0_REGISTER_OFFSET, tmp);
1395
1396 /* dma1 */
1397 tmp = RREG32(DMA_RB_CNTL + DMA1_REGISTER_OFFSET);
1398 tmp &= ~DMA_RB_ENABLE;
1399 WREG32(DMA_RB_CNTL + DMA1_REGISTER_OFFSET, tmp);
1400
1401 /* Reset dma */
1402 WREG32(SRBM_SOFT_RESET, SOFT_RESET_DMA | SOFT_RESET_DMA1);
1403 RREG32(SRBM_SOFT_RESET);
1404 udelay(50);
1405 WREG32(SRBM_SOFT_RESET, 0);
1406
1407 dev_info(rdev->dev, " R_00D034_DMA_STATUS_REG = 0x%08X\n",
1408 RREG32(DMA_STATUS_REG));
1409
1410}
1411
1412static int cayman_gpu_soft_reset(struct radeon_device *rdev, u32 reset_mask) 1314static int cayman_gpu_soft_reset(struct radeon_device *rdev, u32 reset_mask)
1413{ 1315{
1414 struct evergreen_mc_save save; 1316 struct evergreen_mc_save save;
1317 u32 grbm_soft_reset = 0, srbm_soft_reset = 0;
1318 u32 tmp;
1319 int ret = 0;
1415 1320
1416 if (!(RREG32(GRBM_STATUS) & GUI_ACTIVE)) 1321 if (!(RREG32(GRBM_STATUS) & GUI_ACTIVE))
1417 reset_mask &= ~(RADEON_RESET_GFX | RADEON_RESET_COMPUTE); 1322 reset_mask &= ~(RADEON_RESET_GFX | RADEON_RESET_COMPUTE | RADEON_RESET_CP);
1418 1323
1419 if (RREG32(DMA_STATUS_REG) & DMA_IDLE) 1324 if (RREG32(DMA_STATUS_REG) & DMA_IDLE)
1420 reset_mask &= ~RADEON_RESET_DMA; 1325 reset_mask &= ~RADEON_RESET_DMA;
@@ -1422,10 +1327,9 @@ static int cayman_gpu_soft_reset(struct radeon_device *rdev, u32 reset_mask)
1422 if (reset_mask == 0) 1327 if (reset_mask == 0)
1423 return 0; 1328 return 0;
1424 1329
1425 r600_set_bios_scratch_engine_hung(rdev, true);
1426
1427 dev_info(rdev->dev, "GPU softreset: 0x%08X\n", reset_mask); 1330 dev_info(rdev->dev, "GPU softreset: 0x%08X\n", reset_mask);
1428 1331
1332 evergreen_print_gpu_status_regs(rdev);
1429 dev_info(rdev->dev, " VM_CONTEXT0_PROTECTION_FAULT_ADDR 0x%08X\n", 1333 dev_info(rdev->dev, " VM_CONTEXT0_PROTECTION_FAULT_ADDR 0x%08X\n",
1430 RREG32(0x14F8)); 1334 RREG32(0x14F8));
1431 dev_info(rdev->dev, " VM_CONTEXT0_PROTECTION_FAULT_STATUS 0x%08X\n", 1335 dev_info(rdev->dev, " VM_CONTEXT0_PROTECTION_FAULT_STATUS 0x%08X\n",
@@ -1435,23 +1339,102 @@ static int cayman_gpu_soft_reset(struct radeon_device *rdev, u32 reset_mask)
1435 dev_info(rdev->dev, " VM_CONTEXT1_PROTECTION_FAULT_STATUS 0x%08X\n", 1339 dev_info(rdev->dev, " VM_CONTEXT1_PROTECTION_FAULT_STATUS 0x%08X\n",
1436 RREG32(0x14DC)); 1340 RREG32(0x14DC));
1437 1341
1342 r600_set_bios_scratch_engine_hung(rdev, true);
1343
1438 evergreen_mc_stop(rdev, &save); 1344 evergreen_mc_stop(rdev, &save);
1439 if (evergreen_mc_wait_for_idle(rdev)) { 1345 if (evergreen_mc_wait_for_idle(rdev)) {
1440 dev_warn(rdev->dev, "Wait for MC idle timedout !\n"); 1346 dev_warn(rdev->dev, "Wait for MC idle timedout !\n");
1441 } 1347 }
1442 1348
1443 if (reset_mask & (RADEON_RESET_GFX | RADEON_RESET_COMPUTE)) 1349 /* Disable CP parsing/prefetching */
1444 cayman_gpu_soft_reset_gfx(rdev); 1350 WREG32(CP_ME_CNTL, CP_ME_HALT | CP_PFP_HALT);
1351
1352 if (reset_mask & RADEON_RESET_DMA) {
1353 /* dma0 */
1354 tmp = RREG32(DMA_RB_CNTL + DMA0_REGISTER_OFFSET);
1355 tmp &= ~DMA_RB_ENABLE;
1356 WREG32(DMA_RB_CNTL + DMA0_REGISTER_OFFSET, tmp);
1357
1358 /* dma1 */
1359 tmp = RREG32(DMA_RB_CNTL + DMA1_REGISTER_OFFSET);
1360 tmp &= ~DMA_RB_ENABLE;
1361 WREG32(DMA_RB_CNTL + DMA1_REGISTER_OFFSET, tmp);
1362 }
1363
1364 if (reset_mask & (RADEON_RESET_GFX | RADEON_RESET_COMPUTE)) {
1365 grbm_soft_reset = SOFT_RESET_CB |
1366 SOFT_RESET_DB |
1367 SOFT_RESET_GDS |
1368 SOFT_RESET_PA |
1369 SOFT_RESET_SC |
1370 SOFT_RESET_SPI |
1371 SOFT_RESET_SH |
1372 SOFT_RESET_SX |
1373 SOFT_RESET_TC |
1374 SOFT_RESET_TA |
1375 SOFT_RESET_VGT |
1376 SOFT_RESET_IA;
1377 }
1378
1379 if (reset_mask & RADEON_RESET_CP) {
1380 grbm_soft_reset |= SOFT_RESET_CP | SOFT_RESET_VGT;
1381
1382 srbm_soft_reset |= SOFT_RESET_GRBM;
1383 }
1445 1384
1446 if (reset_mask & RADEON_RESET_DMA) 1385 if (reset_mask & RADEON_RESET_DMA)
1447 cayman_gpu_soft_reset_dma(rdev); 1386 srbm_soft_reset |= SOFT_RESET_DMA | SOFT_RESET_DMA1;
1387
1388 if (grbm_soft_reset) {
1389 tmp = RREG32(GRBM_SOFT_RESET);
1390 tmp |= grbm_soft_reset;
1391 dev_info(rdev->dev, "GRBM_SOFT_RESET=0x%08X\n", tmp);
1392 WREG32(GRBM_SOFT_RESET, tmp);
1393 tmp = RREG32(GRBM_SOFT_RESET);
1394
1395 udelay(50);
1396
1397 tmp &= ~grbm_soft_reset;
1398 WREG32(GRBM_SOFT_RESET, tmp);
1399 tmp = RREG32(GRBM_SOFT_RESET);
1400 }
1401
1402 if (srbm_soft_reset) {
1403 tmp = RREG32(SRBM_SOFT_RESET);
1404 tmp |= srbm_soft_reset;
1405 dev_info(rdev->dev, "SRBM_SOFT_RESET=0x%08X\n", tmp);
1406 WREG32(SRBM_SOFT_RESET, tmp);
1407 tmp = RREG32(SRBM_SOFT_RESET);
1408
1409 udelay(50);
1410
1411 tmp &= ~srbm_soft_reset;
1412 WREG32(SRBM_SOFT_RESET, tmp);
1413 tmp = RREG32(SRBM_SOFT_RESET);
1414 }
1448 1415
1449 /* Wait a little for things to settle down */ 1416 /* Wait a little for things to settle down */
1450 udelay(50); 1417 udelay(50);
1451 1418
1452 evergreen_mc_resume(rdev, &save); 1419 evergreen_mc_resume(rdev, &save);
1420 udelay(50);
1421
1422#if 0
1423 if (reset_mask & (RADEON_RESET_GFX | RADEON_RESET_COMPUTE | RADEON_RESET_CP)) {
1424 if (RREG32(GRBM_STATUS) & GUI_ACTIVE)
1425 ret = -EAGAIN;
1426 }
1427
1428 if (reset_mask & RADEON_RESET_DMA) {
1429 if (!(RREG32(DMA_STATUS_REG) & DMA_IDLE))
1430 ret = -EAGAIN;
1431 }
1432#endif
1433
1434 if (!ret)
1435 r600_set_bios_scratch_engine_hung(rdev, false);
1453 1436
1454 r600_set_bios_scratch_engine_hung(rdev, false); 1437 evergreen_print_gpu_status_regs(rdev);
1455 1438
1456 return 0; 1439 return 0;
1457} 1440}
@@ -1460,7 +1443,8 @@ int cayman_asic_reset(struct radeon_device *rdev)
1460{ 1443{
1461 return cayman_gpu_soft_reset(rdev, (RADEON_RESET_GFX | 1444 return cayman_gpu_soft_reset(rdev, (RADEON_RESET_GFX |
1462 RADEON_RESET_COMPUTE | 1445 RADEON_RESET_COMPUTE |
1463 RADEON_RESET_DMA)); 1446 RADEON_RESET_DMA |
1447 RADEON_RESET_CP));
1464} 1448}
1465 1449
1466/** 1450/**