drm/i915: Use CK505 as non-SSC source where available
authorKeith Packard <keithp@keithp.com>
Mon, 26 Sep 2011 21:29:12 +0000 (14:29 -0700)
committerKeith Packard <keithp@keithp.com>
Wed, 28 Sep 2011 21:08:06 +0000 (14:08 -0700)
When trying to use SSC on Ibex Peak without CK505, any non-SSC outputs
(like VGA or TV) get broken. So, do not use SSC on Ibex Peak unless
there is a CK505 available (as specified by the VBT).

On Cougar Point, all clocking is internal, so SSC can always be used,
and there will never be a CK505 available.

This eliminates VGA shimmer on some Ironlake machines which have a
CK505 clock source.

References: https://bugzilla.kernel.org/show_bug.cgi?id=21742
References: https://bugs.freedesktop.org/show_bug.cgi?id=38750
Signed-off-by: Keith Packard <keithp@keithp.com>
Reviewed-by: Chris Wilson <chris@chris-wilson.co.uk>
drivers/gpu/drm/i915/intel_display.c

index f9999357716861e2e8625ea6d91de545a31ae3a7..4c9684c54f18aa03adfe5894823fa9c3fc25f971 100644 (file)
@@ -5119,6 +5119,8 @@ static void ironlake_update_pch_refclk(struct drm_device *dev)
        bool has_cpu_edp = false;
        bool has_pch_edp = false;
        bool has_panel = false;
+       bool has_ck505 = false;
+       bool can_ssc = false;
 
        /* We need to take the global config into account */
        list_for_each_entry(encoder, &mode_config->encoder_list,
@@ -5137,8 +5139,18 @@ static void ironlake_update_pch_refclk(struct drm_device *dev)
                        break;
                }
        }
-       DRM_DEBUG_KMS("has_panel %d has_lvds %d has_pch_edp %d has_cpu_edp %d\n",
-                     has_panel, has_lvds, has_pch_edp, has_cpu_edp);
+
+       if (HAS_PCH_IBX(dev)) {
+               has_ck505 = dev_priv->display_clock_mode;
+               can_ssc = has_ck505;
+       } else {
+               has_ck505 = false;
+               can_ssc = true;
+       }
+
+       DRM_DEBUG_KMS("has_panel %d has_lvds %d has_pch_edp %d has_cpu_edp %d has_ck505 %d\n",
+                     has_panel, has_lvds, has_pch_edp, has_cpu_edp,
+                     has_ck505);
 
        /* Ironlake: try to setup display ref clock before DPLL
         * enabling. This is only under driver's control after
@@ -5148,14 +5160,18 @@ static void ironlake_update_pch_refclk(struct drm_device *dev)
        temp = I915_READ(PCH_DREF_CONTROL);
        /* Always enable nonspread source */
        temp &= ~DREF_NONSPREAD_SOURCE_MASK;
-       temp |= DREF_NONSPREAD_SOURCE_ENABLE;
+
+       if (has_ck505)
+               temp |= DREF_NONSPREAD_CK505_ENABLE;
+       else
+               temp |= DREF_NONSPREAD_SOURCE_ENABLE;
 
        if (has_panel) {
                temp &= ~DREF_SSC_SOURCE_MASK;
                temp |= DREF_SSC_SOURCE_ENABLE;
 
                /* SSC must be turned on before enabling the CPU output  */
-               if (intel_panel_use_ssc(dev_priv)) {
+               if (intel_panel_use_ssc(dev_priv) && can_ssc) {
                        DRM_DEBUG_KMS("Using SSC on panel\n");
                        temp |= DREF_SSC1_ENABLE;
                }
@@ -5169,7 +5185,7 @@ static void ironlake_update_pch_refclk(struct drm_device *dev)
 
                /* Enable CPU source on CPU attached eDP */
                if (has_cpu_edp) {
-                       if (intel_panel_use_ssc(dev_priv)) {
+                       if (intel_panel_use_ssc(dev_priv) && can_ssc) {
                                DRM_DEBUG_KMS("Using SSC on eDP\n");
                                temp |= DREF_CPU_SOURCE_OUTPUT_DOWNSPREAD;
                        }