| From ea289dfd1af1783c2055dd204575087f67118724 Mon Sep 17 00:00:00 2001 |
| From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= <ville.syrjala@linux.intel.com> |
| Date: Thu, 19 Sep 2013 17:00:37 -0300 |
| Subject: drm/i915: Disable/enable planes as the first/last thing during |
| modeset on HSW |
| MIME-Version: 1.0 |
| Content-Type: text/plain; charset=UTF-8 |
| Content-Transfer-Encoding: 8bit |
| |
| Refactor the plane enabling/disabling into helper functions and move |
| the calls to happen as the first thing during .crtc_disable, and the |
| last thing during .crtc_enable. |
| |
| Those are the two clear points where we are sure that the pipe is |
| actually running regardless of the encoder type or hardware |
| generation. |
| |
| v2: Made by Paulo: |
| Remove the code touching everything but the Haswell functions. We |
| need this change on Haswell right now since it fixes a FIFO underrun |
| that we get on pipe A while we enable pipe B (see the workaround |
| notes on the Haswell mode set sequence documentation). We can bring |
| back the code to gens 2-7 later, once they're tested. |
| |
| Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com> |
| Signed-off-by: Paulo Zanoni <paulo.r.zanoni@intel.com> |
| Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch> |
| (cherry picked from commit dda9a66a818d32cbf5c4ecd817456fb6a3b39ec1) |
| Signed-off-by: Darren Hart <dvhart@linux.intel.com> |
| --- |
| drivers/gpu/drm/i915/intel_display.c | 69 +++++++++++++++++++++++------------- |
| 1 file changed, 45 insertions(+), 24 deletions(-) |
| |
| diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c |
| index bfa6a96e4e11..a954c0137b53 100644 |
| --- a/drivers/gpu/drm/i915/intel_display.c |
| +++ b/drivers/gpu/drm/i915/intel_display.c |
| @@ -3453,6 +3453,47 @@ static bool hsw_crtc_supports_ips(struct intel_crtc *crtc) |
| return HAS_IPS(crtc->base.dev) && crtc->pipe == PIPE_A; |
| } |
| |
| +static void haswell_crtc_enable_planes(struct drm_crtc *crtc) |
| +{ |
| + struct drm_device *dev = crtc->dev; |
| + struct drm_i915_private *dev_priv = dev->dev_private; |
| + struct intel_crtc *intel_crtc = to_intel_crtc(crtc); |
| + int pipe = intel_crtc->pipe; |
| + int plane = intel_crtc->plane; |
| + |
| + intel_enable_plane(dev_priv, plane, pipe); |
| + intel_enable_planes(crtc); |
| + intel_crtc_update_cursor(crtc, true); |
| + |
| + hsw_enable_ips(intel_crtc); |
| + |
| + mutex_lock(&dev->struct_mutex); |
| + intel_update_fbc(dev); |
| + mutex_unlock(&dev->struct_mutex); |
| +} |
| + |
| +static void haswell_crtc_disable_planes(struct drm_crtc *crtc) |
| +{ |
| + struct drm_device *dev = crtc->dev; |
| + struct drm_i915_private *dev_priv = dev->dev_private; |
| + struct intel_crtc *intel_crtc = to_intel_crtc(crtc); |
| + int pipe = intel_crtc->pipe; |
| + int plane = intel_crtc->plane; |
| + |
| + intel_crtc_wait_for_pending_flips(crtc); |
| + drm_vblank_off(dev, pipe); |
| + |
| + /* FBC must be disabled before disabling the plane on HSW. */ |
| + if (dev_priv->fbc.plane == plane) |
| + intel_disable_fbc(dev); |
| + |
| + hsw_disable_ips(intel_crtc); |
| + |
| + intel_crtc_update_cursor(crtc, false); |
| + intel_disable_planes(crtc); |
| + intel_disable_plane(dev_priv, plane, pipe); |
| +} |
| + |
| static void haswell_crtc_enable(struct drm_crtc *crtc) |
| { |
| struct drm_device *dev = crtc->dev; |
| @@ -3460,7 +3501,6 @@ static void haswell_crtc_enable(struct drm_crtc *crtc) |
| struct intel_crtc *intel_crtc = to_intel_crtc(crtc); |
| struct intel_encoder *encoder; |
| int pipe = intel_crtc->pipe; |
| - int plane = intel_crtc->plane; |
| |
| WARN_ON(!crtc->enabled); |
| |
| @@ -3496,24 +3536,17 @@ static void haswell_crtc_enable(struct drm_crtc *crtc) |
| intel_update_watermarks(crtc); |
| intel_enable_pipe(dev_priv, pipe, |
| intel_crtc->config.has_pch_encoder, false); |
| - intel_enable_plane(dev_priv, plane, pipe); |
| - intel_enable_planes(crtc); |
| - intel_crtc_update_cursor(crtc, true); |
| - |
| - hsw_enable_ips(intel_crtc); |
| |
| if (intel_crtc->config.has_pch_encoder) |
| lpt_pch_enable(crtc); |
| |
| - mutex_lock(&dev->struct_mutex); |
| - intel_update_fbc(dev); |
| - mutex_unlock(&dev->struct_mutex); |
| - |
| for_each_encoder_on_crtc(dev, crtc, encoder) { |
| encoder->enable(encoder); |
| intel_opregion_notify_encoder(encoder, true); |
| } |
| |
| + haswell_crtc_enable_planes(crtc); |
| + |
| /* |
| * There seems to be a race in PCH platform hw (at least on some |
| * outputs) where an enabled pipe still completes any pageflip right |
| @@ -3620,30 +3653,18 @@ static void haswell_crtc_disable(struct drm_crtc *crtc) |
| struct intel_crtc *intel_crtc = to_intel_crtc(crtc); |
| struct intel_encoder *encoder; |
| int pipe = intel_crtc->pipe; |
| - int plane = intel_crtc->plane; |
| enum transcoder cpu_transcoder = intel_crtc->config.cpu_transcoder; |
| |
| if (!intel_crtc->active) |
| return; |
| |
| + haswell_crtc_disable_planes(crtc); |
| + |
| for_each_encoder_on_crtc(dev, crtc, encoder) { |
| intel_opregion_notify_encoder(encoder, false); |
| encoder->disable(encoder); |
| } |
| |
| - intel_crtc_wait_for_pending_flips(crtc); |
| - drm_vblank_off(dev, pipe); |
| - |
| - /* FBC must be disabled before disabling the plane on HSW. */ |
| - if (dev_priv->fbc.plane == plane) |
| - intel_disable_fbc(dev); |
| - |
| - hsw_disable_ips(intel_crtc); |
| - |
| - intel_crtc_update_cursor(crtc, false); |
| - intel_disable_planes(crtc); |
| - intel_disable_plane(dev_priv, plane, pipe); |
| - |
| if (intel_crtc->config.has_pch_encoder) |
| intel_set_pch_fifo_underrun_reporting(dev, TRANSCODER_A, false); |
| intel_disable_pipe(dev_priv, pipe); |
| -- |
| 1.8.5.rc3 |
| |