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, |