Commit dda9a66a authored by Ville Syrjälä's avatar Ville Syrjälä Committed by Daniel Vetter

drm/i915: Disable/enable planes as the first/last thing during modeset on HSW

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: default avatarVille Syrjälä <ville.syrjala@linux.intel.com>
Signed-off-by: default avatarPaulo Zanoni <paulo.r.zanoni@intel.com>
Signed-off-by: default avatarDaniel Vetter <daniel.vetter@ffwll.ch>
parent f6071166
...@@ -3453,6 +3453,47 @@ static bool hsw_crtc_supports_ips(struct intel_crtc *crtc) ...@@ -3453,6 +3453,47 @@ static bool hsw_crtc_supports_ips(struct intel_crtc *crtc)
return HAS_IPS(crtc->base.dev) && crtc->pipe == PIPE_A; 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) static void haswell_crtc_enable(struct drm_crtc *crtc)
{ {
struct drm_device *dev = crtc->dev; struct drm_device *dev = crtc->dev;
...@@ -3460,7 +3501,6 @@ static void haswell_crtc_enable(struct drm_crtc *crtc) ...@@ -3460,7 +3501,6 @@ static void haswell_crtc_enable(struct drm_crtc *crtc)
struct intel_crtc *intel_crtc = to_intel_crtc(crtc); struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
struct intel_encoder *encoder; struct intel_encoder *encoder;
int pipe = intel_crtc->pipe; int pipe = intel_crtc->pipe;
int plane = intel_crtc->plane;
WARN_ON(!crtc->enabled); WARN_ON(!crtc->enabled);
...@@ -3496,24 +3536,17 @@ static void haswell_crtc_enable(struct drm_crtc *crtc) ...@@ -3496,24 +3536,17 @@ static void haswell_crtc_enable(struct drm_crtc *crtc)
intel_update_watermarks(crtc); intel_update_watermarks(crtc);
intel_enable_pipe(dev_priv, pipe, intel_enable_pipe(dev_priv, pipe,
intel_crtc->config.has_pch_encoder, false); 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) if (intel_crtc->config.has_pch_encoder)
lpt_pch_enable(crtc); 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) { for_each_encoder_on_crtc(dev, crtc, encoder) {
encoder->enable(encoder); encoder->enable(encoder);
intel_opregion_notify_encoder(encoder, true); 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 * There seems to be a race in PCH platform hw (at least on some
* outputs) where an enabled pipe still completes any pageflip right * outputs) where an enabled pipe still completes any pageflip right
...@@ -3620,30 +3653,18 @@ static void haswell_crtc_disable(struct drm_crtc *crtc) ...@@ -3620,30 +3653,18 @@ static void haswell_crtc_disable(struct drm_crtc *crtc)
struct intel_crtc *intel_crtc = to_intel_crtc(crtc); struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
struct intel_encoder *encoder; struct intel_encoder *encoder;
int pipe = intel_crtc->pipe; int pipe = intel_crtc->pipe;
int plane = intel_crtc->plane;
enum transcoder cpu_transcoder = intel_crtc->config.cpu_transcoder; enum transcoder cpu_transcoder = intel_crtc->config.cpu_transcoder;
if (!intel_crtc->active) if (!intel_crtc->active)
return; return;
haswell_crtc_disable_planes(crtc);
for_each_encoder_on_crtc(dev, crtc, encoder) { for_each_encoder_on_crtc(dev, crtc, encoder) {
intel_opregion_notify_encoder(encoder, false); intel_opregion_notify_encoder(encoder, false);
encoder->disable(encoder); 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) if (intel_crtc->config.has_pch_encoder)
intel_set_pch_fifo_underrun_reporting(dev, TRANSCODER_A, false); intel_set_pch_fifo_underrun_reporting(dev, TRANSCODER_A, false);
intel_disable_pipe(dev_priv, pipe); intel_disable_pipe(dev_priv, pipe);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment