aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorAlex Deucher <alexander.deucher@amd.com>2013-01-18 13:53:37 -0500
committerAlex Deucher <alexander.deucher@amd.com>2013-01-31 16:24:49 -0500
commitd3cb781e83b39561f717358e95d357e53a0da720 (patch)
tree35681fcb7b3d1d9c6016600b6078abadbec6f6a6 /drivers
parent410a3418a88cc1273a281d347687f736fc39dd86 (diff)
drm/radeon: rework GPU reset on r6xx/r7xx
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')
-rw-r--r--drivers/gpu/drm/radeon/r600.c249
-rw-r--r--drivers/gpu/drm/radeon/r600d.h2
2 files changed, 129 insertions, 122 deletions
diff --git a/drivers/gpu/drm/radeon/r600.c b/drivers/gpu/drm/radeon/r600.c
index a6208178a6f2..083eeb0b4fd1 100644
--- a/drivers/gpu/drm/radeon/r600.c
+++ b/drivers/gpu/drm/radeon/r600.c
@@ -1266,122 +1266,22 @@ void r600_set_bios_scratch_engine_hung(struct radeon_device *rdev, bool hung)
1266 WREG32(R600_BIOS_3_SCRATCH, tmp); 1266 WREG32(R600_BIOS_3_SCRATCH, tmp);
1267} 1267}
1268 1268
1269/* We doesn't check that the GPU really needs a reset we simply do the 1269static void r600_print_gpu_status_regs(struct radeon_device *rdev)
1270 * reset, it's up to the caller to determine if the GPU needs one. We
1271 * might add an helper function to check that.
1272 */
1273static void r600_gpu_soft_reset_gfx(struct radeon_device *rdev)
1274{ 1270{
1275 u32 grbm_busy_mask = S_008010_VC_BUSY(1) | S_008010_VGT_BUSY_NO_DMA(1) |
1276 S_008010_VGT_BUSY(1) | S_008010_TA03_BUSY(1) |
1277 S_008010_TC_BUSY(1) | S_008010_SX_BUSY(1) |
1278 S_008010_SH_BUSY(1) | S_008010_SPI03_BUSY(1) |
1279 S_008010_SMX_BUSY(1) | S_008010_SC_BUSY(1) |
1280 S_008010_PA_BUSY(1) | S_008010_DB03_BUSY(1) |
1281 S_008010_CR_BUSY(1) | S_008010_CB03_BUSY(1) |
1282 S_008010_GUI_ACTIVE(1);
1283 u32 grbm2_busy_mask = S_008014_SPI0_BUSY(1) | S_008014_SPI1_BUSY(1) |
1284 S_008014_SPI2_BUSY(1) | S_008014_SPI3_BUSY(1) |
1285 S_008014_TA0_BUSY(1) | S_008014_TA1_BUSY(1) |
1286 S_008014_TA2_BUSY(1) | S_008014_TA3_BUSY(1) |
1287 S_008014_DB0_BUSY(1) | S_008014_DB1_BUSY(1) |
1288 S_008014_DB2_BUSY(1) | S_008014_DB3_BUSY(1) |
1289 S_008014_CB0_BUSY(1) | S_008014_CB1_BUSY(1) |
1290 S_008014_CB2_BUSY(1) | S_008014_CB3_BUSY(1);
1291 u32 tmp;
1292
1293 if (!(RREG32(GRBM_STATUS) & GUI_ACTIVE))
1294 return;
1295
1296 dev_info(rdev->dev, " R_008010_GRBM_STATUS = 0x%08X\n",
1297 RREG32(R_008010_GRBM_STATUS));
1298 dev_info(rdev->dev, " R_008014_GRBM_STATUS2 = 0x%08X\n",
1299 RREG32(R_008014_GRBM_STATUS2));
1300 dev_info(rdev->dev, " R_000E50_SRBM_STATUS = 0x%08X\n",
1301 RREG32(R_000E50_SRBM_STATUS));
1302 dev_info(rdev->dev, " R_008674_CP_STALLED_STAT1 = 0x%08X\n",
1303 RREG32(CP_STALLED_STAT1));
1304 dev_info(rdev->dev, " R_008678_CP_STALLED_STAT2 = 0x%08X\n",
1305 RREG32(CP_STALLED_STAT2));
1306 dev_info(rdev->dev, " R_00867C_CP_BUSY_STAT = 0x%08X\n",
1307 RREG32(CP_BUSY_STAT));
1308 dev_info(rdev->dev, " R_008680_CP_STAT = 0x%08X\n",
1309 RREG32(CP_STAT));
1310
1311 /* Disable CP parsing/prefetching */
1312 WREG32(R_0086D8_CP_ME_CNTL, S_0086D8_CP_ME_HALT(1));
1313
1314 /* Check if any of the rendering block is busy and reset it */
1315 if ((RREG32(R_008010_GRBM_STATUS) & grbm_busy_mask) ||
1316 (RREG32(R_008014_GRBM_STATUS2) & grbm2_busy_mask)) {
1317 tmp = S_008020_SOFT_RESET_CR(1) |
1318 S_008020_SOFT_RESET_DB(1) |
1319 S_008020_SOFT_RESET_CB(1) |
1320 S_008020_SOFT_RESET_PA(1) |
1321 S_008020_SOFT_RESET_SC(1) |
1322 S_008020_SOFT_RESET_SMX(1) |
1323 S_008020_SOFT_RESET_SPI(1) |
1324 S_008020_SOFT_RESET_SX(1) |
1325 S_008020_SOFT_RESET_SH(1) |
1326 S_008020_SOFT_RESET_TC(1) |
1327 S_008020_SOFT_RESET_TA(1) |
1328 S_008020_SOFT_RESET_VC(1) |
1329 S_008020_SOFT_RESET_VGT(1);
1330 dev_info(rdev->dev, " R_008020_GRBM_SOFT_RESET=0x%08X\n", tmp);
1331 WREG32(R_008020_GRBM_SOFT_RESET, tmp);
1332 RREG32(R_008020_GRBM_SOFT_RESET);
1333 mdelay(15);
1334 WREG32(R_008020_GRBM_SOFT_RESET, 0);
1335 }
1336 /* Reset CP (we always reset CP) */
1337 tmp = S_008020_SOFT_RESET_CP(1);
1338 dev_info(rdev->dev, "R_008020_GRBM_SOFT_RESET=0x%08X\n", tmp);
1339 WREG32(R_008020_GRBM_SOFT_RESET, tmp);
1340 RREG32(R_008020_GRBM_SOFT_RESET);
1341 mdelay(15);
1342 WREG32(R_008020_GRBM_SOFT_RESET, 0);
1343
1344 dev_info(rdev->dev, " R_008010_GRBM_STATUS = 0x%08X\n", 1271 dev_info(rdev->dev, " R_008010_GRBM_STATUS = 0x%08X\n",
1345 RREG32(R_008010_GRBM_STATUS)); 1272 RREG32(R_008010_GRBM_STATUS));
1346 dev_info(rdev->dev, " R_008014_GRBM_STATUS2 = 0x%08X\n", 1273 dev_info(rdev->dev, " R_008014_GRBM_STATUS2 = 0x%08X\n",
1347 RREG32(R_008014_GRBM_STATUS2)); 1274 RREG32(R_008014_GRBM_STATUS2));
1348 dev_info(rdev->dev, " R_000E50_SRBM_STATUS = 0x%08X\n", 1275 dev_info(rdev->dev, " R_000E50_SRBM_STATUS = 0x%08X\n",
1349 RREG32(R_000E50_SRBM_STATUS)); 1276 RREG32(R_000E50_SRBM_STATUS));
1350 dev_info(rdev->dev, " R_008674_CP_STALLED_STAT1 = 0x%08X\n", 1277 dev_info(rdev->dev, " R_008674_CP_STALLED_STAT1 = 0x%08X\n",
1351 RREG32(CP_STALLED_STAT1)); 1278 RREG32(CP_STALLED_STAT1));
1352 dev_info(rdev->dev, " R_008678_CP_STALLED_STAT2 = 0x%08X\n", 1279 dev_info(rdev->dev, " R_008678_CP_STALLED_STAT2 = 0x%08X\n",
1353 RREG32(CP_STALLED_STAT2)); 1280 RREG32(CP_STALLED_STAT2));
1354 dev_info(rdev->dev, " R_00867C_CP_BUSY_STAT = 0x%08X\n", 1281 dev_info(rdev->dev, " R_00867C_CP_BUSY_STAT = 0x%08X\n",
1355 RREG32(CP_BUSY_STAT)); 1282 RREG32(CP_BUSY_STAT));
1356 dev_info(rdev->dev, " R_008680_CP_STAT = 0x%08X\n", 1283 dev_info(rdev->dev, " R_008680_CP_STAT = 0x%08X\n",
1357 RREG32(CP_STAT)); 1284 RREG32(CP_STAT));
1358
1359}
1360
1361static void r600_gpu_soft_reset_dma(struct radeon_device *rdev)
1362{
1363 u32 tmp;
1364
1365 if (RREG32(DMA_STATUS_REG) & DMA_IDLE)
1366 return;
1367
1368 dev_info(rdev->dev, " R_00D034_DMA_STATUS_REG = 0x%08X\n",
1369 RREG32(DMA_STATUS_REG));
1370
1371 /* Disable DMA */
1372 tmp = RREG32(DMA_RB_CNTL);
1373 tmp &= ~DMA_RB_ENABLE;
1374 WREG32(DMA_RB_CNTL, tmp);
1375
1376 /* Reset dma */
1377 if (rdev->family >= CHIP_RV770)
1378 WREG32(SRBM_SOFT_RESET, RV770_SOFT_RESET_DMA);
1379 else
1380 WREG32(SRBM_SOFT_RESET, SOFT_RESET_DMA);
1381 RREG32(SRBM_SOFT_RESET);
1382 udelay(50);
1383 WREG32(SRBM_SOFT_RESET, 0);
1384
1385 dev_info(rdev->dev, " R_00D034_DMA_STATUS_REG = 0x%08X\n", 1285 dev_info(rdev->dev, " R_00D034_DMA_STATUS_REG = 0x%08X\n",
1386 RREG32(DMA_STATUS_REG)); 1286 RREG32(DMA_STATUS_REG));
1387} 1287}
@@ -1389,9 +1289,12 @@ static void r600_gpu_soft_reset_dma(struct radeon_device *rdev)
1389static int r600_gpu_soft_reset(struct radeon_device *rdev, u32 reset_mask) 1289static int r600_gpu_soft_reset(struct radeon_device *rdev, u32 reset_mask)
1390{ 1290{
1391 struct rv515_mc_save save; 1291 struct rv515_mc_save save;
1292 u32 grbm_soft_reset = 0, srbm_soft_reset = 0;
1293 u32 tmp;
1294 int ret = 0;
1392 1295
1393 if (!(RREG32(GRBM_STATUS) & GUI_ACTIVE)) 1296 if (!(RREG32(GRBM_STATUS) & GUI_ACTIVE))
1394 reset_mask &= ~(RADEON_RESET_GFX | RADEON_RESET_COMPUTE); 1297 reset_mask &= ~(RADEON_RESET_GFX | RADEON_RESET_COMPUTE | RADEON_RESET_CP);
1395 1298
1396 if (RREG32(DMA_STATUS_REG) & DMA_IDLE) 1299 if (RREG32(DMA_STATUS_REG) & DMA_IDLE)
1397 reset_mask &= ~RADEON_RESET_DMA; 1300 reset_mask &= ~RADEON_RESET_DMA;
@@ -1401,6 +1304,8 @@ static int r600_gpu_soft_reset(struct radeon_device *rdev, u32 reset_mask)
1401 1304
1402 dev_info(rdev->dev, "GPU softreset: 0x%08X\n", reset_mask); 1305 dev_info(rdev->dev, "GPU softreset: 0x%08X\n", reset_mask);
1403 1306
1307 r600_print_gpu_status_regs(rdev);
1308
1404 r600_set_bios_scratch_engine_hung(rdev, true); 1309 r600_set_bios_scratch_engine_hung(rdev, true);
1405 1310
1406 rv515_mc_stop(rdev, &save); 1311 rv515_mc_stop(rdev, &save);
@@ -1408,20 +1313,127 @@ static int r600_gpu_soft_reset(struct radeon_device *rdev, u32 reset_mask)
1408 dev_warn(rdev->dev, "Wait for MC idle timedout !\n"); 1313 dev_warn(rdev->dev, "Wait for MC idle timedout !\n");
1409 } 1314 }
1410 1315
1411 if (reset_mask & (RADEON_RESET_GFX | RADEON_RESET_COMPUTE)) 1316 /* Disable CP parsing/prefetching */
1412 r600_gpu_soft_reset_gfx(rdev); 1317 if (rdev->family >= CHIP_RV770)
1318 WREG32(R_0086D8_CP_ME_CNTL, S_0086D8_CP_ME_HALT(1) | S_0086D8_CP_PFP_HALT(1));
1319 else
1320 WREG32(R_0086D8_CP_ME_CNTL, S_0086D8_CP_ME_HALT(1));
1321
1322 /* disable the RLC */
1323 WREG32(RLC_CNTL, 0);
1324
1325 if (reset_mask & RADEON_RESET_DMA) {
1326 /* Disable DMA */
1327 tmp = RREG32(DMA_RB_CNTL);
1328 tmp &= ~DMA_RB_ENABLE;
1329 WREG32(DMA_RB_CNTL, tmp);
1330 }
1331
1332 mdelay(50);
1333
1334 if (reset_mask & (RADEON_RESET_GFX | RADEON_RESET_COMPUTE)) {
1335 if (rdev->family >= CHIP_RV770)
1336 grbm_soft_reset |= S_008020_SOFT_RESET_DB(1) |
1337 S_008020_SOFT_RESET_CB(1) |
1338 S_008020_SOFT_RESET_PA(1) |
1339 S_008020_SOFT_RESET_SC(1) |
1340 S_008020_SOFT_RESET_SPI(1) |
1341 S_008020_SOFT_RESET_SX(1) |
1342 S_008020_SOFT_RESET_SH(1) |
1343 S_008020_SOFT_RESET_TC(1) |
1344 S_008020_SOFT_RESET_TA(1) |
1345 S_008020_SOFT_RESET_VC(1) |
1346 S_008020_SOFT_RESET_VGT(1);
1347 else
1348 grbm_soft_reset |= S_008020_SOFT_RESET_CR(1) |
1349 S_008020_SOFT_RESET_DB(1) |
1350 S_008020_SOFT_RESET_CB(1) |
1351 S_008020_SOFT_RESET_PA(1) |
1352 S_008020_SOFT_RESET_SC(1) |
1353 S_008020_SOFT_RESET_SMX(1) |
1354 S_008020_SOFT_RESET_SPI(1) |
1355 S_008020_SOFT_RESET_SX(1) |
1356 S_008020_SOFT_RESET_SH(1) |
1357 S_008020_SOFT_RESET_TC(1) |
1358 S_008020_SOFT_RESET_TA(1) |
1359 S_008020_SOFT_RESET_VC(1) |
1360 S_008020_SOFT_RESET_VGT(1);
1361 }
1362
1363 if (reset_mask & RADEON_RESET_CP) {
1364 grbm_soft_reset |= S_008020_SOFT_RESET_CP(1) |
1365 S_008020_SOFT_RESET_VGT(1);
1413 1366
1414 if (reset_mask & RADEON_RESET_DMA) 1367 srbm_soft_reset |= S_000E60_SOFT_RESET_GRBM(1);
1415 r600_gpu_soft_reset_dma(rdev); 1368 }
1369
1370 if (reset_mask & RADEON_RESET_DMA) {
1371 if (rdev->family >= CHIP_RV770)
1372 srbm_soft_reset |= RV770_SOFT_RESET_DMA;
1373 else
1374 srbm_soft_reset |= SOFT_RESET_DMA;
1375 }
1376
1377 if (grbm_soft_reset) {
1378 tmp = RREG32(R_008020_GRBM_SOFT_RESET);
1379 tmp |= grbm_soft_reset;
1380 dev_info(rdev->dev, "R_008020_GRBM_SOFT_RESET=0x%08X\n", tmp);
1381 WREG32(R_008020_GRBM_SOFT_RESET, tmp);
1382 tmp = RREG32(R_008020_GRBM_SOFT_RESET);
1383
1384 udelay(50);
1385
1386 tmp &= ~grbm_soft_reset;
1387 WREG32(R_008020_GRBM_SOFT_RESET, tmp);
1388 tmp = RREG32(R_008020_GRBM_SOFT_RESET);
1389 }
1390
1391 if (srbm_soft_reset) {
1392 tmp = RREG32(SRBM_SOFT_RESET);
1393 tmp |= srbm_soft_reset;
1394 dev_info(rdev->dev, "SRBM_SOFT_RESET=0x%08X\n", tmp);
1395 WREG32(SRBM_SOFT_RESET, tmp);
1396 tmp = RREG32(SRBM_SOFT_RESET);
1397
1398 udelay(50);
1399
1400 tmp &= ~srbm_soft_reset;
1401 WREG32(SRBM_SOFT_RESET, tmp);
1402 tmp = RREG32(SRBM_SOFT_RESET);
1403 }
1416 1404
1417 /* Wait a little for things to settle down */ 1405 /* Wait a little for things to settle down */
1418 mdelay(1); 1406 mdelay(1);
1419 1407
1420 rv515_mc_resume(rdev, &save); 1408 rv515_mc_resume(rdev, &save);
1409 udelay(50);
1421 1410
1422 r600_set_bios_scratch_engine_hung(rdev, false); 1411#if 0
1412 if (reset_mask & (RADEON_RESET_GFX | RADEON_RESET_COMPUTE | RADEON_RESET_CP)) {
1413 if (RREG32(GRBM_STATUS) & GUI_ACTIVE)
1414 ret = -EAGAIN;
1415 }
1423 1416
1424 return 0; 1417 if (reset_mask & RADEON_RESET_DMA) {
1418 if (!(RREG32(DMA_STATUS_REG) & DMA_IDLE))
1419 ret = -EAGAIN;
1420 }
1421#endif
1422
1423 if (!ret)
1424 r600_set_bios_scratch_engine_hung(rdev, false);
1425
1426 r600_print_gpu_status_regs(rdev);
1427
1428 return ret;
1429}
1430
1431int r600_asic_reset(struct radeon_device *rdev)
1432{
1433 return r600_gpu_soft_reset(rdev, (RADEON_RESET_GFX |
1434 RADEON_RESET_COMPUTE |
1435 RADEON_RESET_DMA |
1436 RADEON_RESET_CP));
1425} 1437}
1426 1438
1427bool r600_gpu_is_lockup(struct radeon_device *rdev, struct radeon_ring *ring) 1439bool r600_gpu_is_lockup(struct radeon_device *rdev, struct radeon_ring *ring)
@@ -1465,13 +1477,6 @@ bool r600_dma_is_lockup(struct radeon_device *rdev, struct radeon_ring *ring)
1465 return radeon_ring_test_lockup(rdev, ring); 1477 return radeon_ring_test_lockup(rdev, ring);
1466} 1478}
1467 1479
1468int r600_asic_reset(struct radeon_device *rdev)
1469{
1470 return r600_gpu_soft_reset(rdev, (RADEON_RESET_GFX |
1471 RADEON_RESET_COMPUTE |
1472 RADEON_RESET_DMA));
1473}
1474
1475u32 r6xx_remap_render_backend(struct radeon_device *rdev, 1480u32 r6xx_remap_render_backend(struct radeon_device *rdev,
1476 u32 tiling_pipe_num, 1481 u32 tiling_pipe_num,
1477 u32 max_rb_num, 1482 u32 max_rb_num,
diff --git a/drivers/gpu/drm/radeon/r600d.h b/drivers/gpu/drm/radeon/r600d.h
index 62423b0eb2b9..494ef768966f 100644
--- a/drivers/gpu/drm/radeon/r600d.h
+++ b/drivers/gpu/drm/radeon/r600d.h
@@ -182,6 +182,8 @@
182#define CP_COHER_BASE 0x85F8 182#define CP_COHER_BASE 0x85F8
183#define CP_DEBUG 0xC1FC 183#define CP_DEBUG 0xC1FC
184#define R_0086D8_CP_ME_CNTL 0x86D8 184#define R_0086D8_CP_ME_CNTL 0x86D8
185#define S_0086D8_CP_PFP_HALT(x) (((x) & 1)<<26)
186#define C_0086D8_CP_PFP_HALT(x) ((x) & 0xFBFFFFFF)
185#define S_0086D8_CP_ME_HALT(x) (((x) & 1)<<28) 187#define S_0086D8_CP_ME_HALT(x) (((x) & 1)<<28)
186#define C_0086D8_CP_ME_HALT(x) ((x) & 0xEFFFFFFF) 188#define C_0086D8_CP_ME_HALT(x) ((x) & 0xEFFFFFFF)
187#define CP_ME_RAM_DATA 0xC160 189#define CP_ME_RAM_DATA 0xC160