summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris Wilson <chris@chris-wilson.co.uk>2011-01-19 13:29:42 +0000
committerChris Wilson <chris@chris-wilson.co.uk>2011-01-19 13:33:27 +0000
commit633f2ea26665d37bb3c8ae30799aa14988622653 (patch)
treee06f4aef5cec14ce6afa144d454872c446a3520a
parent9a4114ffa7b6f5f4635e3745a8dc051d15d4596a (diff)
drm/i915: Disable SSC for outputs other than LVDS or DP
For CRT and SDVO/HDMI, we need to use a normal, non-SSC, clock and so we must clear any enabling bits left-over from earlier outputs. And also seems to correct the LVDS panel on the Lenovo U160. However, at one point, it did cause an "ERROR failed to disable trancoder". So prolonged testing on top of Jesse's refactored and error-checking CRTC logic is desired. Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
-rw-r--r--drivers/gpu/drm/i915/i915_drv.h1
-rw-r--r--drivers/gpu/drm/i915/intel_bios.c1
-rw-r--r--drivers/gpu/drm/i915/intel_bios.h4
-rw-r--r--drivers/gpu/drm/i915/intel_display.c56
4 files changed, 36 insertions, 26 deletions
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index eaec56ef12b6..52ceae571397 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -350,6 +350,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 4b95295ab04a..35c3b1442ba9 100644
--- a/drivers/gpu/drm/i915/intel_bios.c
+++ b/drivers/gpu/drm/i915/intel_bios.c
@@ -279,6 +279,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 5f8e4edcbbb9..02b1b62415df 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 2c7e90f12657..2f58d97972db 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -4506,44 +4506,50 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc,
* ignoring this setting.
*/
if (HAS_PCH_SPLIT(dev)) {
+ /*XXX BIOS treats 16:31 as a mask for 0:15 */
+
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;
+ temp &= ~DREF_CPU_SOURCE_OUTPUT_MASK;
I915_WRITE(PCH_DREF_CONTROL, temp);
POSTING_READ(PCH_DREF_CONTROL);
udelay(200);
- 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;
-
- /* 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 ((is_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)) {
+ /* Enable CPU source on CPU attached eDP */
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");
+ } else {
+ /* Enable SSC on PCH eDP if needed */
temp |= DREF_SUPERSPREAD_SOURCE_ENABLE;
}
+ I915_WRITE(PCH_DREF_CONTROL, temp);
}
- I915_WRITE(PCH_DREF_CONTROL, temp);
- POSTING_READ(PCH_DREF_CONTROL);
- udelay(200);
+ if (!dev_priv->display_clock_mode)
+ temp |= DREF_SSC1_ENABLE;
+ } else {
+ 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))
+ temp |= DREF_CPU_SOURCE_OUTPUT_NONSPREAD;
}
+
+ I915_WRITE(PCH_DREF_CONTROL, temp);
+ POSTING_READ(PCH_DREF_CONTROL);
+ udelay(200);
}
if (IS_PINEVIEW(dev)) {