diff options
Diffstat (limited to 'drivers/gpu/drm/radeon/ni.c')
-rw-r--r-- | drivers/gpu/drm/radeon/ni.c | 120 |
1 files changed, 91 insertions, 29 deletions
diff --git a/drivers/gpu/drm/radeon/ni.c b/drivers/gpu/drm/radeon/ni.c index 7bdbcb00aaf2..835992d8d067 100644 --- a/drivers/gpu/drm/radeon/ni.c +++ b/drivers/gpu/drm/radeon/ni.c | |||
@@ -1216,7 +1216,7 @@ void cayman_dma_stop(struct radeon_device *rdev) | |||
1216 | int cayman_dma_resume(struct radeon_device *rdev) | 1216 | int cayman_dma_resume(struct radeon_device *rdev) |
1217 | { | 1217 | { |
1218 | struct radeon_ring *ring; | 1218 | struct radeon_ring *ring; |
1219 | u32 rb_cntl, dma_cntl; | 1219 | u32 rb_cntl, dma_cntl, ib_cntl; |
1220 | u32 rb_bufsz; | 1220 | u32 rb_bufsz; |
1221 | u32 reg_offset, wb_offset; | 1221 | u32 reg_offset, wb_offset; |
1222 | int i, r; | 1222 | int i, r; |
@@ -1265,7 +1265,11 @@ int cayman_dma_resume(struct radeon_device *rdev) | |||
1265 | WREG32(DMA_RB_BASE + reg_offset, ring->gpu_addr >> 8); | 1265 | WREG32(DMA_RB_BASE + reg_offset, ring->gpu_addr >> 8); |
1266 | 1266 | ||
1267 | /* enable DMA IBs */ | 1267 | /* enable DMA IBs */ |
1268 | WREG32(DMA_IB_CNTL + reg_offset, DMA_IB_ENABLE | CMD_VMID_FORCE); | 1268 | ib_cntl = DMA_IB_ENABLE | CMD_VMID_FORCE; |
1269 | #ifdef __BIG_ENDIAN | ||
1270 | ib_cntl |= DMA_IB_SWAP_ENABLE; | ||
1271 | #endif | ||
1272 | WREG32(DMA_IB_CNTL + reg_offset, ib_cntl); | ||
1269 | 1273 | ||
1270 | dma_cntl = RREG32(DMA_CNTL + reg_offset); | 1274 | dma_cntl = RREG32(DMA_CNTL + reg_offset); |
1271 | dma_cntl &= ~CTXEMPTY_INT_ENABLE; | 1275 | dma_cntl &= ~CTXEMPTY_INT_ENABLE; |
@@ -1306,22 +1310,20 @@ void cayman_dma_fini(struct radeon_device *rdev) | |||
1306 | radeon_ring_fini(rdev, &rdev->ring[CAYMAN_RING_TYPE_DMA1_INDEX]); | 1310 | radeon_ring_fini(rdev, &rdev->ring[CAYMAN_RING_TYPE_DMA1_INDEX]); |
1307 | } | 1311 | } |
1308 | 1312 | ||
1309 | static int cayman_gpu_soft_reset(struct radeon_device *rdev) | 1313 | static void cayman_gpu_soft_reset_gfx(struct radeon_device *rdev) |
1310 | { | 1314 | { |
1311 | struct evergreen_mc_save save; | ||
1312 | u32 grbm_reset = 0; | 1315 | u32 grbm_reset = 0; |
1313 | 1316 | ||
1314 | if (!(RREG32(GRBM_STATUS) & GUI_ACTIVE)) | 1317 | if (!(RREG32(GRBM_STATUS) & GUI_ACTIVE)) |
1315 | return 0; | 1318 | return; |
1316 | 1319 | ||
1317 | dev_info(rdev->dev, "GPU softreset \n"); | 1320 | dev_info(rdev->dev, " GRBM_STATUS = 0x%08X\n", |
1318 | dev_info(rdev->dev, " GRBM_STATUS=0x%08X\n", | ||
1319 | RREG32(GRBM_STATUS)); | 1321 | RREG32(GRBM_STATUS)); |
1320 | dev_info(rdev->dev, " GRBM_STATUS_SE0=0x%08X\n", | 1322 | dev_info(rdev->dev, " GRBM_STATUS_SE0 = 0x%08X\n", |
1321 | RREG32(GRBM_STATUS_SE0)); | 1323 | RREG32(GRBM_STATUS_SE0)); |
1322 | dev_info(rdev->dev, " GRBM_STATUS_SE1=0x%08X\n", | 1324 | dev_info(rdev->dev, " GRBM_STATUS_SE1 = 0x%08X\n", |
1323 | RREG32(GRBM_STATUS_SE1)); | 1325 | RREG32(GRBM_STATUS_SE1)); |
1324 | dev_info(rdev->dev, " SRBM_STATUS=0x%08X\n", | 1326 | dev_info(rdev->dev, " SRBM_STATUS = 0x%08X\n", |
1325 | RREG32(SRBM_STATUS)); | 1327 | RREG32(SRBM_STATUS)); |
1326 | dev_info(rdev->dev, " R_008674_CP_STALLED_STAT1 = 0x%08X\n", | 1328 | dev_info(rdev->dev, " R_008674_CP_STALLED_STAT1 = 0x%08X\n", |
1327 | RREG32(CP_STALLED_STAT1)); | 1329 | RREG32(CP_STALLED_STAT1)); |
@@ -1331,19 +1333,7 @@ static int cayman_gpu_soft_reset(struct radeon_device *rdev) | |||
1331 | RREG32(CP_BUSY_STAT)); | 1333 | RREG32(CP_BUSY_STAT)); |
1332 | dev_info(rdev->dev, " R_008680_CP_STAT = 0x%08X\n", | 1334 | dev_info(rdev->dev, " R_008680_CP_STAT = 0x%08X\n", |
1333 | RREG32(CP_STAT)); | 1335 | RREG32(CP_STAT)); |
1334 | dev_info(rdev->dev, " VM_CONTEXT0_PROTECTION_FAULT_ADDR 0x%08X\n", | ||
1335 | RREG32(0x14F8)); | ||
1336 | dev_info(rdev->dev, " VM_CONTEXT0_PROTECTION_FAULT_STATUS 0x%08X\n", | ||
1337 | RREG32(0x14D8)); | ||
1338 | dev_info(rdev->dev, " VM_CONTEXT1_PROTECTION_FAULT_ADDR 0x%08X\n", | ||
1339 | RREG32(0x14FC)); | ||
1340 | dev_info(rdev->dev, " VM_CONTEXT1_PROTECTION_FAULT_STATUS 0x%08X\n", | ||
1341 | RREG32(0x14DC)); | ||
1342 | 1336 | ||
1343 | evergreen_mc_stop(rdev, &save); | ||
1344 | if (evergreen_mc_wait_for_idle(rdev)) { | ||
1345 | dev_warn(rdev->dev, "Wait for MC idle timedout !\n"); | ||
1346 | } | ||
1347 | /* Disable CP parsing/prefetching */ | 1337 | /* Disable CP parsing/prefetching */ |
1348 | WREG32(CP_ME_CNTL, CP_ME_HALT | CP_PFP_HALT); | 1338 | WREG32(CP_ME_CNTL, CP_ME_HALT | CP_PFP_HALT); |
1349 | 1339 | ||
@@ -1368,16 +1358,14 @@ static int cayman_gpu_soft_reset(struct radeon_device *rdev) | |||
1368 | udelay(50); | 1358 | udelay(50); |
1369 | WREG32(GRBM_SOFT_RESET, 0); | 1359 | WREG32(GRBM_SOFT_RESET, 0); |
1370 | (void)RREG32(GRBM_SOFT_RESET); | 1360 | (void)RREG32(GRBM_SOFT_RESET); |
1371 | /* Wait a little for things to settle down */ | ||
1372 | udelay(50); | ||
1373 | 1361 | ||
1374 | dev_info(rdev->dev, " GRBM_STATUS=0x%08X\n", | 1362 | dev_info(rdev->dev, " GRBM_STATUS = 0x%08X\n", |
1375 | RREG32(GRBM_STATUS)); | 1363 | RREG32(GRBM_STATUS)); |
1376 | dev_info(rdev->dev, " GRBM_STATUS_SE0=0x%08X\n", | 1364 | dev_info(rdev->dev, " GRBM_STATUS_SE0 = 0x%08X\n", |
1377 | RREG32(GRBM_STATUS_SE0)); | 1365 | RREG32(GRBM_STATUS_SE0)); |
1378 | dev_info(rdev->dev, " GRBM_STATUS_SE1=0x%08X\n", | 1366 | dev_info(rdev->dev, " GRBM_STATUS_SE1 = 0x%08X\n", |
1379 | RREG32(GRBM_STATUS_SE1)); | 1367 | RREG32(GRBM_STATUS_SE1)); |
1380 | dev_info(rdev->dev, " SRBM_STATUS=0x%08X\n", | 1368 | dev_info(rdev->dev, " SRBM_STATUS = 0x%08X\n", |
1381 | RREG32(SRBM_STATUS)); | 1369 | RREG32(SRBM_STATUS)); |
1382 | dev_info(rdev->dev, " R_008674_CP_STALLED_STAT1 = 0x%08X\n", | 1370 | dev_info(rdev->dev, " R_008674_CP_STALLED_STAT1 = 0x%08X\n", |
1383 | RREG32(CP_STALLED_STAT1)); | 1371 | RREG32(CP_STALLED_STAT1)); |
@@ -1387,13 +1375,87 @@ static int cayman_gpu_soft_reset(struct radeon_device *rdev) | |||
1387 | RREG32(CP_BUSY_STAT)); | 1375 | RREG32(CP_BUSY_STAT)); |
1388 | dev_info(rdev->dev, " R_008680_CP_STAT = 0x%08X\n", | 1376 | dev_info(rdev->dev, " R_008680_CP_STAT = 0x%08X\n", |
1389 | RREG32(CP_STAT)); | 1377 | RREG32(CP_STAT)); |
1378 | |||
1379 | } | ||
1380 | |||
1381 | static void cayman_gpu_soft_reset_dma(struct radeon_device *rdev) | ||
1382 | { | ||
1383 | u32 tmp; | ||
1384 | |||
1385 | if (RREG32(DMA_STATUS_REG) & DMA_IDLE) | ||
1386 | return; | ||
1387 | |||
1388 | dev_info(rdev->dev, " R_00D034_DMA_STATUS_REG = 0x%08X\n", | ||
1389 | RREG32(DMA_STATUS_REG)); | ||
1390 | |||
1391 | /* dma0 */ | ||
1392 | tmp = RREG32(DMA_RB_CNTL + DMA0_REGISTER_OFFSET); | ||
1393 | tmp &= ~DMA_RB_ENABLE; | ||
1394 | WREG32(DMA_RB_CNTL + DMA0_REGISTER_OFFSET, tmp); | ||
1395 | |||
1396 | /* dma1 */ | ||
1397 | tmp = RREG32(DMA_RB_CNTL + DMA1_REGISTER_OFFSET); | ||
1398 | tmp &= ~DMA_RB_ENABLE; | ||
1399 | WREG32(DMA_RB_CNTL + DMA1_REGISTER_OFFSET, tmp); | ||
1400 | |||
1401 | /* Reset dma */ | ||
1402 | WREG32(SRBM_SOFT_RESET, SOFT_RESET_DMA | SOFT_RESET_DMA1); | ||
1403 | RREG32(SRBM_SOFT_RESET); | ||
1404 | udelay(50); | ||
1405 | WREG32(SRBM_SOFT_RESET, 0); | ||
1406 | |||
1407 | dev_info(rdev->dev, " R_00D034_DMA_STATUS_REG = 0x%08X\n", | ||
1408 | RREG32(DMA_STATUS_REG)); | ||
1409 | |||
1410 | } | ||
1411 | |||
1412 | static int cayman_gpu_soft_reset(struct radeon_device *rdev, u32 reset_mask) | ||
1413 | { | ||
1414 | struct evergreen_mc_save save; | ||
1415 | |||
1416 | if (!(RREG32(GRBM_STATUS) & GUI_ACTIVE)) | ||
1417 | reset_mask &= ~(RADEON_RESET_GFX | RADEON_RESET_COMPUTE); | ||
1418 | |||
1419 | if (RREG32(DMA_STATUS_REG) & DMA_IDLE) | ||
1420 | reset_mask &= ~RADEON_RESET_DMA; | ||
1421 | |||
1422 | if (reset_mask == 0) | ||
1423 | return 0; | ||
1424 | |||
1425 | dev_info(rdev->dev, "GPU softreset: 0x%08X\n", reset_mask); | ||
1426 | |||
1427 | dev_info(rdev->dev, " VM_CONTEXT0_PROTECTION_FAULT_ADDR 0x%08X\n", | ||
1428 | RREG32(0x14F8)); | ||
1429 | dev_info(rdev->dev, " VM_CONTEXT0_PROTECTION_FAULT_STATUS 0x%08X\n", | ||
1430 | RREG32(0x14D8)); | ||
1431 | dev_info(rdev->dev, " VM_CONTEXT1_PROTECTION_FAULT_ADDR 0x%08X\n", | ||
1432 | RREG32(0x14FC)); | ||
1433 | dev_info(rdev->dev, " VM_CONTEXT1_PROTECTION_FAULT_STATUS 0x%08X\n", | ||
1434 | RREG32(0x14DC)); | ||
1435 | |||
1436 | evergreen_mc_stop(rdev, &save); | ||
1437 | if (evergreen_mc_wait_for_idle(rdev)) { | ||
1438 | dev_warn(rdev->dev, "Wait for MC idle timedout !\n"); | ||
1439 | } | ||
1440 | |||
1441 | if (reset_mask & (RADEON_RESET_GFX | RADEON_RESET_COMPUTE)) | ||
1442 | cayman_gpu_soft_reset_gfx(rdev); | ||
1443 | |||
1444 | if (reset_mask & RADEON_RESET_DMA) | ||
1445 | cayman_gpu_soft_reset_dma(rdev); | ||
1446 | |||
1447 | /* Wait a little for things to settle down */ | ||
1448 | udelay(50); | ||
1449 | |||
1390 | evergreen_mc_resume(rdev, &save); | 1450 | evergreen_mc_resume(rdev, &save); |
1391 | return 0; | 1451 | return 0; |
1392 | } | 1452 | } |
1393 | 1453 | ||
1394 | int cayman_asic_reset(struct radeon_device *rdev) | 1454 | int cayman_asic_reset(struct radeon_device *rdev) |
1395 | { | 1455 | { |
1396 | return cayman_gpu_soft_reset(rdev); | 1456 | return cayman_gpu_soft_reset(rdev, (RADEON_RESET_GFX | |
1457 | RADEON_RESET_COMPUTE | | ||
1458 | RADEON_RESET_DMA)); | ||
1397 | } | 1459 | } |
1398 | 1460 | ||
1399 | /** | 1461 | /** |