diff options
Diffstat (limited to 'drivers/gpu/drm/radeon')
26 files changed, 617 insertions, 136 deletions
diff --git a/drivers/gpu/drm/radeon/evergreen.c b/drivers/gpu/drm/radeon/evergreen.c index f95d7fc1f5e0..4d0e60adbc6d 100644 --- a/drivers/gpu/drm/radeon/evergreen.c +++ b/drivers/gpu/drm/radeon/evergreen.c | |||
@@ -2306,22 +2306,20 @@ bool evergreen_gpu_is_lockup(struct radeon_device *rdev, struct radeon_ring *rin | |||
2306 | return radeon_ring_test_lockup(rdev, ring); | 2306 | return radeon_ring_test_lockup(rdev, ring); |
2307 | } | 2307 | } |
2308 | 2308 | ||
2309 | static int evergreen_gpu_soft_reset(struct radeon_device *rdev) | 2309 | static void evergreen_gpu_soft_reset_gfx(struct radeon_device *rdev) |
2310 | { | 2310 | { |
2311 | struct evergreen_mc_save save; | ||
2312 | u32 grbm_reset = 0; | 2311 | u32 grbm_reset = 0; |
2313 | 2312 | ||
2314 | if (!(RREG32(GRBM_STATUS) & GUI_ACTIVE)) | 2313 | if (!(RREG32(GRBM_STATUS) & GUI_ACTIVE)) |
2315 | return 0; | 2314 | return; |
2316 | 2315 | ||
2317 | dev_info(rdev->dev, "GPU softreset \n"); | 2316 | dev_info(rdev->dev, " GRBM_STATUS = 0x%08X\n", |
2318 | dev_info(rdev->dev, " GRBM_STATUS=0x%08X\n", | ||
2319 | RREG32(GRBM_STATUS)); | 2317 | RREG32(GRBM_STATUS)); |
2320 | dev_info(rdev->dev, " GRBM_STATUS_SE0=0x%08X\n", | 2318 | dev_info(rdev->dev, " GRBM_STATUS_SE0 = 0x%08X\n", |
2321 | RREG32(GRBM_STATUS_SE0)); | 2319 | RREG32(GRBM_STATUS_SE0)); |
2322 | dev_info(rdev->dev, " GRBM_STATUS_SE1=0x%08X\n", | 2320 | dev_info(rdev->dev, " GRBM_STATUS_SE1 = 0x%08X\n", |
2323 | RREG32(GRBM_STATUS_SE1)); | 2321 | RREG32(GRBM_STATUS_SE1)); |
2324 | dev_info(rdev->dev, " SRBM_STATUS=0x%08X\n", | 2322 | dev_info(rdev->dev, " SRBM_STATUS = 0x%08X\n", |
2325 | RREG32(SRBM_STATUS)); | 2323 | RREG32(SRBM_STATUS)); |
2326 | dev_info(rdev->dev, " R_008674_CP_STALLED_STAT1 = 0x%08X\n", | 2324 | dev_info(rdev->dev, " R_008674_CP_STALLED_STAT1 = 0x%08X\n", |
2327 | RREG32(CP_STALLED_STAT1)); | 2325 | RREG32(CP_STALLED_STAT1)); |
@@ -2331,10 +2329,7 @@ static int evergreen_gpu_soft_reset(struct radeon_device *rdev) | |||
2331 | RREG32(CP_BUSY_STAT)); | 2329 | RREG32(CP_BUSY_STAT)); |
2332 | dev_info(rdev->dev, " R_008680_CP_STAT = 0x%08X\n", | 2330 | dev_info(rdev->dev, " R_008680_CP_STAT = 0x%08X\n", |
2333 | RREG32(CP_STAT)); | 2331 | RREG32(CP_STAT)); |
2334 | evergreen_mc_stop(rdev, &save); | 2332 | |
2335 | if (evergreen_mc_wait_for_idle(rdev)) { | ||
2336 | dev_warn(rdev->dev, "Wait for MC idle timedout !\n"); | ||
2337 | } | ||
2338 | /* Disable CP parsing/prefetching */ | 2333 | /* Disable CP parsing/prefetching */ |
2339 | WREG32(CP_ME_CNTL, CP_ME_HALT | CP_PFP_HALT); | 2334 | WREG32(CP_ME_CNTL, CP_ME_HALT | CP_PFP_HALT); |
2340 | 2335 | ||
@@ -2358,15 +2353,14 @@ static int evergreen_gpu_soft_reset(struct radeon_device *rdev) | |||
2358 | udelay(50); | 2353 | udelay(50); |
2359 | WREG32(GRBM_SOFT_RESET, 0); | 2354 | WREG32(GRBM_SOFT_RESET, 0); |
2360 | (void)RREG32(GRBM_SOFT_RESET); | 2355 | (void)RREG32(GRBM_SOFT_RESET); |
2361 | /* Wait a little for things to settle down */ | 2356 | |
2362 | udelay(50); | 2357 | dev_info(rdev->dev, " GRBM_STATUS = 0x%08X\n", |
2363 | dev_info(rdev->dev, " GRBM_STATUS=0x%08X\n", | ||
2364 | RREG32(GRBM_STATUS)); | 2358 | RREG32(GRBM_STATUS)); |
2365 | dev_info(rdev->dev, " GRBM_STATUS_SE0=0x%08X\n", | 2359 | dev_info(rdev->dev, " GRBM_STATUS_SE0 = 0x%08X\n", |
2366 | RREG32(GRBM_STATUS_SE0)); | 2360 | RREG32(GRBM_STATUS_SE0)); |
2367 | dev_info(rdev->dev, " GRBM_STATUS_SE1=0x%08X\n", | 2361 | dev_info(rdev->dev, " GRBM_STATUS_SE1 = 0x%08X\n", |
2368 | RREG32(GRBM_STATUS_SE1)); | 2362 | RREG32(GRBM_STATUS_SE1)); |
2369 | dev_info(rdev->dev, " SRBM_STATUS=0x%08X\n", | 2363 | dev_info(rdev->dev, " SRBM_STATUS = 0x%08X\n", |
2370 | RREG32(SRBM_STATUS)); | 2364 | RREG32(SRBM_STATUS)); |
2371 | dev_info(rdev->dev, " R_008674_CP_STALLED_STAT1 = 0x%08X\n", | 2365 | dev_info(rdev->dev, " R_008674_CP_STALLED_STAT1 = 0x%08X\n", |
2372 | RREG32(CP_STALLED_STAT1)); | 2366 | RREG32(CP_STALLED_STAT1)); |
@@ -2376,13 +2370,71 @@ static int evergreen_gpu_soft_reset(struct radeon_device *rdev) | |||
2376 | RREG32(CP_BUSY_STAT)); | 2370 | RREG32(CP_BUSY_STAT)); |
2377 | dev_info(rdev->dev, " R_008680_CP_STAT = 0x%08X\n", | 2371 | dev_info(rdev->dev, " R_008680_CP_STAT = 0x%08X\n", |
2378 | RREG32(CP_STAT)); | 2372 | RREG32(CP_STAT)); |
2373 | } | ||
2374 | |||
2375 | static void evergreen_gpu_soft_reset_dma(struct radeon_device *rdev) | ||
2376 | { | ||
2377 | u32 tmp; | ||
2378 | |||
2379 | if (RREG32(DMA_STATUS_REG) & DMA_IDLE) | ||
2380 | return; | ||
2381 | |||
2382 | dev_info(rdev->dev, " R_00D034_DMA_STATUS_REG = 0x%08X\n", | ||
2383 | RREG32(DMA_STATUS_REG)); | ||
2384 | |||
2385 | /* Disable DMA */ | ||
2386 | tmp = RREG32(DMA_RB_CNTL); | ||
2387 | tmp &= ~DMA_RB_ENABLE; | ||
2388 | WREG32(DMA_RB_CNTL, tmp); | ||
2389 | |||
2390 | /* Reset dma */ | ||
2391 | WREG32(SRBM_SOFT_RESET, SOFT_RESET_DMA); | ||
2392 | RREG32(SRBM_SOFT_RESET); | ||
2393 | udelay(50); | ||
2394 | WREG32(SRBM_SOFT_RESET, 0); | ||
2395 | |||
2396 | dev_info(rdev->dev, " R_00D034_DMA_STATUS_REG = 0x%08X\n", | ||
2397 | RREG32(DMA_STATUS_REG)); | ||
2398 | } | ||
2399 | |||
2400 | static int evergreen_gpu_soft_reset(struct radeon_device *rdev, u32 reset_mask) | ||
2401 | { | ||
2402 | struct evergreen_mc_save save; | ||
2403 | |||
2404 | if (!(RREG32(GRBM_STATUS) & GUI_ACTIVE)) | ||
2405 | reset_mask &= ~(RADEON_RESET_GFX | RADEON_RESET_COMPUTE); | ||
2406 | |||
2407 | if (RREG32(DMA_STATUS_REG) & DMA_IDLE) | ||
2408 | reset_mask &= ~RADEON_RESET_DMA; | ||
2409 | |||
2410 | if (reset_mask == 0) | ||
2411 | return 0; | ||
2412 | |||
2413 | dev_info(rdev->dev, "GPU softreset: 0x%08X\n", reset_mask); | ||
2414 | |||
2415 | evergreen_mc_stop(rdev, &save); | ||
2416 | if (evergreen_mc_wait_for_idle(rdev)) { | ||
2417 | dev_warn(rdev->dev, "Wait for MC idle timedout !\n"); | ||
2418 | } | ||
2419 | |||
2420 | if (reset_mask & (RADEON_RESET_GFX | RADEON_RESET_COMPUTE)) | ||
2421 | evergreen_gpu_soft_reset_gfx(rdev); | ||
2422 | |||
2423 | if (reset_mask & RADEON_RESET_DMA) | ||
2424 | evergreen_gpu_soft_reset_dma(rdev); | ||
2425 | |||
2426 | /* Wait a little for things to settle down */ | ||
2427 | udelay(50); | ||
2428 | |||
2379 | evergreen_mc_resume(rdev, &save); | 2429 | evergreen_mc_resume(rdev, &save); |
2380 | return 0; | 2430 | return 0; |
2381 | } | 2431 | } |
2382 | 2432 | ||
2383 | int evergreen_asic_reset(struct radeon_device *rdev) | 2433 | int evergreen_asic_reset(struct radeon_device *rdev) |
2384 | { | 2434 | { |
2385 | return evergreen_gpu_soft_reset(rdev); | 2435 | return evergreen_gpu_soft_reset(rdev, (RADEON_RESET_GFX | |
2436 | RADEON_RESET_COMPUTE | | ||
2437 | RADEON_RESET_DMA)); | ||
2386 | } | 2438 | } |
2387 | 2439 | ||
2388 | /* Interrupts */ | 2440 | /* Interrupts */ |
@@ -3215,7 +3267,7 @@ void evergreen_dma_fence_ring_emit(struct radeon_device *rdev, | |||
3215 | radeon_ring_write(ring, DMA_PACKET(DMA_PACKET_TRAP, 0, 0, 0)); | 3267 | radeon_ring_write(ring, DMA_PACKET(DMA_PACKET_TRAP, 0, 0, 0)); |
3216 | /* flush HDP */ | 3268 | /* flush HDP */ |
3217 | radeon_ring_write(ring, DMA_PACKET(DMA_PACKET_SRBM_WRITE, 0, 0, 0)); | 3269 | radeon_ring_write(ring, DMA_PACKET(DMA_PACKET_SRBM_WRITE, 0, 0, 0)); |
3218 | radeon_ring_write(ring, (0xf << 16) | HDP_MEM_COHERENCY_FLUSH_CNTL); | 3270 | radeon_ring_write(ring, (0xf << 16) | (HDP_MEM_COHERENCY_FLUSH_CNTL >> 2)); |
3219 | radeon_ring_write(ring, 1); | 3271 | radeon_ring_write(ring, 1); |
3220 | } | 3272 | } |
3221 | 3273 | ||
diff --git a/drivers/gpu/drm/radeon/evergreend.h b/drivers/gpu/drm/radeon/evergreend.h index cb9baaac9e85..0bfd0e9e469b 100644 --- a/drivers/gpu/drm/radeon/evergreend.h +++ b/drivers/gpu/drm/radeon/evergreend.h | |||
@@ -742,8 +742,9 @@ | |||
742 | #define SOFT_RESET_ROM (1 << 14) | 742 | #define SOFT_RESET_ROM (1 << 14) |
743 | #define SOFT_RESET_SEM (1 << 15) | 743 | #define SOFT_RESET_SEM (1 << 15) |
744 | #define SOFT_RESET_VMC (1 << 17) | 744 | #define SOFT_RESET_VMC (1 << 17) |
745 | #define SOFT_RESET_DMA (1 << 20) | ||
745 | #define SOFT_RESET_TST (1 << 21) | 746 | #define SOFT_RESET_TST (1 << 21) |
746 | #define SOFT_RESET_REGBB (1 << 22) | 747 | #define SOFT_RESET_REGBB (1 << 22) |
747 | #define SOFT_RESET_ORB (1 << 23) | 748 | #define SOFT_RESET_ORB (1 << 23) |
748 | 749 | ||
749 | /* display watermarks */ | 750 | /* display watermarks */ |
@@ -2027,4 +2028,15 @@ | |||
2027 | /* cayman packet3 addition */ | 2028 | /* cayman packet3 addition */ |
2028 | #define CAYMAN_PACKET3_DEALLOC_STATE 0x14 | 2029 | #define CAYMAN_PACKET3_DEALLOC_STATE 0x14 |
2029 | 2030 | ||
2031 | /* DMA regs common on r6xx/r7xx/evergreen/ni */ | ||
2032 | #define DMA_RB_CNTL 0xd000 | ||
2033 | # define DMA_RB_ENABLE (1 << 0) | ||
2034 | # define DMA_RB_SIZE(x) ((x) << 1) /* log2 */ | ||
2035 | # define DMA_RB_SWAP_ENABLE (1 << 9) /* 8IN32 */ | ||
2036 | # define DMA_RPTR_WRITEBACK_ENABLE (1 << 12) | ||
2037 | # define DMA_RPTR_WRITEBACK_SWAP_ENABLE (1 << 13) /* 8IN32 */ | ||
2038 | # define DMA_RPTR_WRITEBACK_TIMER(x) ((x) << 16) /* log2 */ | ||
2039 | #define DMA_STATUS_REG 0xd034 | ||
2040 | # define DMA_IDLE (1 << 0) | ||
2041 | |||
2030 | #endif | 2042 | #endif |
diff --git a/drivers/gpu/drm/radeon/ni.c b/drivers/gpu/drm/radeon/ni.c index 7bdbcb00aaf2..59acabb45c9b 100644 --- a/drivers/gpu/drm/radeon/ni.c +++ b/drivers/gpu/drm/radeon/ni.c | |||
@@ -1306,22 +1306,20 @@ 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; | ||
1312 | u32 grbm_reset = 0; | 1311 | u32 grbm_reset = 0; |
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"); | 1316 | dev_info(rdev->dev, " GRBM_STATUS = 0x%08X\n", |
1318 | 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", |
1321 | RREG32(GRBM_STATUS_SE0)); | 1319 | RREG32(GRBM_STATUS_SE0)); |
1322 | dev_info(rdev->dev, " GRBM_STATUS_SE1=0x%08X\n", | 1320 | dev_info(rdev->dev, " GRBM_STATUS_SE1 = 0x%08X\n", |
1323 | RREG32(GRBM_STATUS_SE1)); | 1321 | RREG32(GRBM_STATUS_SE1)); |
1324 | dev_info(rdev->dev, " SRBM_STATUS=0x%08X\n", | 1322 | dev_info(rdev->dev, " SRBM_STATUS = 0x%08X\n", |
1325 | RREG32(SRBM_STATUS)); | 1323 | RREG32(SRBM_STATUS)); |
1326 | dev_info(rdev->dev, " R_008674_CP_STALLED_STAT1 = 0x%08X\n", | 1324 | dev_info(rdev->dev, " R_008674_CP_STALLED_STAT1 = 0x%08X\n", |
1327 | RREG32(CP_STALLED_STAT1)); | 1325 | RREG32(CP_STALLED_STAT1)); |
@@ -1331,19 +1329,7 @@ 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, " 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 | 1332 | ||
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 */ | 1333 | /* Disable CP parsing/prefetching */ |
1348 | WREG32(CP_ME_CNTL, CP_ME_HALT | CP_PFP_HALT); | 1334 | WREG32(CP_ME_CNTL, CP_ME_HALT | CP_PFP_HALT); |
1349 | 1335 | ||
@@ -1368,16 +1354,14 @@ static int cayman_gpu_soft_reset(struct radeon_device *rdev) | |||
1368 | udelay(50); | 1354 | udelay(50); |
1369 | WREG32(GRBM_SOFT_RESET, 0); | 1355 | WREG32(GRBM_SOFT_RESET, 0); |
1370 | (void)RREG32(GRBM_SOFT_RESET); | 1356 | (void)RREG32(GRBM_SOFT_RESET); |
1371 | /* Wait a little for things to settle down */ | ||
1372 | udelay(50); | ||
1373 | 1357 | ||
1374 | dev_info(rdev->dev, " GRBM_STATUS=0x%08X\n", | 1358 | dev_info(rdev->dev, " GRBM_STATUS = 0x%08X\n", |
1375 | RREG32(GRBM_STATUS)); | 1359 | RREG32(GRBM_STATUS)); |
1376 | dev_info(rdev->dev, " GRBM_STATUS_SE0=0x%08X\n", | 1360 | dev_info(rdev->dev, " GRBM_STATUS_SE0 = 0x%08X\n", |
1377 | RREG32(GRBM_STATUS_SE0)); | 1361 | RREG32(GRBM_STATUS_SE0)); |
1378 | dev_info(rdev->dev, " GRBM_STATUS_SE1=0x%08X\n", | 1362 | dev_info(rdev->dev, " GRBM_STATUS_SE1 = 0x%08X\n", |
1379 | RREG32(GRBM_STATUS_SE1)); | 1363 | RREG32(GRBM_STATUS_SE1)); |
1380 | dev_info(rdev->dev, " SRBM_STATUS=0x%08X\n", | 1364 | dev_info(rdev->dev, " SRBM_STATUS = 0x%08X\n", |
1381 | RREG32(SRBM_STATUS)); | 1365 | RREG32(SRBM_STATUS)); |
1382 | dev_info(rdev->dev, " R_008674_CP_STALLED_STAT1 = 0x%08X\n", | 1366 | dev_info(rdev->dev, " R_008674_CP_STALLED_STAT1 = 0x%08X\n", |
1383 | RREG32(CP_STALLED_STAT1)); | 1367 | RREG32(CP_STALLED_STAT1)); |
@@ -1387,13 +1371,87 @@ static int cayman_gpu_soft_reset(struct radeon_device *rdev) | |||
1387 | RREG32(CP_BUSY_STAT)); | 1371 | RREG32(CP_BUSY_STAT)); |
1388 | dev_info(rdev->dev, " R_008680_CP_STAT = 0x%08X\n", | 1372 | dev_info(rdev->dev, " R_008680_CP_STAT = 0x%08X\n", |
1389 | 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 | |||
1384 | dev_info(rdev->dev, " R_00D034_DMA_STATUS_REG = 0x%08X\n", | ||
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 (!(RREG32(GRBM_STATUS) & GUI_ACTIVE)) | ||
1413 | reset_mask &= ~(RADEON_RESET_GFX | RADEON_RESET_COMPUTE); | ||
1414 | |||
1415 | if (RREG32(DMA_STATUS_REG) & DMA_IDLE) | ||
1416 | reset_mask &= ~RADEON_RESET_DMA; | ||
1417 | |||
1418 | if (reset_mask == 0) | ||
1419 | return 0; | ||
1420 | |||
1421 | dev_info(rdev->dev, "GPU softreset: 0x%08X\n", reset_mask); | ||
1422 | |||
1423 | dev_info(rdev->dev, " VM_CONTEXT0_PROTECTION_FAULT_ADDR 0x%08X\n", | ||
1424 | RREG32(0x14F8)); | ||
1425 | dev_info(rdev->dev, " VM_CONTEXT0_PROTECTION_FAULT_STATUS 0x%08X\n", | ||
1426 | RREG32(0x14D8)); | ||
1427 | dev_info(rdev->dev, " VM_CONTEXT1_PROTECTION_FAULT_ADDR 0x%08X\n", | ||
1428 | RREG32(0x14FC)); | ||
1429 | dev_info(rdev->dev, " VM_CONTEXT1_PROTECTION_FAULT_STATUS 0x%08X\n", | ||
1430 | RREG32(0x14DC)); | ||
1431 | |||
1432 | evergreen_mc_stop(rdev, &save); | ||
1433 | if (evergreen_mc_wait_for_idle(rdev)) { | ||
1434 | dev_warn(rdev->dev, "Wait for MC idle timedout !\n"); | ||
1435 | } | ||
1436 | |||
1437 | if (reset_mask & (RADEON_RESET_GFX | RADEON_RESET_COMPUTE)) | ||
1438 | cayman_gpu_soft_reset_gfx(rdev); | ||
1439 | |||
1440 | if (reset_mask & RADEON_RESET_DMA) | ||
1441 | cayman_gpu_soft_reset_dma(rdev); | ||
1442 | |||
1443 | /* Wait a little for things to settle down */ | ||
1444 | udelay(50); | ||
1445 | |||
1390 | evergreen_mc_resume(rdev, &save); | 1446 | evergreen_mc_resume(rdev, &save); |
1391 | return 0; | 1447 | return 0; |
1392 | } | 1448 | } |
1393 | 1449 | ||
1394 | int cayman_asic_reset(struct radeon_device *rdev) | 1450 | int cayman_asic_reset(struct radeon_device *rdev) |
1395 | { | 1451 | { |
1396 | return cayman_gpu_soft_reset(rdev); | 1452 | return cayman_gpu_soft_reset(rdev, (RADEON_RESET_GFX | |
1453 | RADEON_RESET_COMPUTE | | ||
1454 | RADEON_RESET_DMA)); | ||
1397 | } | 1455 | } |
1398 | 1456 | ||
1399 | /** | 1457 | /** |
diff --git a/drivers/gpu/drm/radeon/nid.h b/drivers/gpu/drm/radeon/nid.h index b93186b8ee4b..48e5022ee921 100644 --- a/drivers/gpu/drm/radeon/nid.h +++ b/drivers/gpu/drm/radeon/nid.h | |||
@@ -65,7 +65,7 @@ | |||
65 | #define SOFT_RESET_VMC (1 << 17) | 65 | #define SOFT_RESET_VMC (1 << 17) |
66 | #define SOFT_RESET_DMA (1 << 20) | 66 | #define SOFT_RESET_DMA (1 << 20) |
67 | #define SOFT_RESET_TST (1 << 21) | 67 | #define SOFT_RESET_TST (1 << 21) |
68 | #define SOFT_RESET_REGBB (1 << 22) | 68 | #define SOFT_RESET_REGBB (1 << 22) |
69 | #define SOFT_RESET_ORB (1 << 23) | 69 | #define SOFT_RESET_ORB (1 << 23) |
70 | 70 | ||
71 | #define VM_CONTEXT0_REQUEST_RESPONSE 0x1470 | 71 | #define VM_CONTEXT0_REQUEST_RESPONSE 0x1470 |
@@ -675,4 +675,3 @@ | |||
675 | #define DMA_PACKET_NOP 0xf | 675 | #define DMA_PACKET_NOP 0xf |
676 | 676 | ||
677 | #endif | 677 | #endif |
678 | |||
diff --git a/drivers/gpu/drm/radeon/r600.c b/drivers/gpu/drm/radeon/r600.c index 2aaf147969bd..3cb9d6089373 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,14 +1279,13 @@ 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"); | 1284 | dev_info(rdev->dev, " R_008010_GRBM_STATUS = 0x%08X\n", |
1286 | 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", |
1289 | RREG32(R_008014_GRBM_STATUS2)); | 1287 | RREG32(R_008014_GRBM_STATUS2)); |
1290 | dev_info(rdev->dev, " R_000E50_SRBM_STATUS=0x%08X\n", | 1288 | dev_info(rdev->dev, " R_000E50_SRBM_STATUS = 0x%08X\n", |
1291 | RREG32(R_000E50_SRBM_STATUS)); | 1289 | RREG32(R_000E50_SRBM_STATUS)); |
1292 | dev_info(rdev->dev, " R_008674_CP_STALLED_STAT1 = 0x%08X\n", | 1290 | dev_info(rdev->dev, " R_008674_CP_STALLED_STAT1 = 0x%08X\n", |
1293 | RREG32(CP_STALLED_STAT1)); | 1291 | RREG32(CP_STALLED_STAT1)); |
@@ -1297,12 +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 | rv515_mc_stop(rdev, &save); | 1298 | |
1301 | if (r600_mc_wait_for_idle(rdev)) { | ||
1302 | dev_warn(rdev->dev, "Wait for MC idle timedout !\n"); | ||
1303 | } | ||
1304 | /* Disable CP parsing/prefetching */ | 1299 | /* Disable CP parsing/prefetching */ |
1305 | 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)); |
1301 | |||
1306 | /* 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 */ |
1307 | if ((RREG32(R_008010_GRBM_STATUS) & grbm_busy_mask) || | 1303 | if ((RREG32(R_008010_GRBM_STATUS) & grbm_busy_mask) || |
1308 | (RREG32(R_008014_GRBM_STATUS2) & grbm2_busy_mask)) { | 1304 | (RREG32(R_008014_GRBM_STATUS2) & grbm2_busy_mask)) { |
@@ -1332,13 +1328,12 @@ static int r600_gpu_soft_reset(struct radeon_device *rdev) | |||
1332 | RREG32(R_008020_GRBM_SOFT_RESET); | 1328 | RREG32(R_008020_GRBM_SOFT_RESET); |
1333 | mdelay(15); | 1329 | mdelay(15); |
1334 | WREG32(R_008020_GRBM_SOFT_RESET, 0); | 1330 | WREG32(R_008020_GRBM_SOFT_RESET, 0); |
1335 | /* Wait a little for things to settle down */ | 1331 | |
1336 | mdelay(1); | 1332 | dev_info(rdev->dev, " R_008010_GRBM_STATUS = 0x%08X\n", |
1337 | dev_info(rdev->dev, " R_008010_GRBM_STATUS=0x%08X\n", | ||
1338 | RREG32(R_008010_GRBM_STATUS)); | 1333 | RREG32(R_008010_GRBM_STATUS)); |
1339 | dev_info(rdev->dev, " R_008014_GRBM_STATUS2=0x%08X\n", | 1334 | dev_info(rdev->dev, " R_008014_GRBM_STATUS2 = 0x%08X\n", |
1340 | RREG32(R_008014_GRBM_STATUS2)); | 1335 | RREG32(R_008014_GRBM_STATUS2)); |
1341 | dev_info(rdev->dev, " R_000E50_SRBM_STATUS=0x%08X\n", | 1336 | dev_info(rdev->dev, " R_000E50_SRBM_STATUS = 0x%08X\n", |
1342 | RREG32(R_000E50_SRBM_STATUS)); | 1337 | RREG32(R_000E50_SRBM_STATUS)); |
1343 | dev_info(rdev->dev, " R_008674_CP_STALLED_STAT1 = 0x%08X\n", | 1338 | dev_info(rdev->dev, " R_008674_CP_STALLED_STAT1 = 0x%08X\n", |
1344 | RREG32(CP_STALLED_STAT1)); | 1339 | RREG32(CP_STALLED_STAT1)); |
@@ -1348,6 +1343,66 @@ static int r600_gpu_soft_reset(struct radeon_device *rdev) | |||
1348 | RREG32(CP_BUSY_STAT)); | 1343 | RREG32(CP_BUSY_STAT)); |
1349 | dev_info(rdev->dev, " R_008680_CP_STAT = 0x%08X\n", | 1344 | dev_info(rdev->dev, " R_008680_CP_STAT = 0x%08X\n", |
1350 | 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 | |||
1356 | dev_info(rdev->dev, " R_00D034_DMA_STATUS_REG = 0x%08X\n", | ||
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 (!(RREG32(GRBM_STATUS) & GUI_ACTIVE)) | ||
1382 | reset_mask &= ~(RADEON_RESET_GFX | RADEON_RESET_COMPUTE); | ||
1383 | |||
1384 | if (RREG32(DMA_STATUS_REG) & DMA_IDLE) | ||
1385 | reset_mask &= ~RADEON_RESET_DMA; | ||
1386 | |||
1387 | if (reset_mask == 0) | ||
1388 | return 0; | ||
1389 | |||
1390 | dev_info(rdev->dev, "GPU softreset: 0x%08X\n", reset_mask); | ||
1391 | |||
1392 | rv515_mc_stop(rdev, &save); | ||
1393 | if (r600_mc_wait_for_idle(rdev)) { | ||
1394 | dev_warn(rdev->dev, "Wait for MC idle timedout !\n"); | ||
1395 | } | ||
1396 | |||
1397 | if (reset_mask & (RADEON_RESET_GFX | RADEON_RESET_COMPUTE)) | ||
1398 | r600_gpu_soft_reset_gfx(rdev); | ||
1399 | |||
1400 | if (reset_mask & RADEON_RESET_DMA) | ||
1401 | r600_gpu_soft_reset_dma(rdev); | ||
1402 | |||
1403 | /* Wait a little for things to settle down */ | ||
1404 | mdelay(1); | ||
1405 | |||
1351 | rv515_mc_resume(rdev, &save); | 1406 | rv515_mc_resume(rdev, &save); |
1352 | return 0; | 1407 | return 0; |
1353 | } | 1408 | } |
@@ -1395,7 +1450,9 @@ bool r600_dma_is_lockup(struct radeon_device *rdev, struct radeon_ring *ring) | |||
1395 | 1450 | ||
1396 | int r600_asic_reset(struct radeon_device *rdev) | 1451 | int r600_asic_reset(struct radeon_device *rdev) |
1397 | { | 1452 | { |
1398 | return r600_gpu_soft_reset(rdev); | 1453 | return r600_gpu_soft_reset(rdev, (RADEON_RESET_GFX | |
1454 | RADEON_RESET_COMPUTE | | ||
1455 | RADEON_RESET_DMA)); | ||
1399 | } | 1456 | } |
1400 | 1457 | ||
1401 | u32 r6xx_remap_render_backend(struct radeon_device *rdev, | 1458 | u32 r6xx_remap_render_backend(struct radeon_device *rdev, |
@@ -2595,7 +2652,7 @@ int r600_copy_blit(struct radeon_device *rdev, | |||
2595 | * @num_gpu_pages: number of GPU pages to xfer | 2652 | * @num_gpu_pages: number of GPU pages to xfer |
2596 | * @fence: radeon fence object | 2653 | * @fence: radeon fence object |
2597 | * | 2654 | * |
2598 | * Copy GPU paging using the DMA engine (r6xx-r7xx). | 2655 | * Copy GPU paging using the DMA engine (r6xx). |
2599 | * Used by the radeon ttm implementation to move pages if | 2656 | * Used by the radeon ttm implementation to move pages if |
2600 | * registered as the asic copy callback. | 2657 | * registered as the asic copy callback. |
2601 | */ | 2658 | */ |
@@ -2618,8 +2675,8 @@ int r600_copy_dma(struct radeon_device *rdev, | |||
2618 | } | 2675 | } |
2619 | 2676 | ||
2620 | size_in_dw = (num_gpu_pages << RADEON_GPU_PAGE_SHIFT) / 4; | 2677 | size_in_dw = (num_gpu_pages << RADEON_GPU_PAGE_SHIFT) / 4; |
2621 | num_loops = DIV_ROUND_UP(size_in_dw, 0xffff); | 2678 | num_loops = DIV_ROUND_UP(size_in_dw, 0xFFFE); |
2622 | r = radeon_ring_lock(rdev, ring, num_loops * 5 + 8); | 2679 | r = radeon_ring_lock(rdev, ring, num_loops * 4 + 8); |
2623 | if (r) { | 2680 | if (r) { |
2624 | DRM_ERROR("radeon: moving bo (%d).\n", r); | 2681 | DRM_ERROR("radeon: moving bo (%d).\n", r); |
2625 | radeon_semaphore_free(rdev, &sem, NULL); | 2682 | radeon_semaphore_free(rdev, &sem, NULL); |
@@ -2636,14 +2693,14 @@ int r600_copy_dma(struct radeon_device *rdev, | |||
2636 | 2693 | ||
2637 | for (i = 0; i < num_loops; i++) { | 2694 | for (i = 0; i < num_loops; i++) { |
2638 | cur_size_in_dw = size_in_dw; | 2695 | cur_size_in_dw = size_in_dw; |
2639 | if (cur_size_in_dw > 0xFFFF) | 2696 | if (cur_size_in_dw > 0xFFFE) |
2640 | cur_size_in_dw = 0xFFFF; | 2697 | cur_size_in_dw = 0xFFFE; |
2641 | size_in_dw -= cur_size_in_dw; | 2698 | size_in_dw -= cur_size_in_dw; |
2642 | radeon_ring_write(ring, DMA_PACKET(DMA_PACKET_COPY, 0, 0, cur_size_in_dw)); | 2699 | radeon_ring_write(ring, DMA_PACKET(DMA_PACKET_COPY, 0, 0, cur_size_in_dw)); |
2643 | radeon_ring_write(ring, dst_offset & 0xfffffffc); | 2700 | radeon_ring_write(ring, dst_offset & 0xfffffffc); |
2644 | radeon_ring_write(ring, src_offset & 0xfffffffc); | 2701 | radeon_ring_write(ring, src_offset & 0xfffffffc); |
2645 | radeon_ring_write(ring, upper_32_bits(dst_offset) & 0xff); | 2702 | radeon_ring_write(ring, (((upper_32_bits(dst_offset) & 0xff) << 16) | |
2646 | radeon_ring_write(ring, upper_32_bits(src_offset) & 0xff); | 2703 | (upper_32_bits(src_offset) & 0xff))); |
2647 | src_offset += cur_size_in_dw * 4; | 2704 | src_offset += cur_size_in_dw * 4; |
2648 | dst_offset += cur_size_in_dw * 4; | 2705 | dst_offset += cur_size_in_dw * 4; |
2649 | } | 2706 | } |
diff --git a/drivers/gpu/drm/radeon/r600_cs.c b/drivers/gpu/drm/radeon/r600_cs.c index 9ea13d07cc55..69ec24ab8d63 100644 --- a/drivers/gpu/drm/radeon/r600_cs.c +++ b/drivers/gpu/drm/radeon/r600_cs.c | |||
@@ -2476,8 +2476,10 @@ static void r600_cs_parser_fini(struct radeon_cs_parser *parser, int error) | |||
2476 | kfree(parser->relocs); | 2476 | kfree(parser->relocs); |
2477 | for (i = 0; i < parser->nchunks; i++) { | 2477 | for (i = 0; i < parser->nchunks; i++) { |
2478 | kfree(parser->chunks[i].kdata); | 2478 | kfree(parser->chunks[i].kdata); |
2479 | kfree(parser->chunks[i].kpage[0]); | 2479 | if (parser->rdev && (parser->rdev->flags & RADEON_IS_AGP)) { |
2480 | kfree(parser->chunks[i].kpage[1]); | 2480 | kfree(parser->chunks[i].kpage[0]); |
2481 | kfree(parser->chunks[i].kpage[1]); | ||
2482 | } | ||
2481 | } | 2483 | } |
2482 | kfree(parser->chunks); | 2484 | kfree(parser->chunks); |
2483 | kfree(parser->chunks_array); | 2485 | kfree(parser->chunks_array); |
@@ -2561,16 +2563,16 @@ int r600_dma_cs_next_reloc(struct radeon_cs_parser *p, | |||
2561 | struct radeon_cs_chunk *relocs_chunk; | 2563 | struct radeon_cs_chunk *relocs_chunk; |
2562 | unsigned idx; | 2564 | unsigned idx; |
2563 | 2565 | ||
2566 | *cs_reloc = NULL; | ||
2564 | if (p->chunk_relocs_idx == -1) { | 2567 | if (p->chunk_relocs_idx == -1) { |
2565 | DRM_ERROR("No relocation chunk !\n"); | 2568 | DRM_ERROR("No relocation chunk !\n"); |
2566 | return -EINVAL; | 2569 | return -EINVAL; |
2567 | } | 2570 | } |
2568 | *cs_reloc = NULL; | ||
2569 | relocs_chunk = &p->chunks[p->chunk_relocs_idx]; | 2571 | relocs_chunk = &p->chunks[p->chunk_relocs_idx]; |
2570 | idx = p->dma_reloc_idx; | 2572 | idx = p->dma_reloc_idx; |
2571 | if (idx >= relocs_chunk->length_dw) { | 2573 | if (idx >= p->nrelocs) { |
2572 | DRM_ERROR("Relocs at %d after relocations chunk end %d !\n", | 2574 | DRM_ERROR("Relocs at %d after relocations chunk end %d !\n", |
2573 | idx, relocs_chunk->length_dw); | 2575 | idx, p->nrelocs); |
2574 | return -EINVAL; | 2576 | return -EINVAL; |
2575 | } | 2577 | } |
2576 | *cs_reloc = p->relocs_ptr[idx]; | 2578 | *cs_reloc = p->relocs_ptr[idx]; |
@@ -2677,16 +2679,29 @@ int r600_dma_cs_parse(struct radeon_cs_parser *p) | |||
2677 | } | 2679 | } |
2678 | p->idx += 7; | 2680 | p->idx += 7; |
2679 | } else { | 2681 | } else { |
2680 | src_offset = ib[idx+2]; | 2682 | if (p->family >= CHIP_RV770) { |
2681 | src_offset |= ((u64)(ib[idx+4] & 0xff)) << 32; | 2683 | src_offset = ib[idx+2]; |
2682 | dst_offset = ib[idx+1]; | 2684 | src_offset |= ((u64)(ib[idx+4] & 0xff)) << 32; |
2683 | dst_offset |= ((u64)(ib[idx+3] & 0xff)) << 32; | 2685 | dst_offset = ib[idx+1]; |
2686 | dst_offset |= ((u64)(ib[idx+3] & 0xff)) << 32; | ||
2684 | 2687 | ||
2685 | ib[idx+1] += (u32)(dst_reloc->lobj.gpu_offset & 0xfffffffc); | 2688 | ib[idx+1] += (u32)(dst_reloc->lobj.gpu_offset & 0xfffffffc); |
2686 | ib[idx+2] += (u32)(src_reloc->lobj.gpu_offset & 0xfffffffc); | 2689 | ib[idx+2] += (u32)(src_reloc->lobj.gpu_offset & 0xfffffffc); |
2687 | ib[idx+3] += upper_32_bits(dst_reloc->lobj.gpu_offset) & 0xff; | 2690 | ib[idx+3] += upper_32_bits(dst_reloc->lobj.gpu_offset) & 0xff; |
2688 | ib[idx+4] += upper_32_bits(src_reloc->lobj.gpu_offset) & 0xff; | 2691 | ib[idx+4] += upper_32_bits(src_reloc->lobj.gpu_offset) & 0xff; |
2689 | p->idx += 5; | 2692 | p->idx += 5; |
2693 | } else { | ||
2694 | src_offset = ib[idx+2]; | ||
2695 | src_offset |= ((u64)(ib[idx+3] & 0xff)) << 32; | ||
2696 | dst_offset = ib[idx+1]; | ||
2697 | dst_offset |= ((u64)(ib[idx+3] & 0xff0000)) << 16; | ||
2698 | |||
2699 | ib[idx+1] += (u32)(dst_reloc->lobj.gpu_offset & 0xfffffffc); | ||
2700 | ib[idx+2] += (u32)(src_reloc->lobj.gpu_offset & 0xfffffffc); | ||
2701 | ib[idx+3] += upper_32_bits(src_reloc->lobj.gpu_offset) & 0xff; | ||
2702 | ib[idx+3] += (upper_32_bits(dst_reloc->lobj.gpu_offset) & 0xff) << 16; | ||
2703 | p->idx += 4; | ||
2704 | } | ||
2690 | } | 2705 | } |
2691 | if ((src_offset + (count * 4)) > radeon_bo_size(src_reloc->robj)) { | 2706 | if ((src_offset + (count * 4)) > radeon_bo_size(src_reloc->robj)) { |
2692 | dev_warn(p->dev, "DMA copy src buffer too small (%llu %lu)\n", | 2707 | dev_warn(p->dev, "DMA copy src buffer too small (%llu %lu)\n", |
diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h index 9b9422c4403a..a08f657329a0 100644 --- a/drivers/gpu/drm/radeon/radeon.h +++ b/drivers/gpu/drm/radeon/radeon.h | |||
@@ -132,6 +132,11 @@ extern int radeon_lockup_timeout; | |||
132 | #define RADEON_VA_RESERVED_SIZE (8 << 20) | 132 | #define RADEON_VA_RESERVED_SIZE (8 << 20) |
133 | #define RADEON_IB_VM_MAX_SIZE (64 << 10) | 133 | #define RADEON_IB_VM_MAX_SIZE (64 << 10) |
134 | 134 | ||
135 | /* reset flags */ | ||
136 | #define RADEON_RESET_GFX (1 << 0) | ||
137 | #define RADEON_RESET_COMPUTE (1 << 1) | ||
138 | #define RADEON_RESET_DMA (1 << 2) | ||
139 | |||
135 | /* | 140 | /* |
136 | * Errata workarounds. | 141 | * Errata workarounds. |
137 | */ | 142 | */ |
@@ -319,7 +324,6 @@ struct radeon_bo { | |||
319 | struct list_head list; | 324 | struct list_head list; |
320 | /* Protected by tbo.reserved */ | 325 | /* Protected by tbo.reserved */ |
321 | u32 placements[3]; | 326 | u32 placements[3]; |
322 | u32 busy_placements[3]; | ||
323 | struct ttm_placement placement; | 327 | struct ttm_placement placement; |
324 | struct ttm_buffer_object tbo; | 328 | struct ttm_buffer_object tbo; |
325 | struct ttm_bo_kmap_obj kmap; | 329 | struct ttm_bo_kmap_obj kmap; |
@@ -649,6 +653,8 @@ struct radeon_ring { | |||
649 | u32 ptr_reg_mask; | 653 | u32 ptr_reg_mask; |
650 | u32 nop; | 654 | u32 nop; |
651 | u32 idx; | 655 | u32 idx; |
656 | u64 last_semaphore_signal_addr; | ||
657 | u64 last_semaphore_wait_addr; | ||
652 | }; | 658 | }; |
653 | 659 | ||
654 | /* | 660 | /* |
diff --git a/drivers/gpu/drm/radeon/radeon_asic.c b/drivers/gpu/drm/radeon/radeon_asic.c index 596bcbe80ed0..9056fafb00ea 100644 --- a/drivers/gpu/drm/radeon/radeon_asic.c +++ b/drivers/gpu/drm/radeon/radeon_asic.c | |||
@@ -1140,9 +1140,9 @@ static struct radeon_asic rv770_asic = { | |||
1140 | .copy = { | 1140 | .copy = { |
1141 | .blit = &r600_copy_blit, | 1141 | .blit = &r600_copy_blit, |
1142 | .blit_ring_index = RADEON_RING_TYPE_GFX_INDEX, | 1142 | .blit_ring_index = RADEON_RING_TYPE_GFX_INDEX, |
1143 | .dma = &r600_copy_dma, | 1143 | .dma = &rv770_copy_dma, |
1144 | .dma_ring_index = R600_RING_TYPE_DMA_INDEX, | 1144 | .dma_ring_index = R600_RING_TYPE_DMA_INDEX, |
1145 | .copy = &r600_copy_dma, | 1145 | .copy = &rv770_copy_dma, |
1146 | .copy_ring_index = R600_RING_TYPE_DMA_INDEX, | 1146 | .copy_ring_index = R600_RING_TYPE_DMA_INDEX, |
1147 | }, | 1147 | }, |
1148 | .surface = { | 1148 | .surface = { |
diff --git a/drivers/gpu/drm/radeon/radeon_asic.h b/drivers/gpu/drm/radeon/radeon_asic.h index 5f4882cc2152..15d70e613076 100644 --- a/drivers/gpu/drm/radeon/radeon_asic.h +++ b/drivers/gpu/drm/radeon/radeon_asic.h | |||
@@ -403,6 +403,10 @@ u32 rv770_page_flip(struct radeon_device *rdev, int crtc, u64 crtc_base); | |||
403 | void r700_vram_gtt_location(struct radeon_device *rdev, struct radeon_mc *mc); | 403 | void r700_vram_gtt_location(struct radeon_device *rdev, struct radeon_mc *mc); |
404 | void r700_cp_stop(struct radeon_device *rdev); | 404 | void r700_cp_stop(struct radeon_device *rdev); |
405 | void r700_cp_fini(struct radeon_device *rdev); | 405 | void r700_cp_fini(struct radeon_device *rdev); |
406 | int rv770_copy_dma(struct radeon_device *rdev, | ||
407 | uint64_t src_offset, uint64_t dst_offset, | ||
408 | unsigned num_gpu_pages, | ||
409 | struct radeon_fence **fence); | ||
406 | 410 | ||
407 | /* | 411 | /* |
408 | * evergreen | 412 | * evergreen |
diff --git a/drivers/gpu/drm/radeon/radeon_combios.c b/drivers/gpu/drm/radeon/radeon_combios.c index 4af89126e223..33a56a09ff10 100644 --- a/drivers/gpu/drm/radeon/radeon_combios.c +++ b/drivers/gpu/drm/radeon/radeon_combios.c | |||
@@ -1548,6 +1548,9 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev) | |||
1548 | of_machine_is_compatible("PowerBook6,7")) { | 1548 | of_machine_is_compatible("PowerBook6,7")) { |
1549 | /* ibook */ | 1549 | /* ibook */ |
1550 | rdev->mode_info.connector_table = CT_IBOOK; | 1550 | rdev->mode_info.connector_table = CT_IBOOK; |
1551 | } else if (of_machine_is_compatible("PowerMac3,5")) { | ||
1552 | /* PowerMac G4 Silver radeon 7500 */ | ||
1553 | rdev->mode_info.connector_table = CT_MAC_G4_SILVER; | ||
1551 | } else if (of_machine_is_compatible("PowerMac4,4")) { | 1554 | } else if (of_machine_is_compatible("PowerMac4,4")) { |
1552 | /* emac */ | 1555 | /* emac */ |
1553 | rdev->mode_info.connector_table = CT_EMAC; | 1556 | rdev->mode_info.connector_table = CT_EMAC; |
@@ -2212,6 +2215,54 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev) | |||
2212 | CONNECTOR_OBJECT_ID_SVIDEO, | 2215 | CONNECTOR_OBJECT_ID_SVIDEO, |
2213 | &hpd); | 2216 | &hpd); |
2214 | break; | 2217 | break; |
2218 | case CT_MAC_G4_SILVER: | ||
2219 | DRM_INFO("Connector Table: %d (mac g4 silver)\n", | ||
2220 | rdev->mode_info.connector_table); | ||
2221 | /* DVI-I - tv dac, int tmds */ | ||
2222 | ddc_i2c = combios_setup_i2c_bus(rdev, DDC_DVI, 0, 0); | ||
2223 | hpd.hpd = RADEON_HPD_1; /* ??? */ | ||
2224 | radeon_add_legacy_encoder(dev, | ||
2225 | radeon_get_encoder_enum(dev, | ||
2226 | ATOM_DEVICE_DFP1_SUPPORT, | ||
2227 | 0), | ||
2228 | ATOM_DEVICE_DFP1_SUPPORT); | ||
2229 | radeon_add_legacy_encoder(dev, | ||
2230 | radeon_get_encoder_enum(dev, | ||
2231 | ATOM_DEVICE_CRT2_SUPPORT, | ||
2232 | 2), | ||
2233 | ATOM_DEVICE_CRT2_SUPPORT); | ||
2234 | radeon_add_legacy_connector(dev, 0, | ||
2235 | ATOM_DEVICE_DFP1_SUPPORT | | ||
2236 | ATOM_DEVICE_CRT2_SUPPORT, | ||
2237 | DRM_MODE_CONNECTOR_DVII, &ddc_i2c, | ||
2238 | CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_I, | ||
2239 | &hpd); | ||
2240 | /* VGA - primary dac */ | ||
2241 | ddc_i2c = combios_setup_i2c_bus(rdev, DDC_VGA, 0, 0); | ||
2242 | hpd.hpd = RADEON_HPD_NONE; | ||
2243 | radeon_add_legacy_encoder(dev, | ||
2244 | radeon_get_encoder_enum(dev, | ||
2245 | ATOM_DEVICE_CRT1_SUPPORT, | ||
2246 | 1), | ||
2247 | ATOM_DEVICE_CRT1_SUPPORT); | ||
2248 | radeon_add_legacy_connector(dev, 1, ATOM_DEVICE_CRT1_SUPPORT, | ||
2249 | DRM_MODE_CONNECTOR_VGA, &ddc_i2c, | ||
2250 | CONNECTOR_OBJECT_ID_VGA, | ||
2251 | &hpd); | ||
2252 | /* TV - TV DAC */ | ||
2253 | ddc_i2c.valid = false; | ||
2254 | hpd.hpd = RADEON_HPD_NONE; | ||
2255 | radeon_add_legacy_encoder(dev, | ||
2256 | radeon_get_encoder_enum(dev, | ||
2257 | ATOM_DEVICE_TV1_SUPPORT, | ||
2258 | 2), | ||
2259 | ATOM_DEVICE_TV1_SUPPORT); | ||
2260 | radeon_add_legacy_connector(dev, 2, ATOM_DEVICE_TV1_SUPPORT, | ||
2261 | DRM_MODE_CONNECTOR_SVIDEO, | ||
2262 | &ddc_i2c, | ||
2263 | CONNECTOR_OBJECT_ID_SVIDEO, | ||
2264 | &hpd); | ||
2265 | break; | ||
2215 | default: | 2266 | default: |
2216 | DRM_INFO("Connector table: %d (invalid)\n", | 2267 | DRM_INFO("Connector table: %d (invalid)\n", |
2217 | rdev->mode_info.connector_table); | 2268 | rdev->mode_info.connector_table); |
diff --git a/drivers/gpu/drm/radeon/radeon_connectors.c b/drivers/gpu/drm/radeon/radeon_connectors.c index 47bf162ab9c6..2399f25ec037 100644 --- a/drivers/gpu/drm/radeon/radeon_connectors.c +++ b/drivers/gpu/drm/radeon/radeon_connectors.c | |||
@@ -741,7 +741,7 @@ radeon_vga_detect(struct drm_connector *connector, bool force) | |||
741 | ret = connector_status_disconnected; | 741 | ret = connector_status_disconnected; |
742 | 742 | ||
743 | if (radeon_connector->ddc_bus) | 743 | if (radeon_connector->ddc_bus) |
744 | dret = radeon_ddc_probe(radeon_connector); | 744 | dret = radeon_ddc_probe(radeon_connector, false); |
745 | if (dret) { | 745 | if (dret) { |
746 | radeon_connector->detected_by_load = false; | 746 | radeon_connector->detected_by_load = false; |
747 | if (radeon_connector->edid) { | 747 | if (radeon_connector->edid) { |
@@ -947,7 +947,7 @@ radeon_dvi_detect(struct drm_connector *connector, bool force) | |||
947 | return connector->status; | 947 | return connector->status; |
948 | 948 | ||
949 | if (radeon_connector->ddc_bus) | 949 | if (radeon_connector->ddc_bus) |
950 | dret = radeon_ddc_probe(radeon_connector); | 950 | dret = radeon_ddc_probe(radeon_connector, false); |
951 | if (dret) { | 951 | if (dret) { |
952 | radeon_connector->detected_by_load = false; | 952 | radeon_connector->detected_by_load = false; |
953 | if (radeon_connector->edid) { | 953 | if (radeon_connector->edid) { |
@@ -1401,7 +1401,8 @@ radeon_dp_detect(struct drm_connector *connector, bool force) | |||
1401 | if (encoder) { | 1401 | if (encoder) { |
1402 | /* setup ddc on the bridge */ | 1402 | /* setup ddc on the bridge */ |
1403 | radeon_atom_ext_encoder_setup_ddc(encoder); | 1403 | radeon_atom_ext_encoder_setup_ddc(encoder); |
1404 | if (radeon_ddc_probe(radeon_connector)) /* try DDC */ | 1404 | /* bridge chips are always aux */ |
1405 | if (radeon_ddc_probe(radeon_connector, true)) /* try DDC */ | ||
1405 | ret = connector_status_connected; | 1406 | ret = connector_status_connected; |
1406 | else if (radeon_connector->dac_load_detect) { /* try load detection */ | 1407 | else if (radeon_connector->dac_load_detect) { /* try load detection */ |
1407 | struct drm_encoder_helper_funcs *encoder_funcs = encoder->helper_private; | 1408 | struct drm_encoder_helper_funcs *encoder_funcs = encoder->helper_private; |
@@ -1419,7 +1420,8 @@ radeon_dp_detect(struct drm_connector *connector, bool force) | |||
1419 | if (radeon_dp_getdpcd(radeon_connector)) | 1420 | if (radeon_dp_getdpcd(radeon_connector)) |
1420 | ret = connector_status_connected; | 1421 | ret = connector_status_connected; |
1421 | } else { | 1422 | } else { |
1422 | if (radeon_ddc_probe(radeon_connector)) | 1423 | /* try non-aux ddc (DP to DVI/HMDI/etc. adapter) */ |
1424 | if (radeon_ddc_probe(radeon_connector, false)) | ||
1423 | ret = connector_status_connected; | 1425 | ret = connector_status_connected; |
1424 | } | 1426 | } |
1425 | } | 1427 | } |
diff --git a/drivers/gpu/drm/radeon/radeon_cs.c b/drivers/gpu/drm/radeon/radeon_cs.c index 396baba0141a..469661fd1903 100644 --- a/drivers/gpu/drm/radeon/radeon_cs.c +++ b/drivers/gpu/drm/radeon/radeon_cs.c | |||
@@ -279,13 +279,13 @@ int radeon_cs_parser_init(struct radeon_cs_parser *p, void *data) | |||
279 | p->chunks[p->chunk_ib_idx].length_dw); | 279 | p->chunks[p->chunk_ib_idx].length_dw); |
280 | return -EINVAL; | 280 | return -EINVAL; |
281 | } | 281 | } |
282 | if ((p->rdev->flags & RADEON_IS_AGP)) { | 282 | if (p->rdev && (p->rdev->flags & RADEON_IS_AGP)) { |
283 | p->chunks[p->chunk_ib_idx].kpage[0] = kmalloc(PAGE_SIZE, GFP_KERNEL); | 283 | p->chunks[p->chunk_ib_idx].kpage[0] = kmalloc(PAGE_SIZE, GFP_KERNEL); |
284 | p->chunks[p->chunk_ib_idx].kpage[1] = kmalloc(PAGE_SIZE, GFP_KERNEL); | 284 | p->chunks[p->chunk_ib_idx].kpage[1] = kmalloc(PAGE_SIZE, GFP_KERNEL); |
285 | if (p->chunks[p->chunk_ib_idx].kpage[0] == NULL || | 285 | if (p->chunks[p->chunk_ib_idx].kpage[0] == NULL || |
286 | p->chunks[p->chunk_ib_idx].kpage[1] == NULL) { | 286 | p->chunks[p->chunk_ib_idx].kpage[1] == NULL) { |
287 | kfree(p->chunks[i].kpage[0]); | 287 | kfree(p->chunks[p->chunk_ib_idx].kpage[0]); |
288 | kfree(p->chunks[i].kpage[1]); | 288 | kfree(p->chunks[p->chunk_ib_idx].kpage[1]); |
289 | return -ENOMEM; | 289 | return -ENOMEM; |
290 | } | 290 | } |
291 | } | 291 | } |
@@ -583,7 +583,8 @@ static int radeon_cs_update_pages(struct radeon_cs_parser *p, int pg_idx) | |||
583 | struct radeon_cs_chunk *ibc = &p->chunks[p->chunk_ib_idx]; | 583 | struct radeon_cs_chunk *ibc = &p->chunks[p->chunk_ib_idx]; |
584 | int i; | 584 | int i; |
585 | int size = PAGE_SIZE; | 585 | int size = PAGE_SIZE; |
586 | bool copy1 = (p->rdev->flags & RADEON_IS_AGP) ? false : true; | 586 | bool copy1 = (p->rdev && (p->rdev->flags & RADEON_IS_AGP)) ? |
587 | false : true; | ||
587 | 588 | ||
588 | for (i = ibc->last_copied_page + 1; i < pg_idx; i++) { | 589 | for (i = ibc->last_copied_page + 1; i < pg_idx; i++) { |
589 | if (DRM_COPY_FROM_USER(p->ib.ptr + (i * (PAGE_SIZE/4)), | 590 | if (DRM_COPY_FROM_USER(p->ib.ptr + (i * (PAGE_SIZE/4)), |
diff --git a/drivers/gpu/drm/radeon/radeon_device.c b/drivers/gpu/drm/radeon/radeon_device.c index cd756262924d..edfc54e41842 100644 --- a/drivers/gpu/drm/radeon/radeon_device.c +++ b/drivers/gpu/drm/radeon/radeon_device.c | |||
@@ -897,6 +897,25 @@ static void radeon_check_arguments(struct radeon_device *rdev) | |||
897 | } | 897 | } |
898 | 898 | ||
899 | /** | 899 | /** |
900 | * radeon_switcheroo_quirk_long_wakeup - return true if longer d3 delay is | ||
901 | * needed for waking up. | ||
902 | * | ||
903 | * @pdev: pci dev pointer | ||
904 | */ | ||
905 | static bool radeon_switcheroo_quirk_long_wakeup(struct pci_dev *pdev) | ||
906 | { | ||
907 | |||
908 | /* 6600m in a macbook pro */ | ||
909 | if (pdev->subsystem_vendor == PCI_VENDOR_ID_APPLE && | ||
910 | pdev->subsystem_device == 0x00e2) { | ||
911 | printk(KERN_INFO "radeon: quirking longer d3 wakeup delay\n"); | ||
912 | return true; | ||
913 | } | ||
914 | |||
915 | return false; | ||
916 | } | ||
917 | |||
918 | /** | ||
900 | * radeon_switcheroo_set_state - set switcheroo state | 919 | * radeon_switcheroo_set_state - set switcheroo state |
901 | * | 920 | * |
902 | * @pdev: pci dev pointer | 921 | * @pdev: pci dev pointer |
@@ -910,10 +929,19 @@ static void radeon_switcheroo_set_state(struct pci_dev *pdev, enum vga_switchero | |||
910 | struct drm_device *dev = pci_get_drvdata(pdev); | 929 | struct drm_device *dev = pci_get_drvdata(pdev); |
911 | pm_message_t pmm = { .event = PM_EVENT_SUSPEND }; | 930 | pm_message_t pmm = { .event = PM_EVENT_SUSPEND }; |
912 | if (state == VGA_SWITCHEROO_ON) { | 931 | if (state == VGA_SWITCHEROO_ON) { |
932 | unsigned d3_delay = dev->pdev->d3_delay; | ||
933 | |||
913 | printk(KERN_INFO "radeon: switched on\n"); | 934 | printk(KERN_INFO "radeon: switched on\n"); |
914 | /* don't suspend or resume card normally */ | 935 | /* don't suspend or resume card normally */ |
915 | dev->switch_power_state = DRM_SWITCH_POWER_CHANGING; | 936 | dev->switch_power_state = DRM_SWITCH_POWER_CHANGING; |
937 | |||
938 | if (d3_delay < 20 && radeon_switcheroo_quirk_long_wakeup(pdev)) | ||
939 | dev->pdev->d3_delay = 20; | ||
940 | |||
916 | radeon_resume_kms(dev); | 941 | radeon_resume_kms(dev); |
942 | |||
943 | dev->pdev->d3_delay = d3_delay; | ||
944 | |||
917 | dev->switch_power_state = DRM_SWITCH_POWER_ON; | 945 | dev->switch_power_state = DRM_SWITCH_POWER_ON; |
918 | drm_kms_helper_poll_enable(dev); | 946 | drm_kms_helper_poll_enable(dev); |
919 | } else { | 947 | } else { |
diff --git a/drivers/gpu/drm/radeon/radeon_display.c b/drivers/gpu/drm/radeon/radeon_display.c index 310c0e5254ba..1da2386d7cf7 100644 --- a/drivers/gpu/drm/radeon/radeon_display.c +++ b/drivers/gpu/drm/radeon/radeon_display.c | |||
@@ -699,10 +699,15 @@ int radeon_ddc_get_modes(struct radeon_connector *radeon_connector) | |||
699 | if (radeon_connector->router.ddc_valid) | 699 | if (radeon_connector->router.ddc_valid) |
700 | radeon_router_select_ddc_port(radeon_connector); | 700 | radeon_router_select_ddc_port(radeon_connector); |
701 | 701 | ||
702 | if ((radeon_connector->base.connector_type == DRM_MODE_CONNECTOR_DisplayPort) || | 702 | if (radeon_connector_encoder_get_dp_bridge_encoder_id(&radeon_connector->base) != |
703 | (radeon_connector->base.connector_type == DRM_MODE_CONNECTOR_eDP) || | 703 | ENCODER_OBJECT_ID_NONE) { |
704 | (radeon_connector_encoder_get_dp_bridge_encoder_id(&radeon_connector->base) != | 704 | struct radeon_connector_atom_dig *dig = radeon_connector->con_priv; |
705 | ENCODER_OBJECT_ID_NONE)) { | 705 | |
706 | if (dig->dp_i2c_bus) | ||
707 | radeon_connector->edid = drm_get_edid(&radeon_connector->base, | ||
708 | &dig->dp_i2c_bus->adapter); | ||
709 | } else if ((radeon_connector->base.connector_type == DRM_MODE_CONNECTOR_DisplayPort) || | ||
710 | (radeon_connector->base.connector_type == DRM_MODE_CONNECTOR_eDP)) { | ||
706 | struct radeon_connector_atom_dig *dig = radeon_connector->con_priv; | 711 | struct radeon_connector_atom_dig *dig = radeon_connector->con_priv; |
707 | 712 | ||
708 | if ((dig->dp_sink_type == CONNECTOR_OBJECT_ID_DISPLAYPORT || | 713 | if ((dig->dp_sink_type == CONNECTOR_OBJECT_ID_DISPLAYPORT || |
diff --git a/drivers/gpu/drm/radeon/radeon_drv.c b/drivers/gpu/drm/radeon/radeon_drv.c index ff7593498a74..d9bf96ee299a 100644 --- a/drivers/gpu/drm/radeon/radeon_drv.c +++ b/drivers/gpu/drm/radeon/radeon_drv.c | |||
@@ -69,9 +69,10 @@ | |||
69 | * 2.26.0 - r600-eg: fix htile size computation | 69 | * 2.26.0 - r600-eg: fix htile size computation |
70 | * 2.27.0 - r600-SI: Add CS ioctl support for async DMA | 70 | * 2.27.0 - r600-SI: Add CS ioctl support for async DMA |
71 | * 2.28.0 - r600-eg: Add MEM_WRITE packet support | 71 | * 2.28.0 - r600-eg: Add MEM_WRITE packet support |
72 | * 2.29.0 - R500 FP16 color clear registers | ||
72 | */ | 73 | */ |
73 | #define KMS_DRIVER_MAJOR 2 | 74 | #define KMS_DRIVER_MAJOR 2 |
74 | #define KMS_DRIVER_MINOR 28 | 75 | #define KMS_DRIVER_MINOR 29 |
75 | #define KMS_DRIVER_PATCHLEVEL 0 | 76 | #define KMS_DRIVER_PATCHLEVEL 0 |
76 | int radeon_driver_load_kms(struct drm_device *dev, unsigned long flags); | 77 | int radeon_driver_load_kms(struct drm_device *dev, unsigned long flags); |
77 | int radeon_driver_unload_kms(struct drm_device *dev); | 78 | int radeon_driver_unload_kms(struct drm_device *dev); |
@@ -306,8 +307,8 @@ static int radeon_kick_out_firmware_fb(struct pci_dev *pdev) | |||
306 | return 0; | 307 | return 0; |
307 | } | 308 | } |
308 | 309 | ||
309 | static int __devinit | 310 | static int radeon_pci_probe(struct pci_dev *pdev, |
310 | radeon_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | 311 | const struct pci_device_id *ent) |
311 | { | 312 | { |
312 | int ret; | 313 | int ret; |
313 | 314 | ||
diff --git a/drivers/gpu/drm/radeon/radeon_i2c.c b/drivers/gpu/drm/radeon/radeon_i2c.c index c5bddd630eb9..fc60b74ee304 100644 --- a/drivers/gpu/drm/radeon/radeon_i2c.c +++ b/drivers/gpu/drm/radeon/radeon_i2c.c | |||
@@ -39,7 +39,7 @@ extern u32 radeon_atom_hw_i2c_func(struct i2c_adapter *adap); | |||
39 | * radeon_ddc_probe | 39 | * radeon_ddc_probe |
40 | * | 40 | * |
41 | */ | 41 | */ |
42 | bool radeon_ddc_probe(struct radeon_connector *radeon_connector) | 42 | bool radeon_ddc_probe(struct radeon_connector *radeon_connector, bool use_aux) |
43 | { | 43 | { |
44 | u8 out = 0x0; | 44 | u8 out = 0x0; |
45 | u8 buf[8]; | 45 | u8 buf[8]; |
@@ -63,7 +63,13 @@ bool radeon_ddc_probe(struct radeon_connector *radeon_connector) | |||
63 | if (radeon_connector->router.ddc_valid) | 63 | if (radeon_connector->router.ddc_valid) |
64 | radeon_router_select_ddc_port(radeon_connector); | 64 | radeon_router_select_ddc_port(radeon_connector); |
65 | 65 | ||
66 | ret = i2c_transfer(&radeon_connector->ddc_bus->adapter, msgs, 2); | 66 | if (use_aux) { |
67 | struct radeon_connector_atom_dig *dig = radeon_connector->con_priv; | ||
68 | ret = i2c_transfer(&dig->dp_i2c_bus->adapter, msgs, 2); | ||
69 | } else { | ||
70 | ret = i2c_transfer(&radeon_connector->ddc_bus->adapter, msgs, 2); | ||
71 | } | ||
72 | |||
67 | if (ret != 2) | 73 | if (ret != 2) |
68 | /* Couldn't find an accessible DDC on this connector */ | 74 | /* Couldn't find an accessible DDC on this connector */ |
69 | return false; | 75 | return false; |
diff --git a/drivers/gpu/drm/radeon/radeon_legacy_encoders.c b/drivers/gpu/drm/radeon/radeon_legacy_encoders.c index f5ba2241dacc..62cd512f5c8d 100644 --- a/drivers/gpu/drm/radeon/radeon_legacy_encoders.c +++ b/drivers/gpu/drm/radeon/radeon_legacy_encoders.c | |||
@@ -640,6 +640,14 @@ static enum drm_connector_status radeon_legacy_primary_dac_detect(struct drm_enc | |||
640 | enum drm_connector_status found = connector_status_disconnected; | 640 | enum drm_connector_status found = connector_status_disconnected; |
641 | bool color = true; | 641 | bool color = true; |
642 | 642 | ||
643 | /* just don't bother on RN50 those chip are often connected to remoting | ||
644 | * console hw and often we get failure to load detect those. So to make | ||
645 | * everyone happy report the encoder as always connected. | ||
646 | */ | ||
647 | if (ASIC_IS_RN50(rdev)) { | ||
648 | return connector_status_connected; | ||
649 | } | ||
650 | |||
643 | /* save the regs we need */ | 651 | /* save the regs we need */ |
644 | vclk_ecp_cntl = RREG32_PLL(RADEON_VCLK_ECP_CNTL); | 652 | vclk_ecp_cntl = RREG32_PLL(RADEON_VCLK_ECP_CNTL); |
645 | crtc_ext_cntl = RREG32(RADEON_CRTC_EXT_CNTL); | 653 | crtc_ext_cntl = RREG32(RADEON_CRTC_EXT_CNTL); |
diff --git a/drivers/gpu/drm/radeon/radeon_mode.h b/drivers/gpu/drm/radeon/radeon_mode.h index d818b503b42f..4003f5a68c09 100644 --- a/drivers/gpu/drm/radeon/radeon_mode.h +++ b/drivers/gpu/drm/radeon/radeon_mode.h | |||
@@ -209,7 +209,8 @@ enum radeon_connector_table { | |||
209 | CT_RN50_POWER, | 209 | CT_RN50_POWER, |
210 | CT_MAC_X800, | 210 | CT_MAC_X800, |
211 | CT_MAC_G5_9600, | 211 | CT_MAC_G5_9600, |
212 | CT_SAM440EP | 212 | CT_SAM440EP, |
213 | CT_MAC_G4_SILVER | ||
213 | }; | 214 | }; |
214 | 215 | ||
215 | enum radeon_dvo_chip { | 216 | enum radeon_dvo_chip { |
@@ -558,7 +559,7 @@ extern void radeon_i2c_put_byte(struct radeon_i2c_chan *i2c, | |||
558 | u8 val); | 559 | u8 val); |
559 | extern void radeon_router_select_ddc_port(struct radeon_connector *radeon_connector); | 560 | extern void radeon_router_select_ddc_port(struct radeon_connector *radeon_connector); |
560 | extern void radeon_router_select_cd_port(struct radeon_connector *radeon_connector); | 561 | extern void radeon_router_select_cd_port(struct radeon_connector *radeon_connector); |
561 | extern bool radeon_ddc_probe(struct radeon_connector *radeon_connector); | 562 | extern bool radeon_ddc_probe(struct radeon_connector *radeon_connector, bool use_aux); |
562 | extern int radeon_ddc_get_modes(struct radeon_connector *radeon_connector); | 563 | extern int radeon_ddc_get_modes(struct radeon_connector *radeon_connector); |
563 | 564 | ||
564 | extern struct drm_encoder *radeon_best_encoder(struct drm_connector *connector); | 565 | extern struct drm_encoder *radeon_best_encoder(struct drm_connector *connector); |
diff --git a/drivers/gpu/drm/radeon/radeon_object.c b/drivers/gpu/drm/radeon/radeon_object.c index 883c95d8d90f..d3aface2d12d 100644 --- a/drivers/gpu/drm/radeon/radeon_object.c +++ b/drivers/gpu/drm/radeon/radeon_object.c | |||
@@ -84,6 +84,7 @@ void radeon_ttm_placement_from_domain(struct radeon_bo *rbo, u32 domain) | |||
84 | rbo->placement.fpfn = 0; | 84 | rbo->placement.fpfn = 0; |
85 | rbo->placement.lpfn = 0; | 85 | rbo->placement.lpfn = 0; |
86 | rbo->placement.placement = rbo->placements; | 86 | rbo->placement.placement = rbo->placements; |
87 | rbo->placement.busy_placement = rbo->placements; | ||
87 | if (domain & RADEON_GEM_DOMAIN_VRAM) | 88 | if (domain & RADEON_GEM_DOMAIN_VRAM) |
88 | rbo->placements[c++] = TTM_PL_FLAG_WC | TTM_PL_FLAG_UNCACHED | | 89 | rbo->placements[c++] = TTM_PL_FLAG_WC | TTM_PL_FLAG_UNCACHED | |
89 | TTM_PL_FLAG_VRAM; | 90 | TTM_PL_FLAG_VRAM; |
@@ -104,14 +105,6 @@ void radeon_ttm_placement_from_domain(struct radeon_bo *rbo, u32 domain) | |||
104 | if (!c) | 105 | if (!c) |
105 | rbo->placements[c++] = TTM_PL_MASK_CACHING | TTM_PL_FLAG_SYSTEM; | 106 | rbo->placements[c++] = TTM_PL_MASK_CACHING | TTM_PL_FLAG_SYSTEM; |
106 | rbo->placement.num_placement = c; | 107 | rbo->placement.num_placement = c; |
107 | |||
108 | c = 0; | ||
109 | rbo->placement.busy_placement = rbo->busy_placements; | ||
110 | if (rbo->rdev->flags & RADEON_IS_AGP) { | ||
111 | rbo->busy_placements[c++] = TTM_PL_FLAG_WC | TTM_PL_FLAG_TT; | ||
112 | } else { | ||
113 | rbo->busy_placements[c++] = TTM_PL_FLAG_CACHED | TTM_PL_FLAG_TT; | ||
114 | } | ||
115 | rbo->placement.num_busy_placement = c; | 108 | rbo->placement.num_busy_placement = c; |
116 | } | 109 | } |
117 | 110 | ||
@@ -357,6 +350,7 @@ int radeon_bo_list_validate(struct list_head *head) | |||
357 | { | 350 | { |
358 | struct radeon_bo_list *lobj; | 351 | struct radeon_bo_list *lobj; |
359 | struct radeon_bo *bo; | 352 | struct radeon_bo *bo; |
353 | u32 domain; | ||
360 | int r; | 354 | int r; |
361 | 355 | ||
362 | r = ttm_eu_reserve_buffers(head); | 356 | r = ttm_eu_reserve_buffers(head); |
@@ -366,9 +360,17 @@ int radeon_bo_list_validate(struct list_head *head) | |||
366 | list_for_each_entry(lobj, head, tv.head) { | 360 | list_for_each_entry(lobj, head, tv.head) { |
367 | bo = lobj->bo; | 361 | bo = lobj->bo; |
368 | if (!bo->pin_count) { | 362 | if (!bo->pin_count) { |
363 | domain = lobj->wdomain ? lobj->wdomain : lobj->rdomain; | ||
364 | |||
365 | retry: | ||
366 | radeon_ttm_placement_from_domain(bo, domain); | ||
369 | r = ttm_bo_validate(&bo->tbo, &bo->placement, | 367 | r = ttm_bo_validate(&bo->tbo, &bo->placement, |
370 | true, false); | 368 | true, false); |
371 | if (unlikely(r)) { | 369 | if (unlikely(r)) { |
370 | if (r != -ERESTARTSYS && domain == RADEON_GEM_DOMAIN_VRAM) { | ||
371 | domain |= RADEON_GEM_DOMAIN_GTT; | ||
372 | goto retry; | ||
373 | } | ||
372 | return r; | 374 | return r; |
373 | } | 375 | } |
374 | } | 376 | } |
diff --git a/drivers/gpu/drm/radeon/radeon_prime.c b/drivers/gpu/drm/radeon/radeon_prime.c index e09521858f64..26c23bb651c6 100644 --- a/drivers/gpu/drm/radeon/radeon_prime.c +++ b/drivers/gpu/drm/radeon/radeon_prime.c | |||
@@ -194,6 +194,7 @@ struct drm_gem_object *radeon_gem_prime_import(struct drm_device *dev, | |||
194 | bo = dma_buf->priv; | 194 | bo = dma_buf->priv; |
195 | if (bo->gem_base.dev == dev) { | 195 | if (bo->gem_base.dev == dev) { |
196 | drm_gem_object_reference(&bo->gem_base); | 196 | drm_gem_object_reference(&bo->gem_base); |
197 | dma_buf_put(dma_buf); | ||
197 | return &bo->gem_base; | 198 | return &bo->gem_base; |
198 | } | 199 | } |
199 | } | 200 | } |
diff --git a/drivers/gpu/drm/radeon/radeon_ring.c b/drivers/gpu/drm/radeon/radeon_ring.c index ebd69562ef6c..2430d80b1871 100644 --- a/drivers/gpu/drm/radeon/radeon_ring.c +++ b/drivers/gpu/drm/radeon/radeon_ring.c | |||
@@ -770,22 +770,30 @@ static int radeon_debugfs_ring_info(struct seq_file *m, void *data) | |||
770 | int ridx = *(int*)node->info_ent->data; | 770 | int ridx = *(int*)node->info_ent->data; |
771 | struct radeon_ring *ring = &rdev->ring[ridx]; | 771 | struct radeon_ring *ring = &rdev->ring[ridx]; |
772 | unsigned count, i, j; | 772 | unsigned count, i, j; |
773 | u32 tmp; | ||
773 | 774 | ||
774 | radeon_ring_free_size(rdev, ring); | 775 | radeon_ring_free_size(rdev, ring); |
775 | count = (ring->ring_size / 4) - ring->ring_free_dw; | 776 | count = (ring->ring_size / 4) - ring->ring_free_dw; |
776 | seq_printf(m, "wptr(0x%04x): 0x%08x\n", ring->wptr_reg, RREG32(ring->wptr_reg)); | 777 | tmp = RREG32(ring->wptr_reg) >> ring->ptr_reg_shift; |
777 | seq_printf(m, "rptr(0x%04x): 0x%08x\n", ring->rptr_reg, RREG32(ring->rptr_reg)); | 778 | seq_printf(m, "wptr(0x%04x): 0x%08x [%5d]\n", ring->wptr_reg, tmp, tmp); |
779 | tmp = RREG32(ring->rptr_reg) >> ring->ptr_reg_shift; | ||
780 | seq_printf(m, "rptr(0x%04x): 0x%08x [%5d]\n", ring->rptr_reg, tmp, tmp); | ||
778 | if (ring->rptr_save_reg) { | 781 | if (ring->rptr_save_reg) { |
779 | seq_printf(m, "rptr next(0x%04x): 0x%08x\n", ring->rptr_save_reg, | 782 | seq_printf(m, "rptr next(0x%04x): 0x%08x\n", ring->rptr_save_reg, |
780 | RREG32(ring->rptr_save_reg)); | 783 | RREG32(ring->rptr_save_reg)); |
781 | } | 784 | } |
782 | seq_printf(m, "driver's copy of the wptr: 0x%08x\n", ring->wptr); | 785 | seq_printf(m, "driver's copy of the wptr: 0x%08x [%5d]\n", ring->wptr, ring->wptr); |
783 | seq_printf(m, "driver's copy of the rptr: 0x%08x\n", ring->rptr); | 786 | seq_printf(m, "driver's copy of the rptr: 0x%08x [%5d]\n", ring->rptr, ring->rptr); |
787 | seq_printf(m, "last semaphore signal addr : 0x%016llx\n", ring->last_semaphore_signal_addr); | ||
788 | seq_printf(m, "last semaphore wait addr : 0x%016llx\n", ring->last_semaphore_wait_addr); | ||
784 | seq_printf(m, "%u free dwords in ring\n", ring->ring_free_dw); | 789 | seq_printf(m, "%u free dwords in ring\n", ring->ring_free_dw); |
785 | seq_printf(m, "%u dwords in ring\n", count); | 790 | seq_printf(m, "%u dwords in ring\n", count); |
786 | i = ring->rptr; | 791 | /* print 8 dw before current rptr as often it's the last executed |
787 | for (j = 0; j <= count; j++) { | 792 | * packet that is the root issue |
788 | seq_printf(m, "r[%04d]=0x%08x\n", i, ring->ring[i]); | 793 | */ |
794 | i = (ring->rptr + ring->ptr_mask + 1 - 32) & ring->ptr_mask; | ||
795 | for (j = 0; j <= (count + 32); j++) { | ||
796 | seq_printf(m, "r[%5d]=0x%08x\n", i, ring->ring[i]); | ||
789 | i = (i + 1) & ring->ptr_mask; | 797 | i = (i + 1) & ring->ptr_mask; |
790 | } | 798 | } |
791 | return 0; | 799 | return 0; |
@@ -794,11 +802,15 @@ static int radeon_debugfs_ring_info(struct seq_file *m, void *data) | |||
794 | static int radeon_ring_type_gfx_index = RADEON_RING_TYPE_GFX_INDEX; | 802 | static int radeon_ring_type_gfx_index = RADEON_RING_TYPE_GFX_INDEX; |
795 | static int cayman_ring_type_cp1_index = CAYMAN_RING_TYPE_CP1_INDEX; | 803 | static int cayman_ring_type_cp1_index = CAYMAN_RING_TYPE_CP1_INDEX; |
796 | static int cayman_ring_type_cp2_index = CAYMAN_RING_TYPE_CP2_INDEX; | 804 | static int cayman_ring_type_cp2_index = CAYMAN_RING_TYPE_CP2_INDEX; |
805 | static int radeon_ring_type_dma1_index = R600_RING_TYPE_DMA_INDEX; | ||
806 | static int radeon_ring_type_dma2_index = CAYMAN_RING_TYPE_DMA1_INDEX; | ||
797 | 807 | ||
798 | static struct drm_info_list radeon_debugfs_ring_info_list[] = { | 808 | static struct drm_info_list radeon_debugfs_ring_info_list[] = { |
799 | {"radeon_ring_gfx", radeon_debugfs_ring_info, 0, &radeon_ring_type_gfx_index}, | 809 | {"radeon_ring_gfx", radeon_debugfs_ring_info, 0, &radeon_ring_type_gfx_index}, |
800 | {"radeon_ring_cp1", radeon_debugfs_ring_info, 0, &cayman_ring_type_cp1_index}, | 810 | {"radeon_ring_cp1", radeon_debugfs_ring_info, 0, &cayman_ring_type_cp1_index}, |
801 | {"radeon_ring_cp2", radeon_debugfs_ring_info, 0, &cayman_ring_type_cp2_index}, | 811 | {"radeon_ring_cp2", radeon_debugfs_ring_info, 0, &cayman_ring_type_cp2_index}, |
812 | {"radeon_ring_dma1", radeon_debugfs_ring_info, 0, &radeon_ring_type_dma1_index}, | ||
813 | {"radeon_ring_dma2", radeon_debugfs_ring_info, 0, &radeon_ring_type_dma2_index}, | ||
802 | }; | 814 | }; |
803 | 815 | ||
804 | static int radeon_debugfs_sa_info(struct seq_file *m, void *data) | 816 | static int radeon_debugfs_sa_info(struct seq_file *m, void *data) |
diff --git a/drivers/gpu/drm/radeon/radeon_semaphore.c b/drivers/gpu/drm/radeon/radeon_semaphore.c index 97f3ece81cd2..8dcc20f53d73 100644 --- a/drivers/gpu/drm/radeon/radeon_semaphore.c +++ b/drivers/gpu/drm/radeon/radeon_semaphore.c | |||
@@ -95,6 +95,10 @@ int radeon_semaphore_sync_rings(struct radeon_device *rdev, | |||
95 | /* we assume caller has already allocated space on waiters ring */ | 95 | /* we assume caller has already allocated space on waiters ring */ |
96 | radeon_semaphore_emit_wait(rdev, waiter, semaphore); | 96 | radeon_semaphore_emit_wait(rdev, waiter, semaphore); |
97 | 97 | ||
98 | /* for debugging lockup only, used by sysfs debug files */ | ||
99 | rdev->ring[signaler].last_semaphore_signal_addr = semaphore->gpu_addr; | ||
100 | rdev->ring[waiter].last_semaphore_wait_addr = semaphore->gpu_addr; | ||
101 | |||
98 | return 0; | 102 | return 0; |
99 | } | 103 | } |
100 | 104 | ||
diff --git a/drivers/gpu/drm/radeon/reg_srcs/rv515 b/drivers/gpu/drm/radeon/reg_srcs/rv515 index 911a8fbd32bb..78d5e99d759d 100644 --- a/drivers/gpu/drm/radeon/reg_srcs/rv515 +++ b/drivers/gpu/drm/radeon/reg_srcs/rv515 | |||
@@ -324,6 +324,8 @@ rv515 0x6d40 | |||
324 | 0x46AC US_OUT_FMT_2 | 324 | 0x46AC US_OUT_FMT_2 |
325 | 0x46B0 US_OUT_FMT_3 | 325 | 0x46B0 US_OUT_FMT_3 |
326 | 0x46B4 US_W_FMT | 326 | 0x46B4 US_W_FMT |
327 | 0x46C0 RB3D_COLOR_CLEAR_VALUE_AR | ||
328 | 0x46C4 RB3D_COLOR_CLEAR_VALUE_GB | ||
327 | 0x4BC0 FG_FOG_BLEND | 329 | 0x4BC0 FG_FOG_BLEND |
328 | 0x4BC4 FG_FOG_FACTOR | 330 | 0x4BC4 FG_FOG_FACTOR |
329 | 0x4BC8 FG_FOG_COLOR_R | 331 | 0x4BC8 FG_FOG_COLOR_R |
diff --git a/drivers/gpu/drm/radeon/rv770.c b/drivers/gpu/drm/radeon/rv770.c index 87c979c4f721..1b2444f4d8f4 100644 --- a/drivers/gpu/drm/radeon/rv770.c +++ b/drivers/gpu/drm/radeon/rv770.c | |||
@@ -887,6 +887,80 @@ static int rv770_mc_init(struct radeon_device *rdev) | |||
887 | return 0; | 887 | return 0; |
888 | } | 888 | } |
889 | 889 | ||
890 | /** | ||
891 | * rv770_copy_dma - copy pages using the DMA engine | ||
892 | * | ||
893 | * @rdev: radeon_device pointer | ||
894 | * @src_offset: src GPU address | ||
895 | * @dst_offset: dst GPU address | ||
896 | * @num_gpu_pages: number of GPU pages to xfer | ||
897 | * @fence: radeon fence object | ||
898 | * | ||
899 | * Copy GPU paging using the DMA engine (r7xx). | ||
900 | * Used by the radeon ttm implementation to move pages if | ||
901 | * registered as the asic copy callback. | ||
902 | */ | ||
903 | int rv770_copy_dma(struct radeon_device *rdev, | ||
904 | uint64_t src_offset, uint64_t dst_offset, | ||
905 | unsigned num_gpu_pages, | ||
906 | struct radeon_fence **fence) | ||
907 | { | ||
908 | struct radeon_semaphore *sem = NULL; | ||
909 | int ring_index = rdev->asic->copy.dma_ring_index; | ||
910 | struct radeon_ring *ring = &rdev->ring[ring_index]; | ||
911 | u32 size_in_dw, cur_size_in_dw; | ||
912 | int i, num_loops; | ||
913 | int r = 0; | ||
914 | |||
915 | r = radeon_semaphore_create(rdev, &sem); | ||
916 | if (r) { | ||
917 | DRM_ERROR("radeon: moving bo (%d).\n", r); | ||
918 | return r; | ||
919 | } | ||
920 | |||
921 | size_in_dw = (num_gpu_pages << RADEON_GPU_PAGE_SHIFT) / 4; | ||
922 | num_loops = DIV_ROUND_UP(size_in_dw, 0xFFFF); | ||
923 | r = radeon_ring_lock(rdev, ring, num_loops * 5 + 8); | ||
924 | if (r) { | ||
925 | DRM_ERROR("radeon: moving bo (%d).\n", r); | ||
926 | radeon_semaphore_free(rdev, &sem, NULL); | ||
927 | return r; | ||
928 | } | ||
929 | |||
930 | if (radeon_fence_need_sync(*fence, ring->idx)) { | ||
931 | radeon_semaphore_sync_rings(rdev, sem, (*fence)->ring, | ||
932 | ring->idx); | ||
933 | radeon_fence_note_sync(*fence, ring->idx); | ||
934 | } else { | ||
935 | radeon_semaphore_free(rdev, &sem, NULL); | ||
936 | } | ||
937 | |||
938 | for (i = 0; i < num_loops; i++) { | ||
939 | cur_size_in_dw = size_in_dw; | ||
940 | if (cur_size_in_dw > 0xFFFF) | ||
941 | cur_size_in_dw = 0xFFFF; | ||
942 | size_in_dw -= cur_size_in_dw; | ||
943 | radeon_ring_write(ring, DMA_PACKET(DMA_PACKET_COPY, 0, 0, cur_size_in_dw)); | ||
944 | radeon_ring_write(ring, dst_offset & 0xfffffffc); | ||
945 | radeon_ring_write(ring, src_offset & 0xfffffffc); | ||
946 | radeon_ring_write(ring, upper_32_bits(dst_offset) & 0xff); | ||
947 | radeon_ring_write(ring, upper_32_bits(src_offset) & 0xff); | ||
948 | src_offset += cur_size_in_dw * 4; | ||
949 | dst_offset += cur_size_in_dw * 4; | ||
950 | } | ||
951 | |||
952 | r = radeon_fence_emit(rdev, fence, ring->idx); | ||
953 | if (r) { | ||
954 | radeon_ring_unlock_undo(rdev, ring); | ||
955 | return r; | ||
956 | } | ||
957 | |||
958 | radeon_ring_unlock_commit(rdev, ring); | ||
959 | radeon_semaphore_free(rdev, &sem, *fence); | ||
960 | |||
961 | return r; | ||
962 | } | ||
963 | |||
890 | static int rv770_startup(struct radeon_device *rdev) | 964 | static int rv770_startup(struct radeon_device *rdev) |
891 | { | 965 | { |
892 | struct radeon_ring *ring; | 966 | struct radeon_ring *ring; |
diff --git a/drivers/gpu/drm/radeon/si.c b/drivers/gpu/drm/radeon/si.c index ef683653f0b7..ae8b48205a6c 100644 --- a/drivers/gpu/drm/radeon/si.c +++ b/drivers/gpu/drm/radeon/si.c | |||
@@ -2126,15 +2126,13 @@ bool si_gpu_is_lockup(struct radeon_device *rdev, struct radeon_ring *ring) | |||
2126 | return radeon_ring_test_lockup(rdev, ring); | 2126 | return radeon_ring_test_lockup(rdev, ring); |
2127 | } | 2127 | } |
2128 | 2128 | ||
2129 | static int si_gpu_soft_reset(struct radeon_device *rdev) | 2129 | static void si_gpu_soft_reset_gfx(struct radeon_device *rdev) |
2130 | { | 2130 | { |
2131 | struct evergreen_mc_save save; | ||
2132 | u32 grbm_reset = 0; | 2131 | u32 grbm_reset = 0; |
2133 | 2132 | ||
2134 | if (!(RREG32(GRBM_STATUS) & GUI_ACTIVE)) | 2133 | if (!(RREG32(GRBM_STATUS) & GUI_ACTIVE)) |
2135 | return 0; | 2134 | return; |
2136 | 2135 | ||
2137 | dev_info(rdev->dev, "GPU softreset \n"); | ||
2138 | dev_info(rdev->dev, " GRBM_STATUS=0x%08X\n", | 2136 | dev_info(rdev->dev, " GRBM_STATUS=0x%08X\n", |
2139 | RREG32(GRBM_STATUS)); | 2137 | RREG32(GRBM_STATUS)); |
2140 | dev_info(rdev->dev, " GRBM_STATUS2=0x%08X\n", | 2138 | dev_info(rdev->dev, " GRBM_STATUS2=0x%08X\n", |
@@ -2145,10 +2143,7 @@ static int si_gpu_soft_reset(struct radeon_device *rdev) | |||
2145 | RREG32(GRBM_STATUS_SE1)); | 2143 | RREG32(GRBM_STATUS_SE1)); |
2146 | dev_info(rdev->dev, " SRBM_STATUS=0x%08X\n", | 2144 | dev_info(rdev->dev, " SRBM_STATUS=0x%08X\n", |
2147 | RREG32(SRBM_STATUS)); | 2145 | RREG32(SRBM_STATUS)); |
2148 | evergreen_mc_stop(rdev, &save); | 2146 | |
2149 | if (radeon_mc_wait_for_idle(rdev)) { | ||
2150 | dev_warn(rdev->dev, "Wait for MC idle timedout !\n"); | ||
2151 | } | ||
2152 | /* Disable CP parsing/prefetching */ | 2147 | /* Disable CP parsing/prefetching */ |
2153 | WREG32(CP_ME_CNTL, CP_ME_HALT | CP_PFP_HALT | CP_CE_HALT); | 2148 | WREG32(CP_ME_CNTL, CP_ME_HALT | CP_PFP_HALT | CP_CE_HALT); |
2154 | 2149 | ||
@@ -2173,8 +2168,7 @@ static int si_gpu_soft_reset(struct radeon_device *rdev) | |||
2173 | udelay(50); | 2168 | udelay(50); |
2174 | WREG32(GRBM_SOFT_RESET, 0); | 2169 | WREG32(GRBM_SOFT_RESET, 0); |
2175 | (void)RREG32(GRBM_SOFT_RESET); | 2170 | (void)RREG32(GRBM_SOFT_RESET); |
2176 | /* Wait a little for things to settle down */ | 2171 | |
2177 | udelay(50); | ||
2178 | dev_info(rdev->dev, " GRBM_STATUS=0x%08X\n", | 2172 | dev_info(rdev->dev, " GRBM_STATUS=0x%08X\n", |
2179 | RREG32(GRBM_STATUS)); | 2173 | RREG32(GRBM_STATUS)); |
2180 | dev_info(rdev->dev, " GRBM_STATUS2=0x%08X\n", | 2174 | dev_info(rdev->dev, " GRBM_STATUS2=0x%08X\n", |
@@ -2185,13 +2179,81 @@ static int si_gpu_soft_reset(struct radeon_device *rdev) | |||
2185 | RREG32(GRBM_STATUS_SE1)); | 2179 | RREG32(GRBM_STATUS_SE1)); |
2186 | dev_info(rdev->dev, " SRBM_STATUS=0x%08X\n", | 2180 | dev_info(rdev->dev, " SRBM_STATUS=0x%08X\n", |
2187 | RREG32(SRBM_STATUS)); | 2181 | RREG32(SRBM_STATUS)); |
2182 | } | ||
2183 | |||
2184 | static void si_gpu_soft_reset_dma(struct radeon_device *rdev) | ||
2185 | { | ||
2186 | u32 tmp; | ||
2187 | |||
2188 | if (RREG32(DMA_STATUS_REG) & DMA_IDLE) | ||
2189 | return; | ||
2190 | |||
2191 | dev_info(rdev->dev, " DMA_STATUS_REG = 0x%08X\n", | ||
2192 | RREG32(DMA_STATUS_REG)); | ||
2193 | |||
2194 | /* dma0 */ | ||
2195 | tmp = RREG32(DMA_RB_CNTL + DMA0_REGISTER_OFFSET); | ||
2196 | tmp &= ~DMA_RB_ENABLE; | ||
2197 | WREG32(DMA_RB_CNTL + DMA0_REGISTER_OFFSET, tmp); | ||
2198 | |||
2199 | /* dma1 */ | ||
2200 | tmp = RREG32(DMA_RB_CNTL + DMA1_REGISTER_OFFSET); | ||
2201 | tmp &= ~DMA_RB_ENABLE; | ||
2202 | WREG32(DMA_RB_CNTL + DMA1_REGISTER_OFFSET, tmp); | ||
2203 | |||
2204 | /* Reset dma */ | ||
2205 | WREG32(SRBM_SOFT_RESET, SOFT_RESET_DMA | SOFT_RESET_DMA1); | ||
2206 | RREG32(SRBM_SOFT_RESET); | ||
2207 | udelay(50); | ||
2208 | WREG32(SRBM_SOFT_RESET, 0); | ||
2209 | |||
2210 | dev_info(rdev->dev, " DMA_STATUS_REG = 0x%08X\n", | ||
2211 | RREG32(DMA_STATUS_REG)); | ||
2212 | } | ||
2213 | |||
2214 | static int si_gpu_soft_reset(struct radeon_device *rdev, u32 reset_mask) | ||
2215 | { | ||
2216 | struct evergreen_mc_save save; | ||
2217 | |||
2218 | if (!(RREG32(GRBM_STATUS) & GUI_ACTIVE)) | ||
2219 | reset_mask &= ~(RADEON_RESET_GFX | RADEON_RESET_COMPUTE); | ||
2220 | |||
2221 | if (RREG32(DMA_STATUS_REG) & DMA_IDLE) | ||
2222 | reset_mask &= ~RADEON_RESET_DMA; | ||
2223 | |||
2224 | if (reset_mask == 0) | ||
2225 | return 0; | ||
2226 | |||
2227 | dev_info(rdev->dev, "GPU softreset: 0x%08X\n", reset_mask); | ||
2228 | |||
2229 | dev_info(rdev->dev, " VM_CONTEXT1_PROTECTION_FAULT_ADDR 0x%08X\n", | ||
2230 | RREG32(VM_CONTEXT1_PROTECTION_FAULT_ADDR)); | ||
2231 | dev_info(rdev->dev, " VM_CONTEXT1_PROTECTION_FAULT_STATUS 0x%08X\n", | ||
2232 | RREG32(VM_CONTEXT1_PROTECTION_FAULT_STATUS)); | ||
2233 | |||
2234 | evergreen_mc_stop(rdev, &save); | ||
2235 | if (radeon_mc_wait_for_idle(rdev)) { | ||
2236 | dev_warn(rdev->dev, "Wait for MC idle timedout !\n"); | ||
2237 | } | ||
2238 | |||
2239 | if (reset_mask & (RADEON_RESET_GFX | RADEON_RESET_COMPUTE)) | ||
2240 | si_gpu_soft_reset_gfx(rdev); | ||
2241 | |||
2242 | if (reset_mask & RADEON_RESET_DMA) | ||
2243 | si_gpu_soft_reset_dma(rdev); | ||
2244 | |||
2245 | /* Wait a little for things to settle down */ | ||
2246 | udelay(50); | ||
2247 | |||
2188 | evergreen_mc_resume(rdev, &save); | 2248 | evergreen_mc_resume(rdev, &save); |
2189 | return 0; | 2249 | return 0; |
2190 | } | 2250 | } |
2191 | 2251 | ||
2192 | int si_asic_reset(struct radeon_device *rdev) | 2252 | int si_asic_reset(struct radeon_device *rdev) |
2193 | { | 2253 | { |
2194 | return si_gpu_soft_reset(rdev); | 2254 | return si_gpu_soft_reset(rdev, (RADEON_RESET_GFX | |
2255 | RADEON_RESET_COMPUTE | | ||
2256 | RADEON_RESET_DMA)); | ||
2195 | } | 2257 | } |
2196 | 2258 | ||
2197 | /* MC */ | 2259 | /* MC */ |
diff --git a/drivers/gpu/drm/radeon/sid.h b/drivers/gpu/drm/radeon/sid.h index 62b46215d423..c056aae814f0 100644 --- a/drivers/gpu/drm/radeon/sid.h +++ b/drivers/gpu/drm/radeon/sid.h | |||
@@ -62,6 +62,22 @@ | |||
62 | 62 | ||
63 | #define SRBM_STATUS 0xE50 | 63 | #define SRBM_STATUS 0xE50 |
64 | 64 | ||
65 | #define SRBM_SOFT_RESET 0x0E60 | ||
66 | #define SOFT_RESET_BIF (1 << 1) | ||
67 | #define SOFT_RESET_DC (1 << 5) | ||
68 | #define SOFT_RESET_DMA1 (1 << 6) | ||
69 | #define SOFT_RESET_GRBM (1 << 8) | ||
70 | #define SOFT_RESET_HDP (1 << 9) | ||
71 | #define SOFT_RESET_IH (1 << 10) | ||
72 | #define SOFT_RESET_MC (1 << 11) | ||
73 | #define SOFT_RESET_ROM (1 << 14) | ||
74 | #define SOFT_RESET_SEM (1 << 15) | ||
75 | #define SOFT_RESET_VMC (1 << 17) | ||
76 | #define SOFT_RESET_DMA (1 << 20) | ||
77 | #define SOFT_RESET_TST (1 << 21) | ||
78 | #define SOFT_RESET_REGBB (1 << 22) | ||
79 | #define SOFT_RESET_ORB (1 << 23) | ||
80 | |||
65 | #define CC_SYS_RB_BACKEND_DISABLE 0xe80 | 81 | #define CC_SYS_RB_BACKEND_DISABLE 0xe80 |
66 | #define GC_USER_SYS_RB_BACKEND_DISABLE 0xe84 | 82 | #define GC_USER_SYS_RB_BACKEND_DISABLE 0xe84 |
67 | 83 | ||
@@ -1013,6 +1029,8 @@ | |||
1013 | # define DATA_SWAP_ENABLE (1 << 3) | 1029 | # define DATA_SWAP_ENABLE (1 << 3) |
1014 | # define FENCE_SWAP_ENABLE (1 << 4) | 1030 | # define FENCE_SWAP_ENABLE (1 << 4) |
1015 | # define CTXEMPTY_INT_ENABLE (1 << 28) | 1031 | # define CTXEMPTY_INT_ENABLE (1 << 28) |
1032 | #define DMA_STATUS_REG 0xd034 | ||
1033 | # define DMA_IDLE (1 << 0) | ||
1016 | #define DMA_TILING_CONFIG 0xd0b8 | 1034 | #define DMA_TILING_CONFIG 0xd0b8 |
1017 | 1035 | ||
1018 | #define DMA_PACKET(cmd, b, t, s, n) ((((cmd) & 0xF) << 28) | \ | 1036 | #define DMA_PACKET(cmd, b, t, s, n) ((((cmd) & 0xF) << 28) | \ |