diff options
author | Ville Syrjälä <ville.syrjala@linux.intel.com> | 2013-09-09 07:06:37 -0400 |
---|---|---|
committer | Daniel Vetter <daniel.vetter@ffwll.ch> | 2013-09-16 16:43:46 -0400 |
commit | da4a1efab8be1e373c1ad31b14deb4e422dad6cb (patch) | |
tree | 9e555853d591903600d69ece9da9334c5a822e2d /drivers/gpu/drm/i915/intel_display.c | |
parent | 293623f7aa6d175d126135fb58c7a88c9695fd11 (diff) |
drm/i915: Make i9xx_crtc_clock_get() work for PCH DPLLs
Add the 120MHz refernce clock case for PCH DPLLs.
Also determine the reference clock frequency more accurately by
checking for the PLLB_REF_INPUT_SPREADSPECTRUMIN refclk input
mode. The gen2 code already checked it, but it stil assumed a
fixed 66MHz refclk. Instead we need to consult the VBT for the
real value.
v2: Fix refclk for SSC panel case
Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Reviewed-by: Jani Nikula <jani.nikula@intel.com>
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Diffstat (limited to 'drivers/gpu/drm/i915/intel_display.c')
-rw-r--r-- | drivers/gpu/drm/i915/intel_display.c | 32 |
1 files changed, 21 insertions, 11 deletions
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 38f2b306a109..e1c6a5547f68 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c | |||
@@ -7341,6 +7341,22 @@ void intel_release_load_detect_pipe(struct drm_connector *connector, | |||
7341 | mutex_unlock(&crtc->mutex); | 7341 | mutex_unlock(&crtc->mutex); |
7342 | } | 7342 | } |
7343 | 7343 | ||
7344 | static int i9xx_pll_refclk(struct drm_device *dev, | ||
7345 | const struct intel_crtc_config *pipe_config) | ||
7346 | { | ||
7347 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
7348 | u32 dpll = pipe_config->dpll_hw_state.dpll; | ||
7349 | |||
7350 | if ((dpll & PLL_REF_INPUT_MASK) == PLLB_REF_INPUT_SPREADSPECTRUMIN) | ||
7351 | return dev_priv->vbt.lvds_ssc_freq * 1000; | ||
7352 | else if (HAS_PCH_SPLIT(dev)) | ||
7353 | return 120000; | ||
7354 | else if (!IS_GEN2(dev)) | ||
7355 | return 96000; | ||
7356 | else | ||
7357 | return 48000; | ||
7358 | } | ||
7359 | |||
7344 | /* Returns the clock of the currently programmed mode of the given pipe. */ | 7360 | /* Returns the clock of the currently programmed mode of the given pipe. */ |
7345 | static void i9xx_crtc_clock_get(struct intel_crtc *crtc, | 7361 | static void i9xx_crtc_clock_get(struct intel_crtc *crtc, |
7346 | struct intel_crtc_config *pipe_config) | 7362 | struct intel_crtc_config *pipe_config) |
@@ -7351,6 +7367,7 @@ static void i9xx_crtc_clock_get(struct intel_crtc *crtc, | |||
7351 | u32 dpll = pipe_config->dpll_hw_state.dpll; | 7367 | u32 dpll = pipe_config->dpll_hw_state.dpll; |
7352 | u32 fp; | 7368 | u32 fp; |
7353 | intel_clock_t clock; | 7369 | intel_clock_t clock; |
7370 | int refclk = i9xx_pll_refclk(dev, pipe_config); | ||
7354 | 7371 | ||
7355 | if ((dpll & DISPLAY_RATE_SELECT_FPA1) == 0) | 7372 | if ((dpll & DISPLAY_RATE_SELECT_FPA1) == 0) |
7356 | fp = pipe_config->dpll_hw_state.fp0; | 7373 | fp = pipe_config->dpll_hw_state.fp0; |
@@ -7390,9 +7407,9 @@ static void i9xx_crtc_clock_get(struct intel_crtc *crtc, | |||
7390 | } | 7407 | } |
7391 | 7408 | ||
7392 | if (IS_PINEVIEW(dev)) | 7409 | if (IS_PINEVIEW(dev)) |
7393 | pineview_clock(96000, &clock); | 7410 | pineview_clock(refclk, &clock); |
7394 | else | 7411 | else |
7395 | i9xx_clock(96000, &clock); | 7412 | i9xx_clock(refclk, &clock); |
7396 | } else { | 7413 | } else { |
7397 | bool is_lvds = (pipe == 1) && (I915_READ(LVDS) & LVDS_PORT_EN); | 7414 | bool is_lvds = (pipe == 1) && (I915_READ(LVDS) & LVDS_PORT_EN); |
7398 | 7415 | ||
@@ -7400,13 +7417,6 @@ static void i9xx_crtc_clock_get(struct intel_crtc *crtc, | |||
7400 | clock.p1 = ffs((dpll & DPLL_FPA01_P1_POST_DIV_MASK_I830_LVDS) >> | 7417 | clock.p1 = ffs((dpll & DPLL_FPA01_P1_POST_DIV_MASK_I830_LVDS) >> |
7401 | DPLL_FPA01_P1_POST_DIV_SHIFT); | 7418 | DPLL_FPA01_P1_POST_DIV_SHIFT); |
7402 | clock.p2 = 14; | 7419 | clock.p2 = 14; |
7403 | |||
7404 | if ((dpll & PLL_REF_INPUT_MASK) == | ||
7405 | PLLB_REF_INPUT_SPREADSPECTRUMIN) { | ||
7406 | /* XXX: might not be 66MHz */ | ||
7407 | i9xx_clock(66000, &clock); | ||
7408 | } else | ||
7409 | i9xx_clock(48000, &clock); | ||
7410 | } else { | 7420 | } else { |
7411 | if (dpll & PLL_P1_DIVIDE_BY_TWO) | 7421 | if (dpll & PLL_P1_DIVIDE_BY_TWO) |
7412 | clock.p1 = 2; | 7422 | clock.p1 = 2; |
@@ -7418,9 +7428,9 @@ static void i9xx_crtc_clock_get(struct intel_crtc *crtc, | |||
7418 | clock.p2 = 4; | 7428 | clock.p2 = 4; |
7419 | else | 7429 | else |
7420 | clock.p2 = 2; | 7430 | clock.p2 = 2; |
7421 | |||
7422 | i9xx_clock(48000, &clock); | ||
7423 | } | 7431 | } |
7432 | |||
7433 | i9xx_clock(refclk, &clock); | ||
7424 | } | 7434 | } |
7425 | 7435 | ||
7426 | pipe_config->adjusted_mode.clock = clock.dot; | 7436 | pipe_config->adjusted_mode.clock = clock.dot; |