drm/i915: Fix edp vdd locking
[deliverable/linux.git] / drivers / gpu / drm / i915 / intel_display.c
index c7e05ed36e1ddceb3e4dcde04491df63acc261e9..2f47978fe808fc2d60781be7d545f6077d6c84df 100644 (file)
@@ -1261,8 +1261,9 @@ void assert_pipe(struct drm_i915_private *dev_priv,
        enum transcoder cpu_transcoder = intel_pipe_to_cpu_transcoder(dev_priv,
                                                                      pipe);
 
-       /* if we need the pipe A quirk it must be always on */
-       if (pipe == PIPE_A && dev_priv->quirks & QUIRK_PIPEA_FORCE)
+       /* if we need the pipe quirk it must be always on */
+       if ((pipe == PIPE_A && dev_priv->quirks & QUIRK_PIPEA_FORCE) ||
+           (pipe == PIPE_B && dev_priv->quirks & QUIRK_PIPEB_FORCE))
                state = true;
 
        if (!intel_display_power_enabled(dev_priv,
@@ -1662,8 +1663,9 @@ static void i9xx_enable_pll(struct intel_crtc *crtc)
  */
 static void i9xx_disable_pll(struct drm_i915_private *dev_priv, enum pipe pipe)
 {
-       /* Don't disable pipe A or pipe A PLLs if needed */
-       if (pipe == PIPE_A && (dev_priv->quirks & QUIRK_PIPEA_FORCE))
+       /* Don't disable pipe or pipe PLLs if needed */
+       if ((pipe == PIPE_A && dev_priv->quirks & QUIRK_PIPEA_FORCE) ||
+           (pipe == PIPE_B && dev_priv->quirks & QUIRK_PIPEB_FORCE))
                return;
 
        /* Make sure the pipe isn't still relying on us */
@@ -1856,7 +1858,7 @@ static void ironlake_enable_pch_transcoder(struct drm_i915_private *dev_priv,
        uint32_t reg, val, pipeconf_val;
 
        /* PCH only available on ILK+ */
-       BUG_ON(INTEL_INFO(dev)->gen < 5);
+       BUG_ON(!HAS_PCH_SPLIT(dev));
 
        /* Make sure PCH DPLL is enabled */
        assert_shared_dpll_enabled(dev_priv,
@@ -1909,7 +1911,7 @@ static void lpt_enable_pch_transcoder(struct drm_i915_private *dev_priv,
        u32 val, pipeconf_val;
 
        /* PCH only available on ILK+ */
-       BUG_ON(INTEL_INFO(dev_priv->dev)->gen < 5);
+       BUG_ON(!HAS_PCH_SPLIT(dev_priv->dev));
 
        /* FDI must be feeding us bits for PCH ports */
        assert_fdi_tx_enabled(dev_priv, (enum pipe) cpu_transcoder);
@@ -2031,8 +2033,8 @@ static void intel_enable_pipe(struct intel_crtc *crtc)
        reg = PIPECONF(cpu_transcoder);
        val = I915_READ(reg);
        if (val & PIPECONF_ENABLE) {
-               WARN_ON(!(pipe == PIPE_A &&
-                         dev_priv->quirks & QUIRK_PIPEA_FORCE));
+               WARN_ON(!((pipe == PIPE_A && dev_priv->quirks & QUIRK_PIPEA_FORCE) ||
+                         (pipe == PIPE_B && dev_priv->quirks & QUIRK_PIPEB_FORCE)));
                return;
        }
 
@@ -2066,17 +2068,26 @@ static void intel_disable_pipe(struct intel_crtc *crtc)
        assert_cursor_disabled(dev_priv, pipe);
        assert_sprites_disabled(dev_priv, pipe);
 
-       /* Don't disable pipe A or pipe A PLLs if needed */
-       if (pipe == PIPE_A && (dev_priv->quirks & QUIRK_PIPEA_FORCE))
-               return;
-
        reg = PIPECONF(cpu_transcoder);
        val = I915_READ(reg);
        if ((val & PIPECONF_ENABLE) == 0)
                return;
 
-       I915_WRITE(reg, val & ~PIPECONF_ENABLE);
-       intel_wait_for_pipe_off(crtc);
+       /*
+        * Double wide has implications for planes
+        * so best keep it disabled when not needed.
+        */
+       if (crtc->config.double_wide)
+               val &= ~PIPECONF_DOUBLE_WIDE;
+
+       /* Don't disable pipe or pipe PLLs if needed */
+       if (!(pipe == PIPE_A && dev_priv->quirks & QUIRK_PIPEA_FORCE) &&
+           !(pipe == PIPE_B && dev_priv->quirks & QUIRK_PIPEB_FORCE))
+               val &= ~PIPECONF_ENABLE;
+
+       I915_WRITE(reg, val);
+       if ((val & PIPECONF_ENABLE) == 0)
+               intel_wait_for_pipe_off(crtc);
 }
 
 /*
@@ -6031,9 +6042,9 @@ static void i9xx_set_pipeconf(struct intel_crtc *intel_crtc)
 
        pipeconf = 0;
 
-       if (dev_priv->quirks & QUIRK_PIPEA_FORCE &&
-           I915_READ(PIPECONF(intel_crtc->pipe)) & PIPECONF_ENABLE)
-               pipeconf |= PIPECONF_ENABLE;
+       if ((intel_crtc->pipe == PIPE_A && dev_priv->quirks & QUIRK_PIPEA_FORCE) ||
+           (intel_crtc->pipe == PIPE_B && dev_priv->quirks & QUIRK_PIPEB_FORCE))
+               pipeconf |= I915_READ(PIPECONF(intel_crtc->pipe)) & PIPECONF_ENABLE;
 
        if (intel_crtc->config.double_wide)
                pipeconf |= PIPECONF_DOUBLE_WIDE;
@@ -9087,7 +9098,12 @@ void intel_frontbuffer_flush(struct drm_device *dev,
 
        intel_edp_psr_flush(dev, frontbuffer_bits);
 
-       if (IS_GEN8(dev))
+       /*
+        * FIXME: Unconditional fbc flushing here is a rather gross hack and
+        * needs to be reworked into a proper frontbuffer tracking scheme like
+        * psr employs.
+        */
+       if (IS_BROADWELL(dev))
                gen8_fbc_sw_flush(dev, FBC_REND_CACHE_CLEAN);
 }
 
@@ -10746,8 +10762,9 @@ check_crtc_state(struct drm_device *dev)
                active = dev_priv->display.get_pipe_config(crtc,
                                                           &pipe_config);
 
-               /* hw state is inconsistent with the pipe A quirk */
-               if (crtc->pipe == PIPE_A && dev_priv->quirks & QUIRK_PIPEA_FORCE)
+               /* hw state is inconsistent with the pipe quirk */
+               if ((crtc->pipe == PIPE_A && dev_priv->quirks & QUIRK_PIPEA_FORCE) ||
+                   (crtc->pipe == PIPE_B && dev_priv->quirks & QUIRK_PIPEB_FORCE))
                        active = crtc->active;
 
                for_each_intel_encoder(dev, encoder) {
@@ -12504,7 +12521,7 @@ static void intel_init_display(struct drm_device *dev)
                dev_priv->display.write_eld = ironlake_write_eld;
                dev_priv->display.modeset_global_resources =
                        ivb_modeset_global_resources;
-       } else if (IS_HASWELL(dev) || IS_GEN8(dev)) {
+       } else if (IS_HASWELL(dev) || IS_BROADWELL(dev)) {
                dev_priv->display.fdi_link_train = hsw_fdi_link_train;
                dev_priv->display.write_eld = haswell_write_eld;
                dev_priv->display.modeset_global_resources =
@@ -12542,6 +12559,8 @@ static void intel_init_display(struct drm_device *dev)
        }
 
        intel_panel_init_backlight_funcs(dev);
+
+       mutex_init(&dev_priv->pps_mutex);
 }
 
 /*
@@ -12557,6 +12576,14 @@ static void quirk_pipea_force(struct drm_device *dev)
        DRM_INFO("applying pipe a force quirk\n");
 }
 
+static void quirk_pipeb_force(struct drm_device *dev)
+{
+       struct drm_i915_private *dev_priv = dev->dev_private;
+
+       dev_priv->quirks |= QUIRK_PIPEB_FORCE;
+       DRM_INFO("applying pipe b force quirk\n");
+}
+
 /*
  * Some machines (Lenovo U160) do not work with SSC on LVDS for some reason
  */
@@ -12631,6 +12658,12 @@ static struct intel_quirk intel_quirks[] = {
        /* ThinkPad T60 needs pipe A force quirk (bug #16494) */
        { 0x2782, 0x17aa, 0x201a, quirk_pipea_force },
 
+       /* 830 needs to leave pipe A & dpll A up */
+       { 0x3577, PCI_ANY_ID, PCI_ANY_ID, quirk_pipea_force },
+
+       /* 830 needs to leave pipe B & dpll B up */
+       { 0x3577, PCI_ANY_ID, PCI_ANY_ID, quirk_pipeb_force },
+
        /* Lenovo U160 cannot use SSC on LVDS */
        { 0x0046, 0x17aa, 0x3920, quirk_ssc_force_disable },
 
@@ -12701,7 +12734,11 @@ static void i915_disable_vga(struct drm_device *dev)
        vga_put(dev->pdev, VGA_RSRC_LEGACY_IO);
        udelay(300);
 
-       I915_WRITE(vga_reg, VGA_DISP_DISABLE);
+       /*
+        * Fujitsu-Siemens Lifebook S6010 (830) has problems resuming
+        * from S3 without preserving (some of?) the other bits.
+        */
+       I915_WRITE(vga_reg, dev_priv->bios_vgacntr | VGA_DISP_DISABLE);
        POSTING_READ(vga_reg);
 }
 
@@ -12790,6 +12827,8 @@ void intel_modeset_init(struct drm_device *dev)
 
        intel_shared_dpll_init(dev);
 
+       /* save the BIOS value before clobbering it */
+       dev_priv->bios_vgacntr = I915_READ(i915_vgacntrl_reg(dev));
        /* Just disable it once at startup */
        i915_disable_vga(dev);
        intel_setup_outputs(dev);
@@ -12966,7 +13005,7 @@ static void intel_sanitize_crtc(struct intel_crtc *crtc)
                }
        }
 
-       if (crtc->active || IS_VALLEYVIEW(dev) || INTEL_INFO(dev)->gen < 5) {
+       if (crtc->active || HAS_GMCH_DISPLAY(dev)) {
                /*
                 * We start out with underrun reporting disabled to avoid races.
                 * For correct bookkeeping mark this on active crtcs.
This page took 0.029871 seconds and 5 git commands to generate.