drm/i915: split i9xx CRTC enable/disable code
authorJesse Barnes <jbarnes@virtuousgeek.org>
Fri, 10 Sep 2010 17:31:34 +0000 (10:31 -0700)
committerChris Wilson <chris@chris-wilson.co.uk>
Fri, 10 Sep 2010 21:23:45 +0000 (22:23 +0100)
So we can use it for CRTC prepare/commit.

Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
drivers/gpu/drm/i915/intel_display.c

index 56ca589a83f52ad67ee4081b64a4dde50020805d..fecb98c2d8ad5df3b7407e675fa9c164ffa33771 100644 (file)
@@ -2262,7 +2262,7 @@ static void intel_crtc_dpms_overlay(struct intel_crtc *intel_crtc, bool enable)
         */
 }
 
-static void i9xx_crtc_dpms(struct drm_crtc *crtc, int mode)
+static void i9xx_crtc_enable(struct drm_crtc *crtc)
 {
        struct drm_device *dev = crtc->dev;
        struct drm_i915_private *dev_priv = dev->dev_private;
@@ -2275,97 +2275,118 @@ static void i9xx_crtc_dpms(struct drm_crtc *crtc, int mode)
        int pipeconf_reg = (pipe == 0) ? PIPEACONF : PIPEBCONF;
        u32 temp;
 
-       /* XXX: When our outputs are all unaware of DPMS modes other than off
-        * and on, we should map those modes to DRM_MODE_DPMS_OFF in the CRTC.
-        */
-       switch (mode) {
-       case DRM_MODE_DPMS_ON:
-       case DRM_MODE_DPMS_STANDBY:
-       case DRM_MODE_DPMS_SUSPEND:
-               /* Enable the DPLL */
-               temp = I915_READ(dpll_reg);
-               if ((temp & DPLL_VCO_ENABLE) == 0) {
-                       I915_WRITE(dpll_reg, temp);
-                       I915_READ(dpll_reg);
-                       /* Wait for the clocks to stabilize. */
-                       udelay(150);
-                       I915_WRITE(dpll_reg, temp | DPLL_VCO_ENABLE);
-                       I915_READ(dpll_reg);
-                       /* Wait for the clocks to stabilize. */
-                       udelay(150);
-                       I915_WRITE(dpll_reg, temp | DPLL_VCO_ENABLE);
-                       I915_READ(dpll_reg);
-                       /* Wait for the clocks to stabilize. */
-                       udelay(150);
-               }
+       /* Enable the DPLL */
+       temp = I915_READ(dpll_reg);
+       if ((temp & DPLL_VCO_ENABLE) == 0) {
+               I915_WRITE(dpll_reg, temp);
+               I915_READ(dpll_reg);
+               /* Wait for the clocks to stabilize. */
+               udelay(150);
+               I915_WRITE(dpll_reg, temp | DPLL_VCO_ENABLE);
+               I915_READ(dpll_reg);
+               /* Wait for the clocks to stabilize. */
+               udelay(150);
+               I915_WRITE(dpll_reg, temp | DPLL_VCO_ENABLE);
+               I915_READ(dpll_reg);
+               /* Wait for the clocks to stabilize. */
+               udelay(150);
+       }
 
-               /* Enable the pipe */
-               temp = I915_READ(pipeconf_reg);
-               if ((temp & PIPEACONF_ENABLE) == 0)
-                       I915_WRITE(pipeconf_reg, temp | PIPEACONF_ENABLE);
-
-               /* Enable the plane */
-               temp = I915_READ(dspcntr_reg);
-               if ((temp & DISPLAY_PLANE_ENABLE) == 0) {
-                       I915_WRITE(dspcntr_reg, temp | DISPLAY_PLANE_ENABLE);
-                       /* Flush the plane changes */
-                       I915_WRITE(dspbase_reg, I915_READ(dspbase_reg));
-               }
+       /* Enable the pipe */
+       temp = I915_READ(pipeconf_reg);
+       if ((temp & PIPEACONF_ENABLE) == 0)
+               I915_WRITE(pipeconf_reg, temp | PIPEACONF_ENABLE);
 
-               intel_crtc_load_lut(crtc);
+       /* Enable the plane */
+       temp = I915_READ(dspcntr_reg);
+       if ((temp & DISPLAY_PLANE_ENABLE) == 0) {
+               I915_WRITE(dspcntr_reg, temp | DISPLAY_PLANE_ENABLE);
+               /* Flush the plane changes */
+               I915_WRITE(dspbase_reg, I915_READ(dspbase_reg));
+       }
 
-               if ((IS_I965G(dev) || plane == 0))
-                       intel_update_fbc(crtc, &crtc->mode);
+       intel_crtc_load_lut(crtc);
 
-               /* Give the overlay scaler a chance to enable if it's on this pipe */
-               intel_crtc_dpms_overlay(intel_crtc, true);
-       break;
-       case DRM_MODE_DPMS_OFF:
-               /* Give the overlay scaler a chance to disable if it's on this pipe */
-               intel_crtc_dpms_overlay(intel_crtc, false);
-               drm_vblank_off(dev, pipe);
-
-               if (dev_priv->cfb_plane == plane &&
-                   dev_priv->display.disable_fbc)
-                       dev_priv->display.disable_fbc(dev);
-
-               /* Disable display plane */
-               temp = I915_READ(dspcntr_reg);
-               if ((temp & DISPLAY_PLANE_ENABLE) != 0) {
-                       I915_WRITE(dspcntr_reg, temp & ~DISPLAY_PLANE_ENABLE);
-                       /* Flush the plane changes */
-                       I915_WRITE(dspbase_reg, I915_READ(dspbase_reg));
-                       I915_READ(dspbase_reg);
-               }
+       if ((IS_I965G(dev) || plane == 0))
+               intel_update_fbc(crtc, &crtc->mode);
 
-               if (!IS_I9XX(dev)) {
-                       /* Wait for vblank for the disable to take effect */
-                       intel_wait_for_vblank_off(dev, pipe);
-               }
+       /* Give the overlay scaler a chance to enable if it's on this pipe */
+       intel_crtc_dpms_overlay(intel_crtc, true);
+}
 
-               /* Don't disable pipe A or pipe A PLLs if needed */
-               if (pipeconf_reg == PIPEACONF &&
-                   (dev_priv->quirks & QUIRK_PIPEA_FORCE))
-                       goto skip_pipe_off;
+static void i9xx_crtc_disable(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;
+       int dpll_reg = (pipe == 0) ? DPLL_A : DPLL_B;
+       int dspcntr_reg = (plane == 0) ? DSPACNTR : DSPBCNTR;
+       int dspbase_reg = (plane == 0) ? DSPAADDR : DSPBADDR;
+       int pipeconf_reg = (pipe == 0) ? PIPEACONF : PIPEBCONF;
+       u32 temp;
 
-               /* Next, disable display pipes */
-               temp = I915_READ(pipeconf_reg);
-               if ((temp & PIPEACONF_ENABLE) != 0) {
-                       I915_WRITE(pipeconf_reg, temp & ~PIPEACONF_ENABLE);
-                       I915_READ(pipeconf_reg);
-               }
+       /* Give the overlay scaler a chance to disable if it's on this pipe */
+       intel_crtc_dpms_overlay(intel_crtc, false);
+       drm_vblank_off(dev, pipe);
+
+       if (dev_priv->cfb_plane == plane &&
+           dev_priv->display.disable_fbc)
+               dev_priv->display.disable_fbc(dev);
 
-               /* Wait for vblank for the disable to take effect. */
+       /* Disable display plane */
+       temp = I915_READ(dspcntr_reg);
+       if ((temp & DISPLAY_PLANE_ENABLE) != 0) {
+               I915_WRITE(dspcntr_reg, temp & ~DISPLAY_PLANE_ENABLE);
+               /* Flush the plane changes */
+               I915_WRITE(dspbase_reg, I915_READ(dspbase_reg));
+               I915_READ(dspbase_reg);
+       }
+
+       if (!IS_I9XX(dev)) {
+               /* Wait for vblank for the disable to take effect */
                intel_wait_for_vblank_off(dev, pipe);
+       }
 
-               temp = I915_READ(dpll_reg);
-               if ((temp & DPLL_VCO_ENABLE) != 0) {
-                       I915_WRITE(dpll_reg, temp & ~DPLL_VCO_ENABLE);
-                       I915_READ(dpll_reg);
-               }
-       skip_pipe_off:
-               /* Wait for the clocks to turn off. */
-               udelay(150);
+       /* Don't disable pipe A or pipe A PLLs if needed */
+       if (pipeconf_reg == PIPEACONF &&
+           (dev_priv->quirks & QUIRK_PIPEA_FORCE))
+               goto skip_pipe_off;
+
+       /* Next, disable display pipes */
+       temp = I915_READ(pipeconf_reg);
+       if ((temp & PIPEACONF_ENABLE) != 0) {
+               I915_WRITE(pipeconf_reg, temp & ~PIPEACONF_ENABLE);
+               I915_READ(pipeconf_reg);
+       }
+
+       /* Wait for vblank for the disable to take effect. */
+       intel_wait_for_vblank_off(dev, pipe);
+
+       temp = I915_READ(dpll_reg);
+       if ((temp & DPLL_VCO_ENABLE) != 0) {
+               I915_WRITE(dpll_reg, temp & ~DPLL_VCO_ENABLE);
+               I915_READ(dpll_reg);
+       }
+skip_pipe_off:
+       /* Wait for the clocks to turn off. */
+       udelay(150);
+}
+
+static void i9xx_crtc_dpms(struct drm_crtc *crtc, int mode)
+{
+       /* XXX: When our outputs are all unaware of DPMS modes other than off
+        * and on, we should map those modes to DRM_MODE_DPMS_OFF in the CRTC.
+        */
+       switch (mode) {
+       case DRM_MODE_DPMS_ON:
+       case DRM_MODE_DPMS_STANDBY:
+       case DRM_MODE_DPMS_SUSPEND:
+               i9xx_crtc_enable(crtc);
+               break;
+       case DRM_MODE_DPMS_OFF:
+               i9xx_crtc_disable(crtc);
                break;
        }
 }