|
@@ -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)
|
|
|
|
|
|
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)
|
|
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)
|
|
|
|
|
|
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)
|
|
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)
|
|
/* 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)
|
|
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)
|
|
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)
|
|
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)
|
|
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)
|
|
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_enable_planes(crtc);
|
|
|
|
- intel_crtc_update_cursor(crtc, true);
|
|
|
|
-
|
|
|
|
- intel_update_fbc(dev);
|
|
|
|
|
|
+ intel_crtc_enable_planes(crtc);
|
|
|
|
|
|
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)
|
|
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)
|
|
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_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);
|
|
|
|
|
|
+ intel_crtc_enable_planes(crtc);
|
|
|
|
|
|
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)
|
|
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)
|
|
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_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_crtc_disable_planes(crtc);
|
|
|
|
|
|
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);
|