aboutsummaryrefslogtreecommitdiff
path: root/drivers/gpu/drm/i915
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/i915')
-rw-r--r--drivers/gpu/drm/i915/i915_drv.h2
-rw-r--r--drivers/gpu/drm/i915/intel_bios.c8
-rw-r--r--drivers/gpu/drm/i915/intel_display.c20
3 files changed, 24 insertions, 6 deletions
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 7325363164f..135a08f615c 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -184,6 +184,8 @@ typedef struct drm_i915_private {
unsigned int lvds_dither:1;
unsigned int lvds_vbt:1;
unsigned int int_crt_support:1;
+ unsigned int lvds_use_ssc:1;
+ int lvds_ssc_freq;
struct drm_i915_fence_reg fence_regs[16]; /* assume 965 */
int fence_reg_start; /* 4 if userland hasn't ioctl'd us yet */
diff --git a/drivers/gpu/drm/i915/intel_bios.c b/drivers/gpu/drm/i915/intel_bios.c
index 4ca82a02552..65be30dccc7 100644
--- a/drivers/gpu/drm/i915/intel_bios.c
+++ b/drivers/gpu/drm/i915/intel_bios.c
@@ -135,6 +135,14 @@ parse_general_features(struct drm_i915_private *dev_priv,
if (general) {
dev_priv->int_tv_support = general->int_tv_support;
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_I855(dev_priv->dev))
+ dev_priv->lvds_ssc_freq = general->ssc_freq ? 66 : 48;
+ 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 8b203870626..13f9b6667c9 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -217,7 +217,7 @@ bool intel_pipe_has_type (struct drm_crtc *crtc, int type)
return false;
}
-#define INTELPllInvalid(s) { /* ErrorF (s) */; return false; }
+#define INTELPllInvalid(s) do { DRM_DEBUG(s); return false; } while (0)
/**
* Returns whether the given set of divisors are valid for a given refclk with
* the given connectors.
@@ -726,7 +726,7 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc,
int dspsize_reg = (pipe == 0) ? DSPASIZE : DSPBSIZE;
int dsppos_reg = (pipe == 0) ? DSPAPOS : DSPBPOS;
int pipesrc_reg = (pipe == 0) ? PIPEASRC : PIPEBSRC;
- int refclk;
+ int refclk, num_outputs = 0;
intel_clock_t clock;
u32 dpll = 0, fp = 0, dspcntr, pipeconf;
bool ok, is_sdvo = false, is_dvo = false;
@@ -763,9 +763,14 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc,
is_crt = true;
break;
}
+
+ num_outputs++;
}
- if (IS_I9XX(dev)) {
+ if (is_lvds && dev_priv->lvds_use_ssc && num_outputs < 2) {
+ refclk = dev_priv->lvds_ssc_freq * 1000;
+ DRM_DEBUG("using SSC reference clock of %d MHz\n", refclk / 1000);
+ } else if (IS_I9XX(dev)) {
refclk = 96000;
} else {
refclk = 48000;
@@ -824,11 +829,14 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc,
}
}
- if (is_tv) {
+ if (is_sdvo && is_tv)
+ dpll |= PLL_REF_INPUT_TVCLKINBC;
+ else if (is_tv)
/* XXX: just matching BIOS for now */
-/* dpll |= PLL_REF_INPUT_TVCLKINBC; */
+ /* dpll |= PLL_REF_INPUT_TVCLKINBC; */
dpll |= 3;
- }
+ else if (is_lvds && dev_priv->lvds_use_ssc && num_outputs < 2)
+ dpll |= PLLB_REF_INPUT_SPREADSPECTRUMIN;
else
dpll |= PLL_REF_INPUT_DREFCLK;