diff options
Diffstat (limited to 'drivers/gpu/drm/radeon/r100.c')
-rw-r--r-- | drivers/gpu/drm/radeon/r100.c | 77 |
1 files changed, 6 insertions, 71 deletions
diff --git a/drivers/gpu/drm/radeon/r100.c b/drivers/gpu/drm/radeon/r100.c index cb1141854282..ad6ceb731713 100644 --- a/drivers/gpu/drm/radeon/r100.c +++ b/drivers/gpu/drm/radeon/r100.c | |||
@@ -660,7 +660,7 @@ int r100_pci_gart_enable(struct radeon_device *rdev) | |||
660 | tmp = RREG32(RADEON_AIC_CNTL) | RADEON_PCIGART_TRANSLATE_EN; | 660 | tmp = RREG32(RADEON_AIC_CNTL) | RADEON_PCIGART_TRANSLATE_EN; |
661 | WREG32(RADEON_AIC_CNTL, tmp); | 661 | WREG32(RADEON_AIC_CNTL, tmp); |
662 | r100_pci_gart_tlb_flush(rdev); | 662 | r100_pci_gart_tlb_flush(rdev); |
663 | DRM_INFO("PCIE GART of %uM enabled (table at 0x%016llX).\n", | 663 | DRM_INFO("PCI GART of %uM enabled (table at 0x%016llX).\n", |
664 | (unsigned)(rdev->mc.gtt_size >> 20), | 664 | (unsigned)(rdev->mc.gtt_size >> 20), |
665 | (unsigned long long)rdev->gart.table_addr); | 665 | (unsigned long long)rdev->gart.table_addr); |
666 | rdev->gart.ready = true; | 666 | rdev->gart.ready = true; |
@@ -2159,79 +2159,18 @@ 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; |
2218 | int r; | ||
2219 | 2165 | ||
2220 | rbbm_status = RREG32(R_000E40_RBBM_STATUS); | 2166 | rbbm_status = RREG32(R_000E40_RBBM_STATUS); |
2221 | if (!G_000E40_GUI_ACTIVE(rbbm_status)) { | 2167 | if (!G_000E40_GUI_ACTIVE(rbbm_status)) { |
2222 | r100_gpu_lockup_update(&rdev->config.r100.lockup, ring); | 2168 | radeon_ring_lockup_update(ring); |
2223 | return false; | 2169 | return false; |
2224 | } | 2170 | } |
2225 | /* force CP activities */ | 2171 | /* force CP activities */ |
2226 | r = radeon_ring_lock(rdev, ring, 2); | 2172 | radeon_ring_force_activity(rdev, ring); |
2227 | if (!r) { | 2173 | return radeon_ring_test_lockup(rdev, ring); |
2228 | /* PACKET2 NOP */ | ||
2229 | radeon_ring_write(ring, 0x80000000); | ||
2230 | radeon_ring_write(ring, 0x80000000); | ||
2231 | radeon_ring_unlock_commit(rdev, ring); | ||
2232 | } | ||
2233 | ring->rptr = RREG32(ring->rptr_reg); | ||
2234 | return r100_gpu_cp_is_lockup(rdev, &rdev->config.r100.lockup, ring); | ||
2235 | } | 2174 | } |
2236 | 2175 | ||
2237 | void r100_bm_disable(struct radeon_device *rdev) | 2176 | void r100_bm_disable(struct radeon_device *rdev) |
@@ -2300,7 +2239,6 @@ int r100_asic_reset(struct radeon_device *rdev) | |||
2300 | if (G_000E40_SE_BUSY(status) || G_000E40_RE_BUSY(status) || | 2239 | if (G_000E40_SE_BUSY(status) || G_000E40_RE_BUSY(status) || |
2301 | G_000E40_TAM_BUSY(status) || G_000E40_PB_BUSY(status)) { | 2240 | G_000E40_TAM_BUSY(status) || G_000E40_PB_BUSY(status)) { |
2302 | dev_err(rdev->dev, "failed to reset GPU\n"); | 2241 | dev_err(rdev->dev, "failed to reset GPU\n"); |
2303 | rdev->gpu_lockup = true; | ||
2304 | ret = -1; | 2242 | ret = -1; |
2305 | } else | 2243 | } else |
2306 | dev_info(rdev->dev, "GPU reset succeed\n"); | 2244 | dev_info(rdev->dev, "GPU reset succeed\n"); |
@@ -3969,12 +3907,9 @@ static int r100_startup(struct radeon_device *rdev) | |||
3969 | if (r) | 3907 | if (r) |
3970 | return r; | 3908 | return r; |
3971 | 3909 | ||
3972 | r = radeon_ib_test(rdev, RADEON_RING_TYPE_GFX_INDEX, &rdev->ring[RADEON_RING_TYPE_GFX_INDEX]); | 3910 | r = radeon_ib_ring_tests(rdev); |
3973 | if (r) { | 3911 | if (r) |
3974 | dev_err(rdev->dev, "failed testing IB (%d).\n", r); | ||
3975 | rdev->accel_working = false; | ||
3976 | return r; | 3912 | return r; |
3977 | } | ||
3978 | 3913 | ||
3979 | return 0; | 3914 | return 0; |
3980 | } | 3915 | } |