drm/i915: clean up panel fitter handling in lvds
authorMika Kuoppala <mika.kuoppala@linux.intel.com>
Fri, 8 Feb 2013 14:35:38 +0000 (16:35 +0200)
committerDaniel Vetter <daniel.vetter@ffwll.ch>
Tue, 19 Feb 2013 23:21:40 +0000 (00:21 +0100)
With the previous patch "drm/i915: disable shared panel fitter for
pipe" we now disable the panel fitter at the right spot in the modeset
sequence in the crtc functions on all platforms. Hence the disabling
in intel_disable_lvds is no longer required and potentially harmful
(since the plane is still enabled at this point).

Similarly on the enabling side we enable the panel fitter in the lvds
callback only once the plane is enabled. Which is too late. Hence move
this into a new intel_pre_enable_lvds callback.

Finally we can ditch lvds_encoder->pfit_dirty - this was required to
work around the crtc helper semantics, but with the new i915 modeset
infrastructure we should enable/disable the pfit only when enabling or
disabling the entire output pipeline. So separate state tracking for
the pfit is no longer required.

Signed-off-by: Mika Kuoppala <mika.kuoppala@intel.com>
[danvet: Bikeshed the commit message a bit to stress that now we
enable/disable the pfit on i9xx platforms at the right point of time
compared to the old code.]
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
drivers/gpu/drm/i915/intel_display.c
drivers/gpu/drm/i915/intel_lvds.c

index fc9b98794b2591a983e6c2e313ed09d5503164d8..6fe4d07778e3fffeddcfebbf199229eb5e719ec8 100644 (file)
@@ -3615,6 +3615,11 @@ static void i9xx_crtc_enable(struct drm_crtc *crtc)
        intel_update_watermarks(dev);
 
        intel_enable_pll(dev_priv, pipe);
+
+       for_each_encoder_on_crtc(dev, crtc, encoder)
+               if (encoder->pre_enable)
+                       encoder->pre_enable(encoder);
+
        intel_enable_pipe(dev_priv, pipe, false);
        intel_enable_plane(dev_priv, plane, pipe);
 
index bff78a3ec37b55003e0b74ddc33c6115129781bd..c7154bfa54cf074da64248e19793e56879548146 100644 (file)
@@ -51,7 +51,6 @@ struct intel_lvds_encoder {
 
        u32 pfit_control;
        u32 pfit_pgm_ratios;
-       bool pfit_dirty;
        bool is_dual_link;
        u32 reg;
 
@@ -151,6 +150,29 @@ static void intel_pre_pll_enable_lvds(struct intel_encoder *encoder)
        I915_WRITE(lvds_encoder->reg, temp);
 }
 
+static void intel_pre_enable_lvds(struct intel_encoder *encoder)
+{
+       struct drm_device *dev = encoder->base.dev;
+       struct intel_lvds_encoder *enc = to_lvds_encoder(&encoder->base);
+       struct drm_i915_private *dev_priv = dev->dev_private;
+
+       if (HAS_PCH_SPLIT(dev) || !enc->pfit_control)
+               return;
+
+       /*
+        * Enable automatic panel scaling so that non-native modes
+        * fill the screen.  The panel fitter should only be
+        * adjusted whilst the pipe is disabled, according to
+        * register description and PRM.
+        */
+       DRM_DEBUG_KMS("applying panel-fitter: %x, %x\n",
+                     enc->pfit_control,
+                     enc->pfit_pgm_ratios);
+
+       I915_WRITE(PFIT_PGM_RATIOS, enc->pfit_pgm_ratios);
+       I915_WRITE(PFIT_CONTROL, enc->pfit_control);
+}
+
 /**
  * Sets the power state for the panel.
  */
@@ -172,22 +194,6 @@ static void intel_enable_lvds(struct intel_encoder *encoder)
 
        I915_WRITE(lvds_encoder->reg, I915_READ(lvds_encoder->reg) | LVDS_PORT_EN);
 
-       if (lvds_encoder->pfit_dirty) {
-               /*
-                * Enable automatic panel scaling so that non-native modes
-                * fill the screen.  The panel fitter should only be
-                * adjusted whilst the pipe is disabled, according to
-                * register description and PRM.
-                */
-               DRM_DEBUG_KMS("applying panel-fitter: %x, %x\n",
-                             lvds_encoder->pfit_control,
-                             lvds_encoder->pfit_pgm_ratios);
-
-               I915_WRITE(PFIT_PGM_RATIOS, lvds_encoder->pfit_pgm_ratios);
-               I915_WRITE(PFIT_CONTROL, lvds_encoder->pfit_control);
-               lvds_encoder->pfit_dirty = false;
-       }
-
        I915_WRITE(ctl_reg, I915_READ(ctl_reg) | POWER_TARGET_ON);
        POSTING_READ(lvds_encoder->reg);
        if (wait_for((I915_READ(stat_reg) & PP_ON) != 0, 1000))
@@ -217,11 +223,6 @@ static void intel_disable_lvds(struct intel_encoder *encoder)
        if (wait_for((I915_READ(stat_reg) & PP_ON) == 0, 1000))
                DRM_ERROR("timed out waiting for panel to power off\n");
 
-       if (lvds_encoder->pfit_control) {
-               I915_WRITE(PFIT_CONTROL, 0);
-               lvds_encoder->pfit_dirty = true;
-       }
-
        I915_WRITE(lvds_encoder->reg, I915_READ(lvds_encoder->reg) & ~LVDS_PORT_EN);
        POSTING_READ(lvds_encoder->reg);
 }
@@ -461,7 +462,6 @@ out:
            pfit_pgm_ratios != lvds_encoder->pfit_pgm_ratios) {
                lvds_encoder->pfit_control = pfit_control;
                lvds_encoder->pfit_pgm_ratios = pfit_pgm_ratios;
-               lvds_encoder->pfit_dirty = true;
        }
        dev_priv->lvds_border_bits = border;
 
@@ -1101,6 +1101,7 @@ bool intel_lvds_init(struct drm_device *dev)
                         DRM_MODE_ENCODER_LVDS);
 
        intel_encoder->enable = intel_enable_lvds;
+       intel_encoder->pre_enable = intel_pre_enable_lvds;
        intel_encoder->pre_pll_enable = intel_pre_pll_enable_lvds;
        intel_encoder->disable = intel_disable_lvds;
        intel_encoder->get_hw_state = intel_lvds_get_hw_state;