diff options
| author | Alex Deucher <alexander.deucher@amd.com> | 2013-01-03 12:20:35 -0500 |
|---|---|---|
| committer | Alex Deucher <alexander.deucher@amd.com> | 2013-01-03 21:28:24 -0500 |
| commit | 71e3d1578c954cf29f1f4db1c8930d3574025eb0 (patch) | |
| tree | 3471fddaad2c3eb84b3935368bd848bb56dbb390 | |
| parent | ec46c76d506e845d28d60d0a9f0e993d517030f5 (diff) | |
drm/radeon: switch to a finer grained reset for r6xx/7xx
No change in functionality as we currently set all the reset
flags.
Reviewed-by: Jerome Glisse <jglisse@redhat.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
| -rw-r--r-- | drivers/gpu/drm/radeon/r600.c | 85 |
1 files changed, 58 insertions, 27 deletions
diff --git a/drivers/gpu/drm/radeon/r600.c b/drivers/gpu/drm/radeon/r600.c index 721b5afd792a..923f93647042 100644 --- a/drivers/gpu/drm/radeon/r600.c +++ b/drivers/gpu/drm/radeon/r600.c | |||
| @@ -1258,9 +1258,8 @@ void r600_vram_scratch_fini(struct radeon_device *rdev) | |||
| 1258 | * reset, it's up to the caller to determine if the GPU needs one. We | 1258 | * reset, it's up to the caller to determine if the GPU needs one. We |
| 1259 | * might add an helper function to check that. | 1259 | * might add an helper function to check that. |
| 1260 | */ | 1260 | */ |
| 1261 | static int r600_gpu_soft_reset(struct radeon_device *rdev) | 1261 | static void r600_gpu_soft_reset_gfx(struct radeon_device *rdev) |
| 1262 | { | 1262 | { |
| 1263 | struct rv515_mc_save save; | ||
| 1264 | u32 grbm_busy_mask = S_008010_VC_BUSY(1) | S_008010_VGT_BUSY_NO_DMA(1) | | 1263 | u32 grbm_busy_mask = S_008010_VC_BUSY(1) | S_008010_VGT_BUSY_NO_DMA(1) | |
| 1265 | S_008010_VGT_BUSY(1) | S_008010_TA03_BUSY(1) | | 1264 | S_008010_VGT_BUSY(1) | S_008010_TA03_BUSY(1) | |
| 1266 | S_008010_TC_BUSY(1) | S_008010_SX_BUSY(1) | | 1265 | S_008010_TC_BUSY(1) | S_008010_SX_BUSY(1) | |
| @@ -1280,9 +1279,8 @@ static int r600_gpu_soft_reset(struct radeon_device *rdev) | |||
| 1280 | u32 tmp; | 1279 | u32 tmp; |
| 1281 | 1280 | ||
| 1282 | if (!(RREG32(GRBM_STATUS) & GUI_ACTIVE)) | 1281 | if (!(RREG32(GRBM_STATUS) & GUI_ACTIVE)) |
| 1283 | return 0; | 1282 | return; |
| 1284 | 1283 | ||
| 1285 | dev_info(rdev->dev, "GPU softreset \n"); | ||
| 1286 | dev_info(rdev->dev, " R_008010_GRBM_STATUS = 0x%08X\n", | 1284 | dev_info(rdev->dev, " R_008010_GRBM_STATUS = 0x%08X\n", |
| 1287 | RREG32(R_008010_GRBM_STATUS)); | 1285 | RREG32(R_008010_GRBM_STATUS)); |
| 1288 | dev_info(rdev->dev, " R_008014_GRBM_STATUS2 = 0x%08X\n", | 1286 | dev_info(rdev->dev, " R_008014_GRBM_STATUS2 = 0x%08X\n", |
| @@ -1297,30 +1295,10 @@ static int r600_gpu_soft_reset(struct radeon_device *rdev) | |||
| 1297 | RREG32(CP_BUSY_STAT)); | 1295 | RREG32(CP_BUSY_STAT)); |
| 1298 | dev_info(rdev->dev, " R_008680_CP_STAT = 0x%08X\n", | 1296 | dev_info(rdev->dev, " R_008680_CP_STAT = 0x%08X\n", |
| 1299 | RREG32(CP_STAT)); | 1297 | RREG32(CP_STAT)); |
| 1300 | dev_info(rdev->dev, " R_00D034_DMA_STATUS_REG = 0x%08X\n", | ||
| 1301 | RREG32(DMA_STATUS_REG)); | ||
| 1302 | rv515_mc_stop(rdev, &save); | ||
| 1303 | if (r600_mc_wait_for_idle(rdev)) { | ||
| 1304 | dev_warn(rdev->dev, "Wait for MC idle timedout !\n"); | ||
| 1305 | } | ||
| 1306 | 1298 | ||
| 1307 | /* Disable CP parsing/prefetching */ | 1299 | /* Disable CP parsing/prefetching */ |
| 1308 | WREG32(R_0086D8_CP_ME_CNTL, S_0086D8_CP_ME_HALT(1)); | 1300 | WREG32(R_0086D8_CP_ME_CNTL, S_0086D8_CP_ME_HALT(1)); |
| 1309 | 1301 | ||
| 1310 | /* Disable DMA */ | ||
| 1311 | tmp = RREG32(DMA_RB_CNTL); | ||
| 1312 | tmp &= ~DMA_RB_ENABLE; | ||
| 1313 | WREG32(DMA_RB_CNTL, tmp); | ||
| 1314 | |||
| 1315 | /* Reset dma */ | ||
| 1316 | if (rdev->family >= CHIP_RV770) | ||
| 1317 | WREG32(SRBM_SOFT_RESET, RV770_SOFT_RESET_DMA); | ||
| 1318 | else | ||
| 1319 | WREG32(SRBM_SOFT_RESET, SOFT_RESET_DMA); | ||
| 1320 | RREG32(SRBM_SOFT_RESET); | ||
| 1321 | udelay(50); | ||
| 1322 | WREG32(SRBM_SOFT_RESET, 0); | ||
| 1323 | |||
| 1324 | /* Check if any of the rendering block is busy and reset it */ | 1302 | /* Check if any of the rendering block is busy and reset it */ |
| 1325 | if ((RREG32(R_008010_GRBM_STATUS) & grbm_busy_mask) || | 1303 | if ((RREG32(R_008010_GRBM_STATUS) & grbm_busy_mask) || |
| 1326 | (RREG32(R_008014_GRBM_STATUS2) & grbm2_busy_mask)) { | 1304 | (RREG32(R_008014_GRBM_STATUS2) & grbm2_busy_mask)) { |
| @@ -1350,8 +1328,7 @@ static int r600_gpu_soft_reset(struct radeon_device *rdev) | |||
| 1350 | RREG32(R_008020_GRBM_SOFT_RESET); | 1328 | RREG32(R_008020_GRBM_SOFT_RESET); |
| 1351 | mdelay(15); | 1329 | mdelay(15); |
| 1352 | WREG32(R_008020_GRBM_SOFT_RESET, 0); | 1330 | WREG32(R_008020_GRBM_SOFT_RESET, 0); |
| 1353 | /* Wait a little for things to settle down */ | 1331 | |
| 1354 | mdelay(1); | ||
| 1355 | dev_info(rdev->dev, " R_008010_GRBM_STATUS = 0x%08X\n", | 1332 | dev_info(rdev->dev, " R_008010_GRBM_STATUS = 0x%08X\n", |
| 1356 | RREG32(R_008010_GRBM_STATUS)); | 1333 | RREG32(R_008010_GRBM_STATUS)); |
| 1357 | dev_info(rdev->dev, " R_008014_GRBM_STATUS2 = 0x%08X\n", | 1334 | dev_info(rdev->dev, " R_008014_GRBM_STATUS2 = 0x%08X\n", |
| @@ -1366,8 +1343,60 @@ static int r600_gpu_soft_reset(struct radeon_device *rdev) | |||
| 1366 | RREG32(CP_BUSY_STAT)); | 1343 | RREG32(CP_BUSY_STAT)); |
| 1367 | dev_info(rdev->dev, " R_008680_CP_STAT = 0x%08X\n", | 1344 | dev_info(rdev->dev, " R_008680_CP_STAT = 0x%08X\n", |
| 1368 | RREG32(CP_STAT)); | 1345 | RREG32(CP_STAT)); |
| 1346 | |||
| 1347 | } | ||
| 1348 | |||
| 1349 | static void r600_gpu_soft_reset_dma(struct radeon_device *rdev) | ||
| 1350 | { | ||
| 1351 | u32 tmp; | ||
| 1352 | |||
| 1353 | if (RREG32(DMA_STATUS_REG) & DMA_IDLE) | ||
| 1354 | return; | ||
| 1355 | |||
| 1369 | dev_info(rdev->dev, " R_00D034_DMA_STATUS_REG = 0x%08X\n", | 1356 | dev_info(rdev->dev, " R_00D034_DMA_STATUS_REG = 0x%08X\n", |
| 1370 | RREG32(DMA_STATUS_REG)); | 1357 | RREG32(DMA_STATUS_REG)); |
| 1358 | |||
| 1359 | /* Disable DMA */ | ||
| 1360 | tmp = RREG32(DMA_RB_CNTL); | ||
| 1361 | tmp &= ~DMA_RB_ENABLE; | ||
| 1362 | WREG32(DMA_RB_CNTL, tmp); | ||
| 1363 | |||
| 1364 | /* Reset dma */ | ||
| 1365 | if (rdev->family >= CHIP_RV770) | ||
| 1366 | WREG32(SRBM_SOFT_RESET, RV770_SOFT_RESET_DMA); | ||
| 1367 | else | ||
| 1368 | WREG32(SRBM_SOFT_RESET, SOFT_RESET_DMA); | ||
| 1369 | RREG32(SRBM_SOFT_RESET); | ||
| 1370 | udelay(50); | ||
| 1371 | WREG32(SRBM_SOFT_RESET, 0); | ||
| 1372 | |||
| 1373 | dev_info(rdev->dev, " R_00D034_DMA_STATUS_REG = 0x%08X\n", | ||
| 1374 | RREG32(DMA_STATUS_REG)); | ||
| 1375 | } | ||
| 1376 | |||
| 1377 | static int r600_gpu_soft_reset(struct radeon_device *rdev, u32 reset_mask) | ||
| 1378 | { | ||
| 1379 | struct rv515_mc_save save; | ||
| 1380 | |||
| 1381 | if (reset_mask == 0) | ||
| 1382 | return 0; | ||
| 1383 | |||
| 1384 | dev_info(rdev->dev, "GPU softreset: 0x%08X\n", reset_mask); | ||
| 1385 | |||
| 1386 | rv515_mc_stop(rdev, &save); | ||
| 1387 | if (r600_mc_wait_for_idle(rdev)) { | ||
| 1388 | dev_warn(rdev->dev, "Wait for MC idle timedout !\n"); | ||
| 1389 | } | ||
| 1390 | |||
| 1391 | if (reset_mask & (RADEON_RESET_GFX | RADEON_RESET_COMPUTE)) | ||
| 1392 | r600_gpu_soft_reset_gfx(rdev); | ||
| 1393 | |||
| 1394 | if (reset_mask & RADEON_RESET_DMA) | ||
| 1395 | r600_gpu_soft_reset_dma(rdev); | ||
| 1396 | |||
| 1397 | /* Wait a little for things to settle down */ | ||
| 1398 | mdelay(1); | ||
| 1399 | |||
| 1371 | rv515_mc_resume(rdev, &save); | 1400 | rv515_mc_resume(rdev, &save); |
| 1372 | return 0; | 1401 | return 0; |
| 1373 | } | 1402 | } |
| @@ -1415,7 +1444,9 @@ bool r600_dma_is_lockup(struct radeon_device *rdev, struct radeon_ring *ring) | |||
| 1415 | 1444 | ||
| 1416 | int r600_asic_reset(struct radeon_device *rdev) | 1445 | int r600_asic_reset(struct radeon_device *rdev) |
| 1417 | { | 1446 | { |
| 1418 | return r600_gpu_soft_reset(rdev); | 1447 | return r600_gpu_soft_reset(rdev, (RADEON_RESET_GFX | |
| 1448 | RADEON_RESET_COMPUTE | | ||
| 1449 | RADEON_RESET_DMA)); | ||
| 1419 | } | 1450 | } |
| 1420 | 1451 | ||
| 1421 | u32 r6xx_remap_render_backend(struct radeon_device *rdev, | 1452 | u32 r6xx_remap_render_backend(struct radeon_device *rdev, |
