diff options
author | Alex Deucher <alexander.deucher@amd.com> | 2013-01-03 12:48:05 -0500 |
---|---|---|
committer | Alex Deucher <alexander.deucher@amd.com> | 2013-01-03 21:29:14 -0500 |
commit | 271d6fed6580c0a7af9b74b9aa90d8a62bdb326d (patch) | |
tree | 721455f4839d3298b9e9a23241fd916a80d0c791 | |
parent | 0ecebb9e0d14e9948e0b1529883a776758117d6f (diff) |
drm/radeon: switch to a finer grained reset for cayman/TN
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/ni.c | 109 |
1 files changed, 70 insertions, 39 deletions
diff --git a/drivers/gpu/drm/radeon/ni.c b/drivers/gpu/drm/radeon/ni.c index 8a9a75d1cb00..896f1cbc58a5 100644 --- a/drivers/gpu/drm/radeon/ni.c +++ b/drivers/gpu/drm/radeon/ni.c | |||
@@ -1306,15 +1306,13 @@ void cayman_dma_fini(struct radeon_device *rdev) | |||
1306 | radeon_ring_fini(rdev, &rdev->ring[CAYMAN_RING_TYPE_DMA1_INDEX]); | 1306 | radeon_ring_fini(rdev, &rdev->ring[CAYMAN_RING_TYPE_DMA1_INDEX]); |
1307 | } | 1307 | } |
1308 | 1308 | ||
1309 | static int cayman_gpu_soft_reset(struct radeon_device *rdev) | 1309 | static void cayman_gpu_soft_reset_gfx(struct radeon_device *rdev) |
1310 | { | 1310 | { |
1311 | struct evergreen_mc_save save; | 1311 | u32 grbm_reset = 0; |
1312 | u32 grbm_reset = 0, tmp; | ||
1313 | 1312 | ||
1314 | if (!(RREG32(GRBM_STATUS) & GUI_ACTIVE)) | 1313 | if (!(RREG32(GRBM_STATUS) & GUI_ACTIVE)) |
1315 | return 0; | 1314 | return; |
1316 | 1315 | ||
1317 | dev_info(rdev->dev, "GPU softreset \n"); | ||
1318 | dev_info(rdev->dev, " GRBM_STATUS = 0x%08X\n", | 1316 | dev_info(rdev->dev, " GRBM_STATUS = 0x%08X\n", |
1319 | RREG32(GRBM_STATUS)); | 1317 | RREG32(GRBM_STATUS)); |
1320 | dev_info(rdev->dev, " GRBM_STATUS_SE0 = 0x%08X\n", | 1318 | dev_info(rdev->dev, " GRBM_STATUS_SE0 = 0x%08X\n", |
@@ -1331,41 +1329,10 @@ static int cayman_gpu_soft_reset(struct radeon_device *rdev) | |||
1331 | RREG32(CP_BUSY_STAT)); | 1329 | RREG32(CP_BUSY_STAT)); |
1332 | dev_info(rdev->dev, " R_008680_CP_STAT = 0x%08X\n", | 1330 | dev_info(rdev->dev, " R_008680_CP_STAT = 0x%08X\n", |
1333 | RREG32(CP_STAT)); | 1331 | RREG32(CP_STAT)); |
1334 | dev_info(rdev->dev, " R_00D034_DMA_STATUS_REG = 0x%08X\n", | ||
1335 | RREG32(DMA_STATUS_REG)); | ||
1336 | dev_info(rdev->dev, " VM_CONTEXT0_PROTECTION_FAULT_ADDR 0x%08X\n", | ||
1337 | RREG32(0x14F8)); | ||
1338 | dev_info(rdev->dev, " VM_CONTEXT0_PROTECTION_FAULT_STATUS 0x%08X\n", | ||
1339 | RREG32(0x14D8)); | ||
1340 | dev_info(rdev->dev, " VM_CONTEXT1_PROTECTION_FAULT_ADDR 0x%08X\n", | ||
1341 | RREG32(0x14FC)); | ||
1342 | dev_info(rdev->dev, " VM_CONTEXT1_PROTECTION_FAULT_STATUS 0x%08X\n", | ||
1343 | RREG32(0x14DC)); | ||
1344 | |||
1345 | evergreen_mc_stop(rdev, &save); | ||
1346 | if (evergreen_mc_wait_for_idle(rdev)) { | ||
1347 | dev_warn(rdev->dev, "Wait for MC idle timedout !\n"); | ||
1348 | } | ||
1349 | 1332 | ||
1350 | /* Disable CP parsing/prefetching */ | 1333 | /* Disable CP parsing/prefetching */ |
1351 | WREG32(CP_ME_CNTL, CP_ME_HALT | CP_PFP_HALT); | 1334 | WREG32(CP_ME_CNTL, CP_ME_HALT | CP_PFP_HALT); |
1352 | 1335 | ||
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 | /* Reset dma */ | ||
1364 | WREG32(SRBM_SOFT_RESET, SOFT_RESET_DMA | SOFT_RESET_DMA1); | ||
1365 | RREG32(SRBM_SOFT_RESET); | ||
1366 | udelay(50); | ||
1367 | WREG32(SRBM_SOFT_RESET, 0); | ||
1368 | |||
1369 | /* reset all the gfx blocks */ | 1336 | /* reset all the gfx blocks */ |
1370 | grbm_reset = (SOFT_RESET_CP | | 1337 | grbm_reset = (SOFT_RESET_CP | |
1371 | SOFT_RESET_CB | | 1338 | SOFT_RESET_CB | |
@@ -1387,8 +1354,6 @@ static int cayman_gpu_soft_reset(struct radeon_device *rdev) | |||
1387 | udelay(50); | 1354 | udelay(50); |
1388 | WREG32(GRBM_SOFT_RESET, 0); | 1355 | WREG32(GRBM_SOFT_RESET, 0); |
1389 | (void)RREG32(GRBM_SOFT_RESET); | 1356 | (void)RREG32(GRBM_SOFT_RESET); |
1390 | /* Wait a little for things to settle down */ | ||
1391 | udelay(50); | ||
1392 | 1357 | ||
1393 | dev_info(rdev->dev, " GRBM_STATUS = 0x%08X\n", | 1358 | dev_info(rdev->dev, " GRBM_STATUS = 0x%08X\n", |
1394 | RREG32(GRBM_STATUS)); | 1359 | RREG32(GRBM_STATUS)); |
@@ -1406,15 +1371,81 @@ static int cayman_gpu_soft_reset(struct radeon_device *rdev) | |||
1406 | RREG32(CP_BUSY_STAT)); | 1371 | RREG32(CP_BUSY_STAT)); |
1407 | dev_info(rdev->dev, " R_008680_CP_STAT = 0x%08X\n", | 1372 | dev_info(rdev->dev, " R_008680_CP_STAT = 0x%08X\n", |
1408 | RREG32(CP_STAT)); | 1373 | RREG32(CP_STAT)); |
1374 | |||
1375 | } | ||
1376 | |||
1377 | static void cayman_gpu_soft_reset_dma(struct radeon_device *rdev) | ||
1378 | { | ||
1379 | u32 tmp; | ||
1380 | |||
1381 | if (RREG32(DMA_STATUS_REG) & DMA_IDLE) | ||
1382 | return; | ||
1383 | |||
1409 | dev_info(rdev->dev, " R_00D034_DMA_STATUS_REG = 0x%08X\n", | 1384 | dev_info(rdev->dev, " R_00D034_DMA_STATUS_REG = 0x%08X\n", |
1410 | RREG32(DMA_STATUS_REG)); | 1385 | RREG32(DMA_STATUS_REG)); |
1386 | |||
1387 | /* dma0 */ | ||
1388 | tmp = RREG32(DMA_RB_CNTL + DMA0_REGISTER_OFFSET); | ||
1389 | tmp &= ~DMA_RB_ENABLE; | ||
1390 | WREG32(DMA_RB_CNTL + DMA0_REGISTER_OFFSET, tmp); | ||
1391 | |||
1392 | /* dma1 */ | ||
1393 | tmp = RREG32(DMA_RB_CNTL + DMA1_REGISTER_OFFSET); | ||
1394 | tmp &= ~DMA_RB_ENABLE; | ||
1395 | WREG32(DMA_RB_CNTL + DMA1_REGISTER_OFFSET, tmp); | ||
1396 | |||
1397 | /* Reset dma */ | ||
1398 | WREG32(SRBM_SOFT_RESET, SOFT_RESET_DMA | SOFT_RESET_DMA1); | ||
1399 | RREG32(SRBM_SOFT_RESET); | ||
1400 | udelay(50); | ||
1401 | WREG32(SRBM_SOFT_RESET, 0); | ||
1402 | |||
1403 | dev_info(rdev->dev, " R_00D034_DMA_STATUS_REG = 0x%08X\n", | ||
1404 | RREG32(DMA_STATUS_REG)); | ||
1405 | |||
1406 | } | ||
1407 | |||
1408 | static int cayman_gpu_soft_reset(struct radeon_device *rdev, u32 reset_mask) | ||
1409 | { | ||
1410 | struct evergreen_mc_save save; | ||
1411 | |||
1412 | if (reset_mask == 0) | ||
1413 | return 0; | ||
1414 | |||
1415 | dev_info(rdev->dev, "GPU softreset: 0x%08X\n", reset_mask); | ||
1416 | |||
1417 | dev_info(rdev->dev, " VM_CONTEXT0_PROTECTION_FAULT_ADDR 0x%08X\n", | ||
1418 | RREG32(0x14F8)); | ||
1419 | dev_info(rdev->dev, " VM_CONTEXT0_PROTECTION_FAULT_STATUS 0x%08X\n", | ||
1420 | RREG32(0x14D8)); | ||
1421 | dev_info(rdev->dev, " VM_CONTEXT1_PROTECTION_FAULT_ADDR 0x%08X\n", | ||
1422 | RREG32(0x14FC)); | ||
1423 | dev_info(rdev->dev, " VM_CONTEXT1_PROTECTION_FAULT_STATUS 0x%08X\n", | ||
1424 | RREG32(0x14DC)); | ||
1425 | |||
1426 | evergreen_mc_stop(rdev, &save); | ||
1427 | if (evergreen_mc_wait_for_idle(rdev)) { | ||
1428 | dev_warn(rdev->dev, "Wait for MC idle timedout !\n"); | ||
1429 | } | ||
1430 | |||
1431 | if (reset_mask & (RADEON_RESET_GFX | RADEON_RESET_COMPUTE)) | ||
1432 | cayman_gpu_soft_reset_gfx(rdev); | ||
1433 | |||
1434 | if (reset_mask & RADEON_RESET_DMA) | ||
1435 | cayman_gpu_soft_reset_dma(rdev); | ||
1436 | |||
1437 | /* Wait a little for things to settle down */ | ||
1438 | udelay(50); | ||
1439 | |||
1411 | evergreen_mc_resume(rdev, &save); | 1440 | evergreen_mc_resume(rdev, &save); |
1412 | return 0; | 1441 | return 0; |
1413 | } | 1442 | } |
1414 | 1443 | ||
1415 | int cayman_asic_reset(struct radeon_device *rdev) | 1444 | int cayman_asic_reset(struct radeon_device *rdev) |
1416 | { | 1445 | { |
1417 | return cayman_gpu_soft_reset(rdev); | 1446 | return cayman_gpu_soft_reset(rdev, (RADEON_RESET_GFX | |
1447 | RADEON_RESET_COMPUTE | | ||
1448 | RADEON_RESET_DMA)); | ||
1418 | } | 1449 | } |
1419 | 1450 | ||
1420 | /** | 1451 | /** |