diff options
Diffstat (limited to 'drivers/gpu/drm/i915/i915_gem.c')
-rw-r--r-- | drivers/gpu/drm/i915/i915_gem.c | 41 |
1 files changed, 27 insertions, 14 deletions
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 12bbd5eac70d..76d3d1ab73c6 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c | |||
@@ -2343,15 +2343,24 @@ static void i915_gem_free_request(struct drm_i915_gem_request *request) | |||
2343 | kfree(request); | 2343 | kfree(request); |
2344 | } | 2344 | } |
2345 | 2345 | ||
2346 | static void i915_gem_reset_ring_lists(struct drm_i915_private *dev_priv, | 2346 | static void i915_gem_reset_ring_status(struct drm_i915_private *dev_priv, |
2347 | struct intel_ring_buffer *ring) | 2347 | struct intel_ring_buffer *ring) |
2348 | { | 2348 | { |
2349 | u32 completed_seqno; | 2349 | u32 completed_seqno = ring->get_seqno(ring, false); |
2350 | u32 acthd; | 2350 | u32 acthd = intel_ring_get_active_head(ring); |
2351 | struct drm_i915_gem_request *request; | ||
2352 | |||
2353 | list_for_each_entry(request, &ring->request_list, list) { | ||
2354 | if (i915_seqno_passed(completed_seqno, request->seqno)) | ||
2355 | continue; | ||
2351 | 2356 | ||
2352 | acthd = intel_ring_get_active_head(ring); | 2357 | i915_set_reset_status(ring, request, acthd); |
2353 | completed_seqno = ring->get_seqno(ring, false); | 2358 | } |
2359 | } | ||
2354 | 2360 | ||
2361 | static void i915_gem_reset_ring_cleanup(struct drm_i915_private *dev_priv, | ||
2362 | struct intel_ring_buffer *ring) | ||
2363 | { | ||
2355 | while (!list_empty(&ring->request_list)) { | 2364 | while (!list_empty(&ring->request_list)) { |
2356 | struct drm_i915_gem_request *request; | 2365 | struct drm_i915_gem_request *request; |
2357 | 2366 | ||
@@ -2359,9 +2368,6 @@ static void i915_gem_reset_ring_lists(struct drm_i915_private *dev_priv, | |||
2359 | struct drm_i915_gem_request, | 2368 | struct drm_i915_gem_request, |
2360 | list); | 2369 | list); |
2361 | 2370 | ||
2362 | if (request->seqno > completed_seqno) | ||
2363 | i915_set_reset_status(ring, request, acthd); | ||
2364 | |||
2365 | i915_gem_free_request(request); | 2371 | i915_gem_free_request(request); |
2366 | } | 2372 | } |
2367 | 2373 | ||
@@ -2403,8 +2409,16 @@ void i915_gem_reset(struct drm_device *dev) | |||
2403 | struct intel_ring_buffer *ring; | 2409 | struct intel_ring_buffer *ring; |
2404 | int i; | 2410 | int i; |
2405 | 2411 | ||
2412 | /* | ||
2413 | * Before we free the objects from the requests, we need to inspect | ||
2414 | * them for finding the guilty party. As the requests only borrow | ||
2415 | * their reference to the objects, the inspection must be done first. | ||
2416 | */ | ||
2417 | for_each_ring(ring, dev_priv, i) | ||
2418 | i915_gem_reset_ring_status(dev_priv, ring); | ||
2419 | |||
2406 | for_each_ring(ring, dev_priv, i) | 2420 | for_each_ring(ring, dev_priv, i) |
2407 | i915_gem_reset_ring_lists(dev_priv, ring); | 2421 | i915_gem_reset_ring_cleanup(dev_priv, ring); |
2408 | 2422 | ||
2409 | i915_gem_cleanup_ringbuffer(dev); | 2423 | i915_gem_cleanup_ringbuffer(dev); |
2410 | 2424 | ||
@@ -4442,10 +4456,9 @@ i915_gem_init_hw(struct drm_device *dev) | |||
4442 | if (dev_priv->ellc_size) | 4456 | if (dev_priv->ellc_size) |
4443 | I915_WRITE(HSW_IDICR, I915_READ(HSW_IDICR) | IDIHASHMSK(0xf)); | 4457 | I915_WRITE(HSW_IDICR, I915_READ(HSW_IDICR) | IDIHASHMSK(0xf)); |
4444 | 4458 | ||
4445 | if (IS_HSW_GT3(dev)) | 4459 | if (IS_HASWELL(dev)) |
4446 | I915_WRITE(MI_PREDICATE_RESULT_2, LOWER_SLICE_ENABLED); | 4460 | I915_WRITE(MI_PREDICATE_RESULT_2, IS_HSW_GT3(dev) ? |
4447 | else | 4461 | LOWER_SLICE_ENABLED : LOWER_SLICE_DISABLED); |
4448 | I915_WRITE(MI_PREDICATE_RESULT_2, LOWER_SLICE_DISABLED); | ||
4449 | 4462 | ||
4450 | if (HAS_PCH_NOP(dev)) { | 4463 | if (HAS_PCH_NOP(dev)) { |
4451 | u32 temp = I915_READ(GEN7_MSG_CTL); | 4464 | u32 temp = I915_READ(GEN7_MSG_CTL); |