diff options
| -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 | /** |
