This resurrects Chris's old code to better manage the PCH reference
clock.  With some previous mode setting bugs fixed, it appears work work
now.

v2: fix compile error

Signed-off-by: Jesse Barnes <jbar...@virtuousgeek.org>
---
 drivers/gpu/drm/i915/i915_drv.h      |    1 +
 drivers/gpu/drm/i915/intel_bios.c    |    1 +
 drivers/gpu/drm/i915/intel_bios.h    |    4 ++-
 drivers/gpu/drm/i915/intel_display.c |   63 +++++++++++++++++++---------------
 4 files changed, 40 insertions(+), 29 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index feb4f16..303e4b3 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -356,6 +356,7 @@ typedef struct drm_i915_private {
        unsigned int lvds_vbt:1;
        unsigned int int_crt_support:1;
        unsigned int lvds_use_ssc:1;
+       unsigned int display_clock_mode:1;
        int lvds_ssc_freq;
        struct {
                int rate;
diff --git a/drivers/gpu/drm/i915/intel_bios.c 
b/drivers/gpu/drm/i915/intel_bios.c
index 61abef8..de3460e 100644
--- a/drivers/gpu/drm/i915/intel_bios.c
+++ b/drivers/gpu/drm/i915/intel_bios.c
@@ -309,6 +309,7 @@ parse_general_features(struct drm_i915_private *dev_priv,
                dev_priv->lvds_use_ssc = general->enable_ssc;
                dev_priv->lvds_ssc_freq =
                        intel_bios_ssc_frequency(dev, general->ssc_freq);
+               dev_priv->display_clock_mode = general->display_clock_mode;
        }
 }
 
diff --git a/drivers/gpu/drm/i915/intel_bios.h 
b/drivers/gpu/drm/i915/intel_bios.h
index 5f8e4ed..02b1b624 100644
--- a/drivers/gpu/drm/i915/intel_bios.h
+++ b/drivers/gpu/drm/i915/intel_bios.h
@@ -120,7 +120,9 @@ struct bdb_general_features {
        u8 ssc_freq:1;
        u8 enable_lfp_on_override:1;
        u8 disable_ssc_ddt:1;
-       u8 rsvd8:3; /* finish byte */
+       u8 rsvd7:1;
+       u8 display_clock_mode:1;
+       u8 rsvd8:1; /* finish byte */
 
         /* bits 3 */
        u8 disable_smooth_vision:1;
diff --git a/drivers/gpu/drm/i915/intel_display.c 
b/drivers/gpu/drm/i915/intel_display.c
index 644fd4cb..2465ad8 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -5057,6 +5057,7 @@ static void ironlake_update_pch_refclk(struct drm_device 
*dev)
        struct intel_encoder *encoder;
        struct intel_encoder *has_edp_encoder = NULL;
        u32 temp;
+       int num_connectors = 0;
        bool has_lvds = false;
 
        /* We need to take the global config into account */
@@ -5076,6 +5077,7 @@ static void ironlake_update_pch_refclk(struct drm_device 
*dev)
                                has_edp_encoder = encoder;
                                break;
                        }
+                       num_connectors++;
                }
        }
 
@@ -5085,43 +5087,48 @@ static void ironlake_update_pch_refclk(struct 
drm_device *dev)
         * ignoring this setting.
         */
        temp = I915_READ(PCH_DREF_CONTROL);
-       /* Always enable nonspread source */
+
+       /* First clear the current state for output switching */
+       temp &= ~DREF_SSC1_ENABLE;
+       temp &= ~DREF_SSC4_ENABLE;
+       temp &= ~DREF_SUPERSPREAD_SOURCE_MASK;
        temp &= ~DREF_NONSPREAD_SOURCE_MASK;
-       temp |= DREF_NONSPREAD_SOURCE_ENABLE;
        temp &= ~DREF_SSC_SOURCE_MASK;
-       temp |= DREF_SSC_SOURCE_ENABLE;
-       I915_WRITE(PCH_DREF_CONTROL, temp);
-
-       POSTING_READ(PCH_DREF_CONTROL);
-       udelay(200);
+       temp &= ~DREF_CPU_SOURCE_OUTPUT_MASK;
 
-       if (has_edp_encoder) {
-               if (intel_panel_use_ssc(dev_priv)) {
-                       temp |= DREF_SSC1_ENABLE;
-                       I915_WRITE(PCH_DREF_CONTROL, temp);
-
-                       POSTING_READ(PCH_DREF_CONTROL);
-                       udelay(200);
-               }
-               temp &= ~DREF_CPU_SOURCE_OUTPUT_MASK;
+       if (!num_connectors)
+               goto out;
 
-               /* Enable CPU source on CPU attached eDP */
-               if (!intel_encoder_is_pch_edp(&has_edp_encoder->base)) {
-                       if (intel_panel_use_ssc(dev_priv))
+       if ((has_lvds || has_edp_encoder) &&
+           intel_panel_use_ssc(dev_priv)) {
+               temp |= DREF_SSC_SOURCE_ENABLE;
+               if (has_edp_encoder) {
+                       if (!intel_encoder_is_pch_edp(&has_edp_encoder->base))
                                temp |= DREF_CPU_SOURCE_OUTPUT_DOWNSPREAD;
                        else
-                               temp |= DREF_CPU_SOURCE_OUTPUT_NONSPREAD;
-               } else {
-                       /* Enable SSC on PCH eDP if needed */
-                       if (intel_panel_use_ssc(dev_priv)) {
-                               DRM_ERROR("enabling SSC on PCH\n");
                                temp |= DREF_SUPERSPREAD_SOURCE_ENABLE;
-                       }
                }
-               I915_WRITE(PCH_DREF_CONTROL, temp);
-               POSTING_READ(PCH_DREF_CONTROL);
-               udelay(200);
+               if (!dev_priv->display_clock_mode)
+                       temp |= DREF_SSC1_ENABLE;
+               num_connectors--;
+       }
+
+       /* Unhandled outputs need non-SSC clock */
+       if (num_connectors) {
+               if (dev_priv->display_clock_mode)
+                       temp |= DREF_NONSPREAD_CK505_ENABLE;
+               else
+                       temp |= DREF_NONSPREAD_SOURCE_ENABLE;
+               if (has_edp_encoder &&
+                   !intel_encoder_is_pch_edp(&has_edp_encoder->base) &&
+                   !intel_panel_use_ssc(dev_priv))
+                       temp |= DREF_CPU_SOURCE_OUTPUT_NONSPREAD;
        }
+
+out:
+       I915_WRITE(PCH_DREF_CONTROL, temp);
+       POSTING_READ(PCH_DREF_CONTROL);
+       udelay(200);
 }
 
 static int ironlake_crtc_mode_set(struct drm_crtc *crtc,
-- 
1.7.4.1

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

Reply via email to