diff options
-rw-r--r-- | drivers/gpu/drm/radeon/evergreen.c | 5 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/ni.c | 5 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/r100.c | 57 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/r300.c | 4 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/r600.c | 10 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/radeon.h | 16 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/radeon_asic.h | 5 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/radeon_ring.c | 53 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/si.c | 5 |
9 files changed, 69 insertions, 91 deletions
diff --git a/drivers/gpu/drm/radeon/evergreen.c b/drivers/gpu/drm/radeon/evergreen.c index 8b7a01b85374..66f05bba8a42 100644 --- a/drivers/gpu/drm/radeon/evergreen.c +++ b/drivers/gpu/drm/radeon/evergreen.c | |||
@@ -2424,7 +2424,6 @@ bool evergreen_gpu_is_lockup(struct radeon_device *rdev, struct radeon_ring *rin | |||
2424 | u32 srbm_status; | 2424 | u32 srbm_status; |
2425 | u32 grbm_status; | 2425 | u32 grbm_status; |
2426 | u32 grbm_status_se0, grbm_status_se1; | 2426 | u32 grbm_status_se0, grbm_status_se1; |
2427 | struct r100_gpu_lockup *lockup = &rdev->config.evergreen.lockup; | ||
2428 | int r; | 2427 | int r; |
2429 | 2428 | ||
2430 | srbm_status = RREG32(SRBM_STATUS); | 2429 | srbm_status = RREG32(SRBM_STATUS); |
@@ -2432,7 +2431,7 @@ bool evergreen_gpu_is_lockup(struct radeon_device *rdev, struct radeon_ring *rin | |||
2432 | grbm_status_se0 = RREG32(GRBM_STATUS_SE0); | 2431 | grbm_status_se0 = RREG32(GRBM_STATUS_SE0); |
2433 | grbm_status_se1 = RREG32(GRBM_STATUS_SE1); | 2432 | grbm_status_se1 = RREG32(GRBM_STATUS_SE1); |
2434 | if (!(grbm_status & GUI_ACTIVE)) { | 2433 | if (!(grbm_status & GUI_ACTIVE)) { |
2435 | r100_gpu_lockup_update(lockup, ring); | 2434 | radeon_ring_lockup_update(ring); |
2436 | return false; | 2435 | return false; |
2437 | } | 2436 | } |
2438 | /* force CP activities */ | 2437 | /* force CP activities */ |
@@ -2444,7 +2443,7 @@ bool evergreen_gpu_is_lockup(struct radeon_device *rdev, struct radeon_ring *rin | |||
2444 | radeon_ring_unlock_commit(rdev, ring); | 2443 | radeon_ring_unlock_commit(rdev, ring); |
2445 | } | 2444 | } |
2446 | ring->rptr = RREG32(CP_RB_RPTR); | 2445 | ring->rptr = RREG32(CP_RB_RPTR); |
2447 | return r100_gpu_cp_is_lockup(rdev, lockup, ring); | 2446 | return radeon_ring_test_lockup(rdev, ring); |
2448 | } | 2447 | } |
2449 | 2448 | ||
2450 | static int evergreen_gpu_soft_reset(struct radeon_device *rdev) | 2449 | static int evergreen_gpu_soft_reset(struct radeon_device *rdev) |
diff --git a/drivers/gpu/drm/radeon/ni.c b/drivers/gpu/drm/radeon/ni.c index 01464289d32c..8404b2a2386d 100644 --- a/drivers/gpu/drm/radeon/ni.c +++ b/drivers/gpu/drm/radeon/ni.c | |||
@@ -1397,7 +1397,6 @@ bool cayman_gpu_is_lockup(struct radeon_device *rdev, struct radeon_ring *ring) | |||
1397 | u32 srbm_status; | 1397 | u32 srbm_status; |
1398 | u32 grbm_status; | 1398 | u32 grbm_status; |
1399 | u32 grbm_status_se0, grbm_status_se1; | 1399 | u32 grbm_status_se0, grbm_status_se1; |
1400 | struct r100_gpu_lockup *lockup = &rdev->config.cayman.lockup; | ||
1401 | int r; | 1400 | int r; |
1402 | 1401 | ||
1403 | srbm_status = RREG32(SRBM_STATUS); | 1402 | srbm_status = RREG32(SRBM_STATUS); |
@@ -1405,7 +1404,7 @@ bool cayman_gpu_is_lockup(struct radeon_device *rdev, struct radeon_ring *ring) | |||
1405 | grbm_status_se0 = RREG32(GRBM_STATUS_SE0); | 1404 | grbm_status_se0 = RREG32(GRBM_STATUS_SE0); |
1406 | grbm_status_se1 = RREG32(GRBM_STATUS_SE1); | 1405 | grbm_status_se1 = RREG32(GRBM_STATUS_SE1); |
1407 | if (!(grbm_status & GUI_ACTIVE)) { | 1406 | if (!(grbm_status & GUI_ACTIVE)) { |
1408 | r100_gpu_lockup_update(lockup, ring); | 1407 | radeon_ring_lockup_update(ring); |
1409 | return false; | 1408 | return false; |
1410 | } | 1409 | } |
1411 | /* force CP activities */ | 1410 | /* force CP activities */ |
@@ -1418,7 +1417,7 @@ bool cayman_gpu_is_lockup(struct radeon_device *rdev, struct radeon_ring *ring) | |||
1418 | } | 1417 | } |
1419 | /* XXX deal with CP0,1,2 */ | 1418 | /* XXX deal with CP0,1,2 */ |
1420 | ring->rptr = RREG32(ring->rptr_reg); | 1419 | ring->rptr = RREG32(ring->rptr_reg); |
1421 | return r100_gpu_cp_is_lockup(rdev, lockup, ring); | 1420 | return radeon_ring_test_lockup(rdev, ring); |
1422 | } | 1421 | } |
1423 | 1422 | ||
1424 | static int cayman_gpu_soft_reset(struct radeon_device *rdev) | 1423 | static int cayman_gpu_soft_reset(struct radeon_device *rdev) |
diff --git a/drivers/gpu/drm/radeon/r100.c b/drivers/gpu/drm/radeon/r100.c index 825f11774491..ccf5e3b844d3 100644 --- a/drivers/gpu/drm/radeon/r100.c +++ b/drivers/gpu/drm/radeon/r100.c | |||
@@ -2159,59 +2159,6 @@ int r100_mc_wait_for_idle(struct radeon_device *rdev) | |||
2159 | return -1; | 2159 | return -1; |
2160 | } | 2160 | } |
2161 | 2161 | ||
2162 | void r100_gpu_lockup_update(struct r100_gpu_lockup *lockup, struct radeon_ring *ring) | ||
2163 | { | ||
2164 | lockup->last_cp_rptr = ring->rptr; | ||
2165 | lockup->last_jiffies = jiffies; | ||
2166 | } | ||
2167 | |||
2168 | /** | ||
2169 | * r100_gpu_cp_is_lockup() - check if CP is lockup by recording information | ||
2170 | * @rdev: radeon device structure | ||
2171 | * @lockup: r100_gpu_lockup structure holding CP lockup tracking informations | ||
2172 | * @cp: radeon_cp structure holding CP information | ||
2173 | * | ||
2174 | * We don't need to initialize the lockup tracking information as we will either | ||
2175 | * have CP rptr to a different value of jiffies wrap around which will force | ||
2176 | * initialization of the lockup tracking informations. | ||
2177 | * | ||
2178 | * A possible false positivie is if we get call after while and last_cp_rptr == | ||
2179 | * the current CP rptr, even if it's unlikely it might happen. To avoid this | ||
2180 | * if the elapsed time since last call is bigger than 2 second than we return | ||
2181 | * false and update the tracking information. Due to this the caller must call | ||
2182 | * r100_gpu_cp_is_lockup several time in less than 2sec for lockup to be reported | ||
2183 | * the fencing code should be cautious about that. | ||
2184 | * | ||
2185 | * Caller should write to the ring to force CP to do something so we don't get | ||
2186 | * false positive when CP is just gived nothing to do. | ||
2187 | * | ||
2188 | **/ | ||
2189 | bool r100_gpu_cp_is_lockup(struct radeon_device *rdev, struct r100_gpu_lockup *lockup, struct radeon_ring *ring) | ||
2190 | { | ||
2191 | unsigned long cjiffies, elapsed; | ||
2192 | |||
2193 | cjiffies = jiffies; | ||
2194 | if (!time_after(cjiffies, lockup->last_jiffies)) { | ||
2195 | /* likely a wrap around */ | ||
2196 | lockup->last_cp_rptr = ring->rptr; | ||
2197 | lockup->last_jiffies = jiffies; | ||
2198 | return false; | ||
2199 | } | ||
2200 | if (ring->rptr != lockup->last_cp_rptr) { | ||
2201 | /* CP is still working no lockup */ | ||
2202 | lockup->last_cp_rptr = ring->rptr; | ||
2203 | lockup->last_jiffies = jiffies; | ||
2204 | return false; | ||
2205 | } | ||
2206 | elapsed = jiffies_to_msecs(cjiffies - lockup->last_jiffies); | ||
2207 | if (elapsed >= 10000) { | ||
2208 | dev_err(rdev->dev, "GPU lockup CP stall for more than %lumsec\n", elapsed); | ||
2209 | return true; | ||
2210 | } | ||
2211 | /* give a chance to the GPU ... */ | ||
2212 | return false; | ||
2213 | } | ||
2214 | |||
2215 | bool r100_gpu_is_lockup(struct radeon_device *rdev, struct radeon_ring *ring) | 2162 | bool r100_gpu_is_lockup(struct radeon_device *rdev, struct radeon_ring *ring) |
2216 | { | 2163 | { |
2217 | u32 rbbm_status; | 2164 | u32 rbbm_status; |
@@ -2219,7 +2166,7 @@ bool r100_gpu_is_lockup(struct radeon_device *rdev, struct radeon_ring *ring) | |||
2219 | 2166 | ||
2220 | rbbm_status = RREG32(R_000E40_RBBM_STATUS); | 2167 | rbbm_status = RREG32(R_000E40_RBBM_STATUS); |
2221 | if (!G_000E40_GUI_ACTIVE(rbbm_status)) { | 2168 | if (!G_000E40_GUI_ACTIVE(rbbm_status)) { |
2222 | r100_gpu_lockup_update(&rdev->config.r100.lockup, ring); | 2169 | radeon_ring_lockup_update(ring); |
2223 | return false; | 2170 | return false; |
2224 | } | 2171 | } |
2225 | /* force CP activities */ | 2172 | /* force CP activities */ |
@@ -2231,7 +2178,7 @@ bool r100_gpu_is_lockup(struct radeon_device *rdev, struct radeon_ring *ring) | |||
2231 | radeon_ring_unlock_commit(rdev, ring); | 2178 | radeon_ring_unlock_commit(rdev, ring); |
2232 | } | 2179 | } |
2233 | ring->rptr = RREG32(ring->rptr_reg); | 2180 | ring->rptr = RREG32(ring->rptr_reg); |
2234 | return r100_gpu_cp_is_lockup(rdev, &rdev->config.r100.lockup, ring); | 2181 | return radeon_ring_test_lockup(rdev, ring); |
2235 | } | 2182 | } |
2236 | 2183 | ||
2237 | void r100_bm_disable(struct radeon_device *rdev) | 2184 | void r100_bm_disable(struct radeon_device *rdev) |
diff --git a/drivers/gpu/drm/radeon/r300.c b/drivers/gpu/drm/radeon/r300.c index 26e0db87beb5..e207664bbdc7 100644 --- a/drivers/gpu/drm/radeon/r300.c +++ b/drivers/gpu/drm/radeon/r300.c | |||
@@ -384,7 +384,7 @@ bool r300_gpu_is_lockup(struct radeon_device *rdev, struct radeon_ring *ring) | |||
384 | 384 | ||
385 | rbbm_status = RREG32(R_000E40_RBBM_STATUS); | 385 | rbbm_status = RREG32(R_000E40_RBBM_STATUS); |
386 | if (!G_000E40_GUI_ACTIVE(rbbm_status)) { | 386 | if (!G_000E40_GUI_ACTIVE(rbbm_status)) { |
387 | r100_gpu_lockup_update(&rdev->config.r300.lockup, ring); | 387 | radeon_ring_lockup_update(ring); |
388 | return false; | 388 | return false; |
389 | } | 389 | } |
390 | /* force CP activities */ | 390 | /* force CP activities */ |
@@ -396,7 +396,7 @@ bool r300_gpu_is_lockup(struct radeon_device *rdev, struct radeon_ring *ring) | |||
396 | radeon_ring_unlock_commit(rdev, ring); | 396 | radeon_ring_unlock_commit(rdev, ring); |
397 | } | 397 | } |
398 | ring->rptr = RREG32(RADEON_CP_RB_RPTR); | 398 | ring->rptr = RREG32(RADEON_CP_RB_RPTR); |
399 | return r100_gpu_cp_is_lockup(rdev, &rdev->config.r300.lockup, ring); | 399 | return radeon_ring_test_lockup(rdev, ring); |
400 | } | 400 | } |
401 | 401 | ||
402 | int r300_asic_reset(struct radeon_device *rdev) | 402 | int r300_asic_reset(struct radeon_device *rdev) |
diff --git a/drivers/gpu/drm/radeon/r600.c b/drivers/gpu/drm/radeon/r600.c index 6070f9099507..45d52ccc457a 100644 --- a/drivers/gpu/drm/radeon/r600.c +++ b/drivers/gpu/drm/radeon/r600.c | |||
@@ -1350,19 +1350,13 @@ bool r600_gpu_is_lockup(struct radeon_device *rdev, struct radeon_ring *ring) | |||
1350 | u32 srbm_status; | 1350 | u32 srbm_status; |
1351 | u32 grbm_status; | 1351 | u32 grbm_status; |
1352 | u32 grbm_status2; | 1352 | u32 grbm_status2; |
1353 | struct r100_gpu_lockup *lockup; | ||
1354 | int r; | 1353 | int r; |
1355 | 1354 | ||
1356 | if (rdev->family >= CHIP_RV770) | ||
1357 | lockup = &rdev->config.rv770.lockup; | ||
1358 | else | ||
1359 | lockup = &rdev->config.r600.lockup; | ||
1360 | |||
1361 | srbm_status = RREG32(R_000E50_SRBM_STATUS); | 1355 | srbm_status = RREG32(R_000E50_SRBM_STATUS); |
1362 | grbm_status = RREG32(R_008010_GRBM_STATUS); | 1356 | grbm_status = RREG32(R_008010_GRBM_STATUS); |
1363 | grbm_status2 = RREG32(R_008014_GRBM_STATUS2); | 1357 | grbm_status2 = RREG32(R_008014_GRBM_STATUS2); |
1364 | if (!G_008010_GUI_ACTIVE(grbm_status)) { | 1358 | if (!G_008010_GUI_ACTIVE(grbm_status)) { |
1365 | r100_gpu_lockup_update(lockup, ring); | 1359 | radeon_ring_lockup_update(ring); |
1366 | return false; | 1360 | return false; |
1367 | } | 1361 | } |
1368 | /* force CP activities */ | 1362 | /* force CP activities */ |
@@ -1374,7 +1368,7 @@ bool r600_gpu_is_lockup(struct radeon_device *rdev, struct radeon_ring *ring) | |||
1374 | radeon_ring_unlock_commit(rdev, ring); | 1368 | radeon_ring_unlock_commit(rdev, ring); |
1375 | } | 1369 | } |
1376 | ring->rptr = RREG32(ring->rptr_reg); | 1370 | ring->rptr = RREG32(ring->rptr_reg); |
1377 | return r100_gpu_cp_is_lockup(rdev, lockup, ring); | 1371 | return radeon_ring_test_lockup(rdev, ring); |
1378 | } | 1372 | } |
1379 | 1373 | ||
1380 | int r600_asic_reset(struct radeon_device *rdev) | 1374 | int r600_asic_reset(struct radeon_device *rdev) |
diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h index f7372c41f16b..b8d4d947c347 100644 --- a/drivers/gpu/drm/radeon/radeon.h +++ b/drivers/gpu/drm/radeon/radeon.h | |||
@@ -670,6 +670,8 @@ struct radeon_ring { | |||
670 | unsigned ring_size; | 670 | unsigned ring_size; |
671 | unsigned ring_free_dw; | 671 | unsigned ring_free_dw; |
672 | int count_dw; | 672 | int count_dw; |
673 | unsigned long last_activity; | ||
674 | unsigned last_rptr; | ||
673 | uint64_t gpu_addr; | 675 | uint64_t gpu_addr; |
674 | uint32_t align_mask; | 676 | uint32_t align_mask; |
675 | uint32_t ptr_mask; | 677 | uint32_t ptr_mask; |
@@ -814,6 +816,8 @@ void radeon_ring_commit(struct radeon_device *rdev, struct radeon_ring *cp); | |||
814 | void radeon_ring_unlock_commit(struct radeon_device *rdev, struct radeon_ring *cp); | 816 | void radeon_ring_unlock_commit(struct radeon_device *rdev, struct radeon_ring *cp); |
815 | void radeon_ring_unlock_undo(struct radeon_device *rdev, struct radeon_ring *cp); | 817 | void radeon_ring_unlock_undo(struct radeon_device *rdev, struct radeon_ring *cp); |
816 | int radeon_ring_test(struct radeon_device *rdev, struct radeon_ring *cp); | 818 | int radeon_ring_test(struct radeon_device *rdev, struct radeon_ring *cp); |
819 | void radeon_ring_lockup_update(struct radeon_ring *ring); | ||
820 | bool radeon_ring_test_lockup(struct radeon_device *rdev, struct radeon_ring *ring); | ||
817 | int radeon_ring_init(struct radeon_device *rdev, struct radeon_ring *cp, unsigned ring_size, | 821 | int radeon_ring_init(struct radeon_device *rdev, struct radeon_ring *cp, unsigned ring_size, |
818 | unsigned rptr_offs, unsigned rptr_reg, unsigned wptr_reg, | 822 | unsigned rptr_offs, unsigned rptr_reg, unsigned wptr_reg, |
819 | u32 ptr_reg_shift, u32 ptr_reg_mask, u32 nop); | 823 | u32 ptr_reg_shift, u32 ptr_reg_mask, u32 nop); |
@@ -1272,16 +1276,10 @@ struct radeon_asic { | |||
1272 | /* | 1276 | /* |
1273 | * Asic structures | 1277 | * Asic structures |
1274 | */ | 1278 | */ |
1275 | struct r100_gpu_lockup { | ||
1276 | unsigned long last_jiffies; | ||
1277 | u32 last_cp_rptr; | ||
1278 | }; | ||
1279 | |||
1280 | struct r100_asic { | 1279 | struct r100_asic { |
1281 | const unsigned *reg_safe_bm; | 1280 | const unsigned *reg_safe_bm; |
1282 | unsigned reg_safe_bm_size; | 1281 | unsigned reg_safe_bm_size; |
1283 | u32 hdp_cntl; | 1282 | u32 hdp_cntl; |
1284 | struct r100_gpu_lockup lockup; | ||
1285 | }; | 1283 | }; |
1286 | 1284 | ||
1287 | struct r300_asic { | 1285 | struct r300_asic { |
@@ -1289,7 +1287,6 @@ struct r300_asic { | |||
1289 | unsigned reg_safe_bm_size; | 1287 | unsigned reg_safe_bm_size; |
1290 | u32 resync_scratch; | 1288 | u32 resync_scratch; |
1291 | u32 hdp_cntl; | 1289 | u32 hdp_cntl; |
1292 | struct r100_gpu_lockup lockup; | ||
1293 | }; | 1290 | }; |
1294 | 1291 | ||
1295 | struct r600_asic { | 1292 | struct r600_asic { |
@@ -1311,7 +1308,6 @@ struct r600_asic { | |||
1311 | unsigned tiling_group_size; | 1308 | unsigned tiling_group_size; |
1312 | unsigned tile_config; | 1309 | unsigned tile_config; |
1313 | unsigned backend_map; | 1310 | unsigned backend_map; |
1314 | struct r100_gpu_lockup lockup; | ||
1315 | }; | 1311 | }; |
1316 | 1312 | ||
1317 | struct rv770_asic { | 1313 | struct rv770_asic { |
@@ -1337,7 +1333,6 @@ struct rv770_asic { | |||
1337 | unsigned tiling_group_size; | 1333 | unsigned tiling_group_size; |
1338 | unsigned tile_config; | 1334 | unsigned tile_config; |
1339 | unsigned backend_map; | 1335 | unsigned backend_map; |
1340 | struct r100_gpu_lockup lockup; | ||
1341 | }; | 1336 | }; |
1342 | 1337 | ||
1343 | struct evergreen_asic { | 1338 | struct evergreen_asic { |
@@ -1364,7 +1359,6 @@ struct evergreen_asic { | |||
1364 | unsigned tiling_group_size; | 1359 | unsigned tiling_group_size; |
1365 | unsigned tile_config; | 1360 | unsigned tile_config; |
1366 | unsigned backend_map; | 1361 | unsigned backend_map; |
1367 | struct r100_gpu_lockup lockup; | ||
1368 | }; | 1362 | }; |
1369 | 1363 | ||
1370 | struct cayman_asic { | 1364 | struct cayman_asic { |
@@ -1403,7 +1397,6 @@ struct cayman_asic { | |||
1403 | unsigned multi_gpu_tile_size; | 1397 | unsigned multi_gpu_tile_size; |
1404 | 1398 | ||
1405 | unsigned tile_config; | 1399 | unsigned tile_config; |
1406 | struct r100_gpu_lockup lockup; | ||
1407 | }; | 1400 | }; |
1408 | 1401 | ||
1409 | struct si_asic { | 1402 | struct si_asic { |
@@ -1434,7 +1427,6 @@ struct si_asic { | |||
1434 | unsigned multi_gpu_tile_size; | 1427 | unsigned multi_gpu_tile_size; |
1435 | 1428 | ||
1436 | unsigned tile_config; | 1429 | unsigned tile_config; |
1437 | struct r100_gpu_lockup lockup; | ||
1438 | }; | 1430 | }; |
1439 | 1431 | ||
1440 | union radeon_asic_config { | 1432 | union radeon_asic_config { |
diff --git a/drivers/gpu/drm/radeon/radeon_asic.h b/drivers/gpu/drm/radeon/radeon_asic.h index b135bec649d1..b0941f9cdfa5 100644 --- a/drivers/gpu/drm/radeon/radeon_asic.h +++ b/drivers/gpu/drm/radeon/radeon_asic.h | |||
@@ -103,11 +103,6 @@ int r100_pci_gart_enable(struct radeon_device *rdev); | |||
103 | void r100_pci_gart_disable(struct radeon_device *rdev); | 103 | void r100_pci_gart_disable(struct radeon_device *rdev); |
104 | int r100_debugfs_mc_info_init(struct radeon_device *rdev); | 104 | int r100_debugfs_mc_info_init(struct radeon_device *rdev); |
105 | int r100_gui_wait_for_idle(struct radeon_device *rdev); | 105 | int r100_gui_wait_for_idle(struct radeon_device *rdev); |
106 | void r100_gpu_lockup_update(struct r100_gpu_lockup *lockup, | ||
107 | struct radeon_ring *cp); | ||
108 | bool r100_gpu_cp_is_lockup(struct radeon_device *rdev, | ||
109 | struct r100_gpu_lockup *lockup, | ||
110 | struct radeon_ring *cp); | ||
111 | void r100_ib_fini(struct radeon_device *rdev); | 106 | void r100_ib_fini(struct radeon_device *rdev); |
112 | int r100_ib_test(struct radeon_device *rdev, struct radeon_ring *ring); | 107 | int r100_ib_test(struct radeon_device *rdev, struct radeon_ring *ring); |
113 | void r100_irq_disable(struct radeon_device *rdev); | 108 | void r100_irq_disable(struct radeon_device *rdev); |
diff --git a/drivers/gpu/drm/radeon/radeon_ring.c b/drivers/gpu/drm/radeon/radeon_ring.c index 1b020ef7fcdd..203ec1f6bbb9 100644 --- a/drivers/gpu/drm/radeon/radeon_ring.c +++ b/drivers/gpu/drm/radeon/radeon_ring.c | |||
@@ -396,6 +396,59 @@ void radeon_ring_unlock_undo(struct radeon_device *rdev, struct radeon_ring *rin | |||
396 | mutex_unlock(&ring->mutex); | 396 | mutex_unlock(&ring->mutex); |
397 | } | 397 | } |
398 | 398 | ||
399 | void radeon_ring_lockup_update(struct radeon_ring *ring) | ||
400 | { | ||
401 | ring->last_rptr = ring->rptr; | ||
402 | ring->last_activity = jiffies; | ||
403 | } | ||
404 | |||
405 | /** | ||
406 | * radeon_ring_test_lockup() - check if ring is lockedup by recording information | ||
407 | * @rdev: radeon device structure | ||
408 | * @ring: radeon_ring structure holding ring information | ||
409 | * | ||
410 | * We don't need to initialize the lockup tracking information as we will either | ||
411 | * have CP rptr to a different value of jiffies wrap around which will force | ||
412 | * initialization of the lockup tracking informations. | ||
413 | * | ||
414 | * A possible false positivie is if we get call after while and last_cp_rptr == | ||
415 | * the current CP rptr, even if it's unlikely it might happen. To avoid this | ||
416 | * if the elapsed time since last call is bigger than 2 second than we return | ||
417 | * false and update the tracking information. Due to this the caller must call | ||
418 | * radeon_ring_test_lockup several time in less than 2sec for lockup to be reported | ||
419 | * the fencing code should be cautious about that. | ||
420 | * | ||
421 | * Caller should write to the ring to force CP to do something so we don't get | ||
422 | * false positive when CP is just gived nothing to do. | ||
423 | * | ||
424 | **/ | ||
425 | bool radeon_ring_test_lockup(struct radeon_device *rdev, struct radeon_ring *ring) | ||
426 | { | ||
427 | unsigned long cjiffies, elapsed; | ||
428 | uint32_t rptr; | ||
429 | |||
430 | cjiffies = jiffies; | ||
431 | if (!time_after(cjiffies, ring->last_activity)) { | ||
432 | /* likely a wrap around */ | ||
433 | radeon_ring_lockup_update(ring); | ||
434 | return false; | ||
435 | } | ||
436 | rptr = RREG32(ring->rptr_reg); | ||
437 | ring->rptr = (rptr & ring->ptr_reg_mask) >> ring->ptr_reg_shift; | ||
438 | if (ring->rptr != ring->last_rptr) { | ||
439 | /* CP is still working no lockup */ | ||
440 | radeon_ring_lockup_update(ring); | ||
441 | return false; | ||
442 | } | ||
443 | elapsed = jiffies_to_msecs(cjiffies - ring->last_activity); | ||
444 | if (elapsed >= 10000) { | ||
445 | dev_err(rdev->dev, "GPU lockup CP stall for more than %lumsec\n", elapsed); | ||
446 | return true; | ||
447 | } | ||
448 | /* give a chance to the GPU ... */ | ||
449 | return false; | ||
450 | } | ||
451 | |||
399 | int radeon_ring_init(struct radeon_device *rdev, struct radeon_ring *ring, unsigned ring_size, | 452 | int radeon_ring_init(struct radeon_device *rdev, struct radeon_ring *ring, unsigned ring_size, |
400 | unsigned rptr_offs, unsigned rptr_reg, unsigned wptr_reg, | 453 | unsigned rptr_offs, unsigned rptr_reg, unsigned wptr_reg, |
401 | u32 ptr_reg_shift, u32 ptr_reg_mask, u32 nop) | 454 | u32 ptr_reg_shift, u32 ptr_reg_mask, u32 nop) |
diff --git a/drivers/gpu/drm/radeon/si.c b/drivers/gpu/drm/radeon/si.c index 14919e1539fa..c2422f514202 100644 --- a/drivers/gpu/drm/radeon/si.c +++ b/drivers/gpu/drm/radeon/si.c | |||
@@ -2217,7 +2217,6 @@ bool si_gpu_is_lockup(struct radeon_device *rdev, struct radeon_ring *ring) | |||
2217 | u32 srbm_status; | 2217 | u32 srbm_status; |
2218 | u32 grbm_status, grbm_status2; | 2218 | u32 grbm_status, grbm_status2; |
2219 | u32 grbm_status_se0, grbm_status_se1; | 2219 | u32 grbm_status_se0, grbm_status_se1; |
2220 | struct r100_gpu_lockup *lockup = &rdev->config.si.lockup; | ||
2221 | int r; | 2220 | int r; |
2222 | 2221 | ||
2223 | srbm_status = RREG32(SRBM_STATUS); | 2222 | srbm_status = RREG32(SRBM_STATUS); |
@@ -2226,7 +2225,7 @@ bool si_gpu_is_lockup(struct radeon_device *rdev, struct radeon_ring *ring) | |||
2226 | grbm_status_se0 = RREG32(GRBM_STATUS_SE0); | 2225 | grbm_status_se0 = RREG32(GRBM_STATUS_SE0); |
2227 | grbm_status_se1 = RREG32(GRBM_STATUS_SE1); | 2226 | grbm_status_se1 = RREG32(GRBM_STATUS_SE1); |
2228 | if (!(grbm_status & GUI_ACTIVE)) { | 2227 | if (!(grbm_status & GUI_ACTIVE)) { |
2229 | r100_gpu_lockup_update(lockup, ring); | 2228 | radeon_ring_lockup_update(ring); |
2230 | return false; | 2229 | return false; |
2231 | } | 2230 | } |
2232 | /* force CP activities */ | 2231 | /* force CP activities */ |
@@ -2239,7 +2238,7 @@ bool si_gpu_is_lockup(struct radeon_device *rdev, struct radeon_ring *ring) | |||
2239 | } | 2238 | } |
2240 | /* XXX deal with CP0,1,2 */ | 2239 | /* XXX deal with CP0,1,2 */ |
2241 | ring->rptr = RREG32(ring->rptr_reg); | 2240 | ring->rptr = RREG32(ring->rptr_reg); |
2242 | return r100_gpu_cp_is_lockup(rdev, lockup, ring); | 2241 | return radeon_ring_test_lockup(rdev, ring); |
2243 | } | 2242 | } |
2244 | 2243 | ||
2245 | static int si_gpu_soft_reset(struct radeon_device *rdev) | 2244 | static int si_gpu_soft_reset(struct radeon_device *rdev) |