diff options
author | Chris Wilson <chris@chris-wilson.co.uk> | 2011-01-12 17:04:08 +0000 |
---|---|---|
committer | Chris Wilson <chris@chris-wilson.co.uk> | 2011-01-13 16:05:58 +0000 |
commit | a76150302d6e7ebc43e1a1ddaee7fd51db8da3b3 (patch) | |
tree | 18237da2f01fa732d5dfc9c567d17209ca6b418c /drivers/gpu/drm | |
parent | c8303e7f3f3093c16ef0fa5f73280637c89d4368 (diff) |
drm/i915: Add a module option to override the use of SSC
In order to workaround the issue with LVDS not working on the Lenovo
U160 apparently due to using the wrong SSC frequency, add an option to
disable SSC.
Suggested-by: Lukács, Árpád <lukacs.arpad@gmail.com>
Bugzillla: https://bugs.freedesktop.org/show_bug.cgi?id=32748
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Cc: stable@kernel.org
Diffstat (limited to 'drivers/gpu/drm')
-rw-r--r-- | drivers/gpu/drm/i915/i915_drv.c | 3 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/i915_drv.h | 1 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/intel_bios.c | 17 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/intel_display.c | 17 |
4 files changed, 21 insertions, 17 deletions
diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c index 0de75a23f8e..72fea2bcfc4 100644 --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c @@ -49,6 +49,9 @@ module_param_named(powersave, i915_powersave, int, 0600); unsigned int i915_lvds_downclock = 0; module_param_named(lvds_downclock, i915_lvds_downclock, int, 0400); +unsigned int i915_panel_use_ssc = 1; +module_param_named(lvds_use_ssc, i915_panel_use_ssc, int, 0600); + bool i915_try_reset = true; module_param_named(reset, i915_try_reset, bool, 0600); diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 385fc7ec39d..5969f46ac2d 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -954,6 +954,7 @@ extern int i915_max_ioctl; extern unsigned int i915_fbpercrtc; extern unsigned int i915_powersave; extern unsigned int i915_lvds_downclock; +extern unsigned int i915_panel_use_ssc; extern int i915_suspend(struct drm_device *dev, pm_message_t state); extern int i915_resume(struct drm_device *dev); diff --git a/drivers/gpu/drm/i915/intel_bios.c b/drivers/gpu/drm/i915/intel_bios.c index b0b1200ed65..0b44956c336 100644 --- a/drivers/gpu/drm/i915/intel_bios.c +++ b/drivers/gpu/drm/i915/intel_bios.c @@ -264,17 +264,12 @@ parse_general_features(struct drm_i915_private *dev_priv, dev_priv->int_crt_support = general->int_crt_support; dev_priv->lvds_use_ssc = general->enable_ssc; - if (dev_priv->lvds_use_ssc) { - if (IS_I85X(dev)) - dev_priv->lvds_ssc_freq = - general->ssc_freq ? 66 : 48; - else if (IS_GEN5(dev) || IS_GEN6(dev)) - dev_priv->lvds_ssc_freq = - general->ssc_freq ? 100 : 120; - else - dev_priv->lvds_ssc_freq = - general->ssc_freq ? 100 : 96; - } + if (IS_I85X(dev)) + dev_priv->lvds_ssc_freq = general->ssc_freq ? 66 : 48; + else if (IS_GEN5(dev) || IS_GEN6(dev)) + dev_priv->lvds_ssc_freq = general->ssc_freq ? 100 : 120; + else + dev_priv->lvds_ssc_freq = general->ssc_freq ? 100 : 96; } } diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 25d96889d7d..98967f3b772 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -3822,6 +3822,11 @@ static void intel_update_watermarks(struct drm_device *dev) sr_hdisplay, sr_htotal, pixel_size); } +static inline bool intel_panel_use_ssc(struct drm_i915_private *dev_priv) +{ + return dev_priv->lvds_use_ssc && i915_panel_use_ssc; +} + static int intel_crtc_mode_set(struct drm_crtc *crtc, struct drm_display_mode *mode, struct drm_display_mode *adjusted_mode, @@ -3884,7 +3889,7 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc, num_connectors++; } - if (is_lvds && dev_priv->lvds_use_ssc && num_connectors < 2) { + if (is_lvds && intel_panel_use_ssc(dev_priv) && num_connectors < 2) { refclk = dev_priv->lvds_ssc_freq * 1000; DRM_DEBUG_KMS("using SSC reference clock of %d MHz\n", refclk / 1000); @@ -4059,7 +4064,7 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc, udelay(200); if (has_edp_encoder) { - if (dev_priv->lvds_use_ssc) { + if (intel_panel_use_ssc(dev_priv)) { temp |= DREF_SSC1_ENABLE; I915_WRITE(PCH_DREF_CONTROL, temp); @@ -4070,13 +4075,13 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc, /* Enable CPU source on CPU attached eDP */ if (!intel_encoder_is_pch_edp(&has_edp_encoder->base)) { - if (dev_priv->lvds_use_ssc) + if (intel_panel_use_ssc(dev_priv)) temp |= DREF_CPU_SOURCE_OUTPUT_DOWNSPREAD; else temp |= DREF_CPU_SOURCE_OUTPUT_NONSPREAD; } else { /* Enable SSC on PCH eDP if needed */ - if (dev_priv->lvds_use_ssc) { + if (intel_panel_use_ssc(dev_priv)) { DRM_ERROR("enabling SSC on PCH\n"); temp |= DREF_SUPERSPREAD_SOURCE_ENABLE; } @@ -4104,7 +4109,7 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc, int factor = 21; if (is_lvds) { - if ((dev_priv->lvds_use_ssc && + if ((intel_panel_use_ssc(dev_priv) && dev_priv->lvds_ssc_freq == 100) || (I915_READ(PCH_LVDS) & LVDS_CLKB_POWER_MASK) == LVDS_CLKB_POWER_UP) factor = 25; @@ -4183,7 +4188,7 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc, /* XXX: just matching BIOS for now */ /* dpll |= PLL_REF_INPUT_TVCLKINBC; */ dpll |= 3; - else if (is_lvds && dev_priv->lvds_use_ssc && num_connectors < 2) + else if (is_lvds && intel_panel_use_ssc(dev_priv) && num_connectors < 2) dpll |= PLLB_REF_INPUT_SPREADSPECTRUMIN; else dpll |= PLL_REF_INPUT_DREFCLK; |