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,
