Skip to content

Commit

Permalink
drm/i915: Add a module option to override the use of SSC
Browse files Browse the repository at this point in the history
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
  • Loading branch information
Chris Wilson committed Jan 13, 2011
1 parent c8303e7 commit a761503
Show file tree
Hide file tree
Showing 4 changed files with 21 additions and 17 deletions.
3 changes: 3 additions & 0 deletions drivers/gpu/drm/i915/i915_drv.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);

Expand Down
1 change: 1 addition & 0 deletions drivers/gpu/drm/i915/i915_drv.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
17 changes: 6 additions & 11 deletions drivers/gpu/drm/i915/intel_bios.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
}

Expand Down
17 changes: 11 additions & 6 deletions drivers/gpu/drm/i915/intel_display.c
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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);

Expand All @@ -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;
}
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand Down

0 comments on commit a761503

Please sign in to comment.