aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/i915/intel_display.c
diff options
context:
space:
mode:
authorMaarten Lankhorst <maarten.lankhorst@linux.intel.com>2015-08-18 07:40:06 -0400
committerMaarten Lankhorst <maarten.lankhorst@linux.intel.com>2015-11-02 09:50:31 -0500
commit7580d774b0466fff28aab19db4f36dac37a3d1a9 (patch)
tree9b5024b8be800450c9bd1f26d9691b165faba675 /drivers/gpu/drm/i915/intel_display.c
parentf935675f0c07f87da2facc4c144d511e6da48240 (diff)
drm/i915: Wait for object idle without locks in atomic_commit, v2.
Make pinning and waiting a separate step, and wait for object idle without struct_mutex held. Changes since v1: - Do not wait when a reset is in progress. - Remove call to i915_gem_object_wait_rendering for intel_overlay_do_put_image (Chris Wilson) Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Reviewed-by: Chris Wilson <chris@chris-wilson.co.uk>
Diffstat (limited to 'drivers/gpu/drm/i915/intel_display.c')
-rw-r--r--drivers/gpu/drm/i915/intel_display.c82
1 files changed, 69 insertions, 13 deletions
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 8393759782d0..2e5164265250 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -2320,9 +2320,7 @@ static unsigned int intel_linear_alignment(struct drm_i915_private *dev_priv)
2320int 2320int
2321intel_pin_and_fence_fb_obj(struct drm_plane *plane, 2321intel_pin_and_fence_fb_obj(struct drm_plane *plane,
2322 struct drm_framebuffer *fb, 2322 struct drm_framebuffer *fb,
2323 const struct drm_plane_state *plane_state, 2323 const struct drm_plane_state *plane_state)
2324 struct intel_engine_cs *pipelined,
2325 struct drm_i915_gem_request **pipelined_request)
2326{ 2324{
2327 struct drm_device *dev = fb->dev; 2325 struct drm_device *dev = fb->dev;
2328 struct drm_i915_private *dev_priv = dev->dev_private; 2326 struct drm_i915_private *dev_priv = dev->dev_private;
@@ -2378,8 +2376,8 @@ intel_pin_and_fence_fb_obj(struct drm_plane *plane,
2378 */ 2376 */
2379 intel_runtime_pm_get(dev_priv); 2377 intel_runtime_pm_get(dev_priv);
2380 2378
2381 ret = i915_gem_object_pin_to_display_plane(obj, alignment, pipelined, 2379 ret = i915_gem_object_pin_to_display_plane(obj, alignment,
2382 pipelined_request, &view); 2380 &view);
2383 if (ret) 2381 if (ret)
2384 goto err_pm; 2382 goto err_pm;
2385 2383
@@ -11426,9 +11424,14 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc,
11426 * synchronisation, so all we want here is to pin the framebuffer 11424 * synchronisation, so all we want here is to pin the framebuffer
11427 * into the display plane and skip any waits. 11425 * into the display plane and skip any waits.
11428 */ 11426 */
11427 if (!mmio_flip) {
11428 ret = i915_gem_object_sync(obj, ring, &request);
11429 if (ret)
11430 goto cleanup_pending;
11431 }
11432
11429 ret = intel_pin_and_fence_fb_obj(crtc->primary, fb, 11433 ret = intel_pin_and_fence_fb_obj(crtc->primary, fb,
11430 crtc->primary->state, 11434 crtc->primary->state);
11431 mmio_flip ? i915_gem_request_get_ring(obj->last_write_req) : ring, &request);
11432 if (ret) 11435 if (ret)
11433 goto cleanup_pending; 11436 goto cleanup_pending;
11434 11437
@@ -13150,7 +13153,10 @@ static int intel_atomic_prepare_commit(struct drm_device *dev,
13150 struct drm_atomic_state *state, 13153 struct drm_atomic_state *state,
13151 bool async) 13154 bool async)
13152{ 13155{
13156 struct drm_i915_private *dev_priv = dev->dev_private;
13157 struct drm_plane_state *plane_state;
13153 struct drm_crtc_state *crtc_state; 13158 struct drm_crtc_state *crtc_state;
13159 struct drm_plane *plane;
13154 struct drm_crtc *crtc; 13160 struct drm_crtc *crtc;
13155 int i, ret; 13161 int i, ret;
13156 13162
@@ -13163,6 +13169,9 @@ static int intel_atomic_prepare_commit(struct drm_device *dev,
13163 ret = intel_crtc_wait_for_pending_flips(crtc); 13169 ret = intel_crtc_wait_for_pending_flips(crtc);
13164 if (ret) 13170 if (ret)
13165 return ret; 13171 return ret;
13172
13173 if (atomic_read(&to_intel_crtc(crtc)->unpin_work_count) >= 2)
13174 flush_workqueue(dev_priv->wq);
13166 } 13175 }
13167 13176
13168 ret = mutex_lock_interruptible(&dev->struct_mutex); 13177 ret = mutex_lock_interruptible(&dev->struct_mutex);
@@ -13170,6 +13179,37 @@ static int intel_atomic_prepare_commit(struct drm_device *dev,
13170 return ret; 13179 return ret;
13171 13180
13172 ret = drm_atomic_helper_prepare_planes(dev, state); 13181 ret = drm_atomic_helper_prepare_planes(dev, state);
13182 if (!ret && !async && !i915_reset_in_progress(&dev_priv->gpu_error)) {
13183 u32 reset_counter;
13184
13185 reset_counter = atomic_read(&dev_priv->gpu_error.reset_counter);
13186 mutex_unlock(&dev->struct_mutex);
13187
13188 for_each_plane_in_state(state, plane, plane_state, i) {
13189 struct intel_plane_state *intel_plane_state =
13190 to_intel_plane_state(plane_state);
13191
13192 if (!intel_plane_state->wait_req)
13193 continue;
13194
13195 ret = __i915_wait_request(intel_plane_state->wait_req,
13196 reset_counter, true,
13197 NULL, NULL);
13198
13199 /* Swallow -EIO errors to allow updates during hw lockup. */
13200 if (ret == -EIO)
13201 ret = 0;
13202
13203 if (ret)
13204 break;
13205 }
13206
13207 if (!ret)
13208 return 0;
13209
13210 mutex_lock(&dev->struct_mutex);
13211 drm_atomic_helper_cleanup_planes(dev, state);
13212 }
13173 13213
13174 mutex_unlock(&dev->struct_mutex); 13214 mutex_unlock(&dev->struct_mutex);
13175 return ret; 13215 return ret;
@@ -13196,15 +13236,17 @@ static int intel_atomic_commit(struct drm_device *dev,
13196 bool async) 13236 bool async)
13197{ 13237{
13198 struct drm_i915_private *dev_priv = dev->dev_private; 13238 struct drm_i915_private *dev_priv = dev->dev_private;
13199 struct drm_crtc *crtc;
13200 struct drm_crtc_state *crtc_state; 13239 struct drm_crtc_state *crtc_state;
13240 struct drm_crtc *crtc;
13201 int ret = 0; 13241 int ret = 0;
13202 int i; 13242 int i;
13203 bool any_ms = false; 13243 bool any_ms = false;
13204 13244
13205 ret = intel_atomic_prepare_commit(dev, state, async); 13245 ret = intel_atomic_prepare_commit(dev, state, async);
13206 if (ret) 13246 if (ret) {
13247 DRM_DEBUG_ATOMIC("Preparing state failed with %i\n", ret);
13207 return ret; 13248 return ret;
13249 }
13208 13250
13209 drm_atomic_helper_swap_state(dev, state); 13251 drm_atomic_helper_swap_state(dev, state);
13210 dev_priv->wm.config = to_intel_atomic_state(state)->wm_config; 13252 dev_priv->wm.config = to_intel_atomic_state(state)->wm_config;
@@ -13495,11 +13537,20 @@ intel_prepare_plane_fb(struct drm_plane *plane,
13495 if (ret) 13537 if (ret)
13496 DRM_DEBUG_KMS("failed to attach phys object\n"); 13538 DRM_DEBUG_KMS("failed to attach phys object\n");
13497 } else { 13539 } else {
13498 ret = intel_pin_and_fence_fb_obj(plane, fb, new_state, NULL, NULL); 13540 ret = intel_pin_and_fence_fb_obj(plane, fb, new_state);
13499 } 13541 }
13500 13542
13501 if (ret == 0) 13543 if (ret == 0) {
13544 if (obj) {
13545 struct intel_plane_state *plane_state =
13546 to_intel_plane_state(new_state);
13547
13548 i915_gem_request_assign(&plane_state->wait_req,
13549 obj->last_write_req);
13550 }
13551
13502 i915_gem_track_fb(old_obj, obj, intel_plane->frontbuffer_bit); 13552 i915_gem_track_fb(old_obj, obj, intel_plane->frontbuffer_bit);
13553 }
13503 13554
13504 return ret; 13555 return ret;
13505} 13556}
@@ -13519,9 +13570,12 @@ intel_cleanup_plane_fb(struct drm_plane *plane,
13519{ 13570{
13520 struct drm_device *dev = plane->dev; 13571 struct drm_device *dev = plane->dev;
13521 struct intel_plane *intel_plane = to_intel_plane(plane); 13572 struct intel_plane *intel_plane = to_intel_plane(plane);
13573 struct intel_plane_state *old_intel_state;
13522 struct drm_i915_gem_object *old_obj = intel_fb_obj(old_state->fb); 13574 struct drm_i915_gem_object *old_obj = intel_fb_obj(old_state->fb);
13523 struct drm_i915_gem_object *obj = intel_fb_obj(plane->state->fb); 13575 struct drm_i915_gem_object *obj = intel_fb_obj(plane->state->fb);
13524 13576
13577 old_intel_state = to_intel_plane_state(old_state);
13578
13525 if (!obj && !old_obj) 13579 if (!obj && !old_obj)
13526 return; 13580 return;
13527 13581
@@ -13533,6 +13587,9 @@ intel_cleanup_plane_fb(struct drm_plane *plane,
13533 if ((old_obj && (old_obj->frontbuffer_bits & intel_plane->frontbuffer_bit)) || 13587 if ((old_obj && (old_obj->frontbuffer_bits & intel_plane->frontbuffer_bit)) ||
13534 (obj && !(obj->frontbuffer_bits & intel_plane->frontbuffer_bit))) 13588 (obj && !(obj->frontbuffer_bits & intel_plane->frontbuffer_bit)))
13535 i915_gem_track_fb(old_obj, obj, intel_plane->frontbuffer_bit); 13589 i915_gem_track_fb(old_obj, obj, intel_plane->frontbuffer_bit);
13590
13591 i915_gem_request_assign(&old_intel_state->wait_req, NULL);
13592
13536} 13593}
13537 13594
13538int 13595int
@@ -15498,8 +15555,7 @@ void intel_modeset_gem_init(struct drm_device *dev)
15498 mutex_lock(&dev->struct_mutex); 15555 mutex_lock(&dev->struct_mutex);
15499 ret = intel_pin_and_fence_fb_obj(c->primary, 15556 ret = intel_pin_and_fence_fb_obj(c->primary,
15500 c->primary->fb, 15557 c->primary->fb,
15501 c->primary->state, 15558 c->primary->state);
15502 NULL, NULL);
15503 mutex_unlock(&dev->struct_mutex); 15559 mutex_unlock(&dev->struct_mutex);
15504 if (ret) { 15560 if (ret) {
15505 DRM_ERROR("failed to pin boot fb on pipe %d\n", 15561 DRM_ERROR("failed to pin boot fb on pipe %d\n",