diff options
Diffstat (limited to 'drivers/gpu/drm/i915/intel_display.c')
-rw-r--r-- | drivers/gpu/drm/i915/intel_display.c | 58 |
1 files changed, 30 insertions, 28 deletions
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 14b024becb91..9fa24347963a 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -2114,8 +2114,8 @@ static int i9xx_update_plane(struct drm_crtc *crtc, struct drm_framebuffer *fb, fb->pitches[0]); I915_WRITE(DSPSTRIDE(plane), fb->pitches[0]); if (INTEL_INFO(dev)->gen >= 4) { - I915_MODIFY_DISPBASE(DSPSURF(plane), - i915_gem_obj_ggtt_offset(obj) + intel_crtc->dspaddr_offset); + I915_WRITE(DSPSURF(plane), + i915_gem_obj_ggtt_offset(obj) + intel_crtc->dspaddr_offset); I915_WRITE(DSPTILEOFF(plane), (y << 16) | x); I915_WRITE(DSPLINOFF(plane), linear_offset); } else @@ -2205,8 +2205,8 @@ static int ironlake_update_plane(struct drm_crtc *crtc, i915_gem_obj_ggtt_offset(obj), linear_offset, x, y, fb->pitches[0]); I915_WRITE(DSPSTRIDE(plane), fb->pitches[0]); - I915_MODIFY_DISPBASE(DSPSURF(plane), - i915_gem_obj_ggtt_offset(obj) + intel_crtc->dspaddr_offset); + I915_WRITE(DSPSURF(plane), + i915_gem_obj_ggtt_offset(obj) + intel_crtc->dspaddr_offset); if (IS_HASWELL(dev) || IS_BROADWELL(dev)) { I915_WRITE(DSPOFFSET(plane), (y << 16) | x); } else { @@ -2982,6 +2982,30 @@ static bool intel_crtc_has_pending_flip(struct drm_crtc *crtc) return pending; } +bool intel_has_pending_fb_unpin(struct drm_device *dev) +{ + struct intel_crtc *crtc; + + /* Note that we don't need to be called with mode_config.lock here + * as our list of CRTC objects is static for the lifetime of the + * device and so cannot disappear as we iterate. Similarly, we can + * happily treat the predicates as racy, atomic checks as userspace + * cannot claim and pin a new fb without at least acquring the + * struct_mutex and so serialising with us. + */ + list_for_each_entry(crtc, &dev->mode_config.crtc_list, base.head) { + if (atomic_read(&crtc->unpin_work_count) == 0) + continue; + + if (crtc->unpin_work) + intel_wait_for_vblank(dev, crtc->pipe); + + return true; + } + + return false; +} + static void intel_crtc_wait_for_pending_flips(struct drm_crtc *crtc) { struct drm_device *dev = crtc->dev; @@ -8720,28 +8744,6 @@ static struct drm_crtc_helper_funcs intel_helper_funcs = { .load_lut = intel_crtc_load_lut, }; -static bool intel_encoder_crtc_ok(struct drm_encoder *encoder, - struct drm_crtc *crtc) -{ - struct drm_device *dev; - struct drm_crtc *tmp; - int crtc_mask = 1; - - WARN(!crtc, "checking null crtc?\n"); - - dev = crtc->dev; - - list_for_each_entry(tmp, &dev->mode_config.crtc_list, head) { - if (tmp == crtc) - break; - crtc_mask <<= 1; - } - - if (encoder->possible_crtcs & crtc_mask) - return true; - return false; -} - /** * intel_modeset_update_staged_output_state * @@ -9916,8 +9918,8 @@ intel_modeset_stage_output_state(struct drm_device *dev, } /* Make sure the new CRTC will work with the encoder */ - if (!intel_encoder_crtc_ok(&connector->new_encoder->base, - new_crtc)) { + if (!drm_encoder_crtc_ok(&connector->new_encoder->base, + new_crtc)) { return -EINVAL; } connector->encoder->new_crtc = to_intel_crtc(new_crtc); |