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

drm/i915: Convert gmch platforms over to ilk_crtc_{enable, disable}_planes()

Use the same code for enabling/disabling planes on all platforms. Rename
the functions to reflect that they're no longer specific to any
platform.

For now we leave the plane enable/disable to ccur at the same old
position in the modeset sequence.
Signed-off-by: default avatarVille Syrjälä <ville.syrjala@linux.intel.com>
Reviewed-by: default avatarChris Wilson <chris@chris-wilson.co.uk>
[danvet: Frob drm_vblank_on conflict.]
Signed-off-by: default avatarDaniel Vetter <daniel.vetter@ffwll.ch>
parent 1cf0ba14
...@@ -3634,7 +3634,49 @@ static void intel_crtc_load_lut(struct drm_crtc *crtc) ...@@ -3634,7 +3634,49 @@ static void intel_crtc_load_lut(struct drm_crtc *crtc)
hsw_enable_ips(intel_crtc); hsw_enable_ips(intel_crtc);
} }
static void ilk_crtc_enable_planes(struct drm_crtc *crtc) static void intel_crtc_dpms_overlay(struct intel_crtc *intel_crtc, bool enable)
{
if (!enable && intel_crtc->overlay) {
struct drm_device *dev = intel_crtc->base.dev;
struct drm_i915_private *dev_priv = dev->dev_private;
mutex_lock(&dev->struct_mutex);
dev_priv->mm.interruptible = false;
(void) intel_overlay_switch_off(intel_crtc->overlay);
dev_priv->mm.interruptible = true;
mutex_unlock(&dev->struct_mutex);
}
/* Let userspace switch the overlay on again. In most cases userspace
* has to recompute where to put it anyway.
*/
}
/**
* i9xx_fixup_plane - ugly workaround for G45 to fire up the hardware
* cursor plane briefly if not already running after enabling the display
* plane.
* This workaround avoids occasional blank screens when self refresh is
* enabled.
*/
static void
g4x_fixup_plane(struct drm_i915_private *dev_priv, enum pipe pipe)
{
u32 cntl = I915_READ(CURCNTR(pipe));
if ((cntl & CURSOR_MODE) == 0) {
u32 fw_bcl_self = I915_READ(FW_BLC_SELF);
I915_WRITE(FW_BLC_SELF, fw_bcl_self & ~FW_BLC_SELF_EN);
I915_WRITE(CURCNTR(pipe), CURSOR_MODE_64_ARGB_AX);
intel_wait_for_vblank(dev_priv->dev, pipe);
I915_WRITE(CURCNTR(pipe), cntl);
I915_WRITE(CURBASE(pipe), I915_READ(CURBASE(pipe)));
I915_WRITE(FW_BLC_SELF, fw_bcl_self);
}
}
static void intel_crtc_enable_planes(struct drm_crtc *crtc)
{ {
struct drm_device *dev = crtc->dev; struct drm_device *dev = crtc->dev;
struct drm_i915_private *dev_priv = dev->dev_private; struct drm_i915_private *dev_priv = dev->dev_private;
...@@ -3644,7 +3686,11 @@ static void ilk_crtc_enable_planes(struct drm_crtc *crtc) ...@@ -3644,7 +3686,11 @@ static void ilk_crtc_enable_planes(struct drm_crtc *crtc)
intel_enable_primary_hw_plane(dev_priv, plane, pipe); intel_enable_primary_hw_plane(dev_priv, plane, pipe);
intel_enable_planes(crtc); intel_enable_planes(crtc);
/* The fixup needs to happen before cursor is enabled */
if (IS_G4X(dev))
g4x_fixup_plane(dev_priv, pipe);
intel_crtc_update_cursor(crtc, true); intel_crtc_update_cursor(crtc, true);
intel_crtc_dpms_overlay(intel_crtc, true);
hsw_enable_ips(intel_crtc); hsw_enable_ips(intel_crtc);
...@@ -3653,7 +3699,7 @@ static void ilk_crtc_enable_planes(struct drm_crtc *crtc) ...@@ -3653,7 +3699,7 @@ static void ilk_crtc_enable_planes(struct drm_crtc *crtc)
mutex_unlock(&dev->struct_mutex); mutex_unlock(&dev->struct_mutex);
} }
static void ilk_crtc_disable_planes(struct drm_crtc *crtc) static void intel_crtc_disable_planes(struct drm_crtc *crtc)
{ {
struct drm_device *dev = crtc->dev; struct drm_device *dev = crtc->dev;
struct drm_i915_private *dev_priv = dev->dev_private; struct drm_i915_private *dev_priv = dev->dev_private;
...@@ -3669,6 +3715,7 @@ static void ilk_crtc_disable_planes(struct drm_crtc *crtc) ...@@ -3669,6 +3715,7 @@ static void ilk_crtc_disable_planes(struct drm_crtc *crtc)
hsw_disable_ips(intel_crtc); hsw_disable_ips(intel_crtc);
intel_crtc_dpms_overlay(intel_crtc, false);
intel_crtc_update_cursor(crtc, false); intel_crtc_update_cursor(crtc, false);
intel_disable_planes(crtc); intel_disable_planes(crtc);
intel_disable_primary_hw_plane(dev_priv, plane, pipe); intel_disable_primary_hw_plane(dev_priv, plane, pipe);
...@@ -3726,7 +3773,7 @@ static void ironlake_crtc_enable(struct drm_crtc *crtc) ...@@ -3726,7 +3773,7 @@ static void ironlake_crtc_enable(struct drm_crtc *crtc)
if (HAS_PCH_CPT(dev)) if (HAS_PCH_CPT(dev))
cpt_verify_modeset(dev, intel_crtc->pipe); cpt_verify_modeset(dev, intel_crtc->pipe);
ilk_crtc_enable_planes(crtc); intel_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
...@@ -3827,7 +3874,7 @@ static void haswell_crtc_enable(struct drm_crtc *crtc) ...@@ -3827,7 +3874,7 @@ static void haswell_crtc_enable(struct drm_crtc *crtc)
/* If we change the relative order between pipe/planes enabling, we need /* If we change the relative order between pipe/planes enabling, we need
* to change the workaround. */ * to change the workaround. */
haswell_mode_set_planes_workaround(intel_crtc); haswell_mode_set_planes_workaround(intel_crtc);
ilk_crtc_enable_planes(crtc); intel_crtc_enable_planes(crtc);
} }
static void ironlake_pfit_disable(struct intel_crtc *crtc) static void ironlake_pfit_disable(struct intel_crtc *crtc)
...@@ -3857,7 +3904,7 @@ static void ironlake_crtc_disable(struct drm_crtc *crtc) ...@@ -3857,7 +3904,7 @@ static void ironlake_crtc_disable(struct drm_crtc *crtc)
if (!intel_crtc->active) if (!intel_crtc->active)
return; return;
ilk_crtc_disable_planes(crtc); intel_crtc_disable_planes(crtc);
for_each_encoder_on_crtc(dev, crtc, encoder) for_each_encoder_on_crtc(dev, crtc, encoder)
encoder->disable(encoder); encoder->disable(encoder);
...@@ -3920,7 +3967,7 @@ static void haswell_crtc_disable(struct drm_crtc *crtc) ...@@ -3920,7 +3967,7 @@ static void haswell_crtc_disable(struct drm_crtc *crtc)
if (!intel_crtc->active) if (!intel_crtc->active)
return; return;
ilk_crtc_disable_planes(crtc); intel_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);
...@@ -3966,48 +4013,6 @@ static void haswell_crtc_off(struct drm_crtc *crtc) ...@@ -3966,48 +4013,6 @@ static void haswell_crtc_off(struct drm_crtc *crtc)
intel_ddi_put_crtc_pll(crtc); intel_ddi_put_crtc_pll(crtc);
} }
static void intel_crtc_dpms_overlay(struct intel_crtc *intel_crtc, bool enable)
{
if (!enable && intel_crtc->overlay) {
struct drm_device *dev = intel_crtc->base.dev;
struct drm_i915_private *dev_priv = dev->dev_private;
mutex_lock(&dev->struct_mutex);
dev_priv->mm.interruptible = false;
(void) intel_overlay_switch_off(intel_crtc->overlay);
dev_priv->mm.interruptible = true;
mutex_unlock(&dev->struct_mutex);
}
/* Let userspace switch the overlay on again. In most cases userspace
* has to recompute where to put it anyway.
*/
}
/**
* i9xx_fixup_plane - ugly workaround for G45 to fire up the hardware
* cursor plane briefly if not already running after enabling the display
* plane.
* This workaround avoids occasional blank screens when self refresh is
* enabled.
*/
static void
g4x_fixup_plane(struct drm_i915_private *dev_priv, enum pipe pipe)
{
u32 cntl = I915_READ(CURCNTR(pipe));
if ((cntl & CURSOR_MODE) == 0) {
u32 fw_bcl_self = I915_READ(FW_BLC_SELF);
I915_WRITE(FW_BLC_SELF, fw_bcl_self & ~FW_BLC_SELF_EN);
I915_WRITE(CURCNTR(pipe), CURSOR_MODE_64_ARGB_AX);
intel_wait_for_vblank(dev_priv->dev, pipe);
I915_WRITE(CURCNTR(pipe), cntl);
I915_WRITE(CURBASE(pipe), I915_READ(CURBASE(pipe)));
I915_WRITE(FW_BLC_SELF, fw_bcl_self);
}
}
static void i9xx_pfit_enable(struct intel_crtc *crtc) static void i9xx_pfit_enable(struct intel_crtc *crtc)
{ {
struct drm_device *dev = crtc->base.dev; struct drm_device *dev = crtc->base.dev;
...@@ -4311,7 +4316,6 @@ static void valleyview_crtc_enable(struct drm_crtc *crtc) ...@@ -4311,7 +4316,6 @@ static void valleyview_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;
bool is_dsi; bool is_dsi;
WARN_ON(!crtc->enabled); WARN_ON(!crtc->enabled);
...@@ -4343,11 +4347,7 @@ static void valleyview_crtc_enable(struct drm_crtc *crtc) ...@@ -4343,11 +4347,7 @@ static void valleyview_crtc_enable(struct drm_crtc *crtc)
intel_wait_for_vblank(dev_priv->dev, pipe); intel_wait_for_vblank(dev_priv->dev, pipe);
intel_set_cpu_fifo_underrun_reporting(dev, pipe, true); intel_set_cpu_fifo_underrun_reporting(dev, pipe, true);
intel_enable_primary_hw_plane(dev_priv, plane, pipe); intel_crtc_enable_planes(crtc);
intel_enable_planes(crtc);
intel_crtc_update_cursor(crtc, true);
intel_update_fbc(dev);
for_each_encoder_on_crtc(dev, crtc, encoder) for_each_encoder_on_crtc(dev, crtc, encoder)
encoder->enable(encoder); encoder->enable(encoder);
...@@ -4360,7 +4360,6 @@ static void i9xx_crtc_enable(struct drm_crtc *crtc) ...@@ -4360,7 +4360,6 @@ static void i9xx_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);
...@@ -4384,17 +4383,7 @@ static void i9xx_crtc_enable(struct drm_crtc *crtc) ...@@ -4384,17 +4383,7 @@ static void i9xx_crtc_enable(struct drm_crtc *crtc)
intel_wait_for_vblank(dev_priv->dev, pipe); intel_wait_for_vblank(dev_priv->dev, pipe);
intel_set_cpu_fifo_underrun_reporting(dev, pipe, true); intel_set_cpu_fifo_underrun_reporting(dev, pipe, true);
intel_enable_primary_hw_plane(dev_priv, plane, pipe); intel_crtc_enable_planes(crtc);
intel_enable_planes(crtc);
/* The fixup needs to happen before cursor is enabled */
if (IS_G4X(dev))
g4x_fixup_plane(dev_priv, pipe);
intel_crtc_update_cursor(crtc, true);
/* Give the overlay scaler a chance to enable if it's on this pipe */
intel_crtc_dpms_overlay(intel_crtc, true);
intel_update_fbc(dev);
for_each_encoder_on_crtc(dev, crtc, encoder) for_each_encoder_on_crtc(dev, crtc, encoder)
encoder->enable(encoder); encoder->enable(encoder);
...@@ -4422,7 +4411,6 @@ static void i9xx_crtc_disable(struct drm_crtc *crtc) ...@@ -4422,7 +4411,6 @@ static void i9xx_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;
if (!intel_crtc->active) if (!intel_crtc->active)
return; return;
...@@ -4430,17 +4418,7 @@ static void i9xx_crtc_disable(struct drm_crtc *crtc) ...@@ -4430,17 +4418,7 @@ static void i9xx_crtc_disable(struct drm_crtc *crtc)
for_each_encoder_on_crtc(dev, crtc, encoder) for_each_encoder_on_crtc(dev, crtc, encoder)
encoder->disable(encoder); encoder->disable(encoder);
/* Give the overlay scaler a chance to disable if it's on this pipe */ intel_crtc_disable_planes(crtc);
intel_crtc_wait_for_pending_flips(crtc);
drm_vblank_off(dev, pipe);
if (dev_priv->fbc.plane == plane)
intel_disable_fbc(dev);
intel_crtc_dpms_overlay(intel_crtc, false);
intel_crtc_update_cursor(crtc, false);
intel_disable_planes(crtc);
intel_disable_primary_hw_plane(dev_priv, plane, pipe);
intel_set_cpu_fifo_underrun_reporting(dev, pipe, false); intel_set_cpu_fifo_underrun_reporting(dev, pipe, 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