Commit 5dc5298b authored by Paulo Zanoni's avatar Paulo Zanoni Committed by Daniel Vetter

drm/i915: add proper CPU/PCH checks to crtc_mode_set functions

On ironlake_crtc_mode_set, WARN if not using IBX or CPT.

On haswell_crtc_mode_set, only run IBX/CPT code on IBX/CPT. I am still
not sure whether IBX/CPT will be possible with a Haswell CPU, so leave
the code there for now and put a WARN in case we spot it.
Signed-off-by: default avatarPaulo Zanoni <paulo.r.zanoni@intel.com>
Reviewed-by: default avatarDamien Lespiau <damien.lespiau@intel.com>
Signed-off-by: default avatarDaniel Vetter <daniel.vetter@ffwll.ch>
parent 09b4ddf9
...@@ -5002,6 +5002,9 @@ static int ironlake_crtc_mode_set(struct drm_crtc *crtc, ...@@ -5002,6 +5002,9 @@ static int ironlake_crtc_mode_set(struct drm_crtc *crtc,
num_connectors++; num_connectors++;
} }
WARN(!(HAS_PCH_IBX(dev) || HAS_PCH_CPT(dev)),
"Unexpected PCH type %d\n", INTEL_PCH_TYPE(dev));
ok = ironlake_compute_clocks(crtc, adjusted_mode, &clock, ok = ironlake_compute_clocks(crtc, adjusted_mode, &clock,
&has_reduced_clock, &reduced_clock); &has_reduced_clock, &reduced_clock);
if (!ok) { if (!ok) {
...@@ -5027,12 +5030,8 @@ static int ironlake_crtc_mode_set(struct drm_crtc *crtc, ...@@ -5027,12 +5030,8 @@ static int ironlake_crtc_mode_set(struct drm_crtc *crtc,
DRM_DEBUG_KMS("Mode for pipe %d:\n", pipe); DRM_DEBUG_KMS("Mode for pipe %d:\n", pipe);
drm_mode_debug_printmodeline(mode); drm_mode_debug_printmodeline(mode);
/* CPU eDP is the only output that doesn't need a PCH PLL of its own on /* CPU eDP is the only output that doesn't need a PCH PLL of its own. */
* pre-Haswell/LPT generation */ if (!is_cpu_edp) {
if (HAS_PCH_LPT(dev)) {
DRM_DEBUG_KMS("LPT detected: no PLL for pipe %d necessary\n",
pipe);
} else if (!is_cpu_edp) {
struct intel_pch_pll *pll; struct intel_pch_pll *pll;
pll = intel_get_pch_pll(intel_crtc, dpll, fp); pll = intel_get_pch_pll(intel_crtc, dpll, fp);
...@@ -5155,7 +5154,7 @@ static int haswell_crtc_mode_set(struct drm_crtc *crtc, ...@@ -5155,7 +5154,7 @@ static int haswell_crtc_mode_set(struct drm_crtc *crtc,
int plane = intel_crtc->plane; int plane = intel_crtc->plane;
int num_connectors = 0; int num_connectors = 0;
intel_clock_t clock, reduced_clock; intel_clock_t clock, reduced_clock;
u32 dpll, fp = 0, fp2 = 0; u32 dpll = 0, fp = 0, fp2 = 0;
bool ok, has_reduced_clock = false; bool ok, has_reduced_clock = false;
bool is_lvds = false, is_dp = false, is_cpu_edp = false; bool is_lvds = false, is_dp = false, is_cpu_edp = false;
struct intel_encoder *encoder; struct intel_encoder *encoder;
...@@ -5181,12 +5180,22 @@ static int haswell_crtc_mode_set(struct drm_crtc *crtc, ...@@ -5181,12 +5180,22 @@ static int haswell_crtc_mode_set(struct drm_crtc *crtc,
num_connectors++; num_connectors++;
} }
/* We are not sure yet this won't happen. */
WARN(!HAS_PCH_LPT(dev), "Unexpected PCH type %d\n",
INTEL_PCH_TYPE(dev));
WARN(num_connectors != 1, "%d connectors attached to pipe %c\n",
num_connectors, pipe_name(pipe));
if (HAS_PCH_IBX(dev) || HAS_PCH_CPT(dev)) {
ok = ironlake_compute_clocks(crtc, adjusted_mode, &clock, ok = ironlake_compute_clocks(crtc, adjusted_mode, &clock,
&has_reduced_clock, &reduced_clock); &has_reduced_clock,
&reduced_clock);
if (!ok) { if (!ok) {
DRM_ERROR("Couldn't find PLL settings for mode!\n"); DRM_ERROR("Couldn't find PLL settings for mode!\n");
return -EINVAL; return -EINVAL;
} }
}
/* Ensure that the cursor is valid for the new mode before changing... */ /* Ensure that the cursor is valid for the new mode before changing... */
intel_crtc_update_cursor(crtc, true); intel_crtc_update_cursor(crtc, true);
...@@ -5196,22 +5205,21 @@ static int haswell_crtc_mode_set(struct drm_crtc *crtc, ...@@ -5196,22 +5205,21 @@ static int haswell_crtc_mode_set(struct drm_crtc *crtc,
if (is_lvds && dev_priv->lvds_dither) if (is_lvds && dev_priv->lvds_dither)
dither = true; dither = true;
DRM_DEBUG_KMS("Mode for pipe %d:\n", pipe);
drm_mode_debug_printmodeline(mode);
if (HAS_PCH_IBX(dev) || HAS_PCH_CPT(dev)) {
fp = clock.n << 16 | clock.m1 << 8 | clock.m2; fp = clock.n << 16 | clock.m1 << 8 | clock.m2;
if (has_reduced_clock) if (has_reduced_clock)
fp2 = reduced_clock.n << 16 | reduced_clock.m1 << 8 | fp2 = reduced_clock.n << 16 | reduced_clock.m1 << 8 |
reduced_clock.m2; reduced_clock.m2;
dpll = ironlake_compute_dpll(intel_crtc, adjusted_mode, &clock, fp); dpll = ironlake_compute_dpll(intel_crtc, adjusted_mode, &clock,
fp);
DRM_DEBUG_KMS("Mode for pipe %d:\n", pipe);
drm_mode_debug_printmodeline(mode);
/* CPU eDP is the only output that doesn't need a PCH PLL of its own on /* CPU eDP is the only output that doesn't need a PCH PLL of its
* pre-Haswell/LPT generation */ * own on pre-Haswell/LPT generation */
if (HAS_PCH_LPT(dev)) { if (!is_cpu_edp) {
DRM_DEBUG_KMS("LPT detected: no PLL for pipe %d necessary\n",
pipe);
} else if (!is_cpu_edp) {
struct intel_pch_pll *pll; struct intel_pch_pll *pll;
pll = intel_get_pch_pll(intel_crtc, dpll, fp); pll = intel_get_pch_pll(intel_crtc, dpll, fp);
...@@ -5223,9 +5231,9 @@ static int haswell_crtc_mode_set(struct drm_crtc *crtc, ...@@ -5223,9 +5231,9 @@ static int haswell_crtc_mode_set(struct drm_crtc *crtc,
} else } else
intel_put_pch_pll(intel_crtc); intel_put_pch_pll(intel_crtc);
/* The LVDS pin pair needs to be on before the DPLLs are enabled. /* The LVDS pin pair needs to be on before the DPLLs are
* This is an exception to the general rule that mode_set doesn't turn * enabled. This is an exception to the general rule that
* things on. * mode_set doesn't turn things on.
*/ */
if (is_lvds) { if (is_lvds) {
temp = I915_READ(PCH_LVDS); temp = I915_READ(PCH_LVDS);
...@@ -5242,17 +5250,20 @@ static int haswell_crtc_mode_set(struct drm_crtc *crtc, ...@@ -5242,17 +5250,20 @@ static int haswell_crtc_mode_set(struct drm_crtc *crtc,
/* set the corresponsding LVDS_BORDER bit */ /* set the corresponsding LVDS_BORDER bit */
temp |= dev_priv->lvds_border_bits; temp |= dev_priv->lvds_border_bits;
/* Set the B0-B3 data pairs corresponding to whether we're going to /* Set the B0-B3 data pairs corresponding to whether
* set the DPLLs for dual-channel mode or not. * we're going to set the DPLLs for dual-channel mode or
* not.
*/ */
if (clock.p2 == 7) if (clock.p2 == 7)
temp |= LVDS_B0B3_POWER_UP | LVDS_CLKB_POWER_UP; temp |= LVDS_B0B3_POWER_UP | LVDS_CLKB_POWER_UP;
else else
temp &= ~(LVDS_B0B3_POWER_UP | LVDS_CLKB_POWER_UP); temp &= ~(LVDS_B0B3_POWER_UP |
LVDS_CLKB_POWER_UP);
/* It would be nice to set 24 vs 18-bit mode (LVDS_A3_POWER_UP) /* It would be nice to set 24 vs 18-bit mode
* appropriately here, but we need to look more thoroughly into how * (LVDS_A3_POWER_UP) appropriately here, but we need to
* panels behave in the two modes. * look more thoroughly into how panels behave in the
* two modes.
*/ */
temp &= ~(LVDS_HSYNC_POLARITY | LVDS_VSYNC_POLARITY); temp &= ~(LVDS_HSYNC_POLARITY | LVDS_VSYNC_POLARITY);
if (adjusted_mode->flags & DRM_MODE_FLAG_NHSYNC) if (adjusted_mode->flags & DRM_MODE_FLAG_NHSYNC)
...@@ -5261,17 +5272,23 @@ static int haswell_crtc_mode_set(struct drm_crtc *crtc, ...@@ -5261,17 +5272,23 @@ static int haswell_crtc_mode_set(struct drm_crtc *crtc,
temp |= LVDS_VSYNC_POLARITY; temp |= LVDS_VSYNC_POLARITY;
I915_WRITE(PCH_LVDS, temp); I915_WRITE(PCH_LVDS, temp);
} }
}
if (is_dp && !is_cpu_edp) { if (is_dp && !is_cpu_edp) {
intel_dp_set_m_n(crtc, mode, adjusted_mode); intel_dp_set_m_n(crtc, mode, adjusted_mode);
} else { } else {
/* For non-DP output, clear any trans DP clock recovery setting.*/ if (HAS_PCH_IBX(dev) || HAS_PCH_CPT(dev)) {
/* For non-DP output, clear any trans DP clock recovery
* setting.*/
I915_WRITE(TRANSDATA_M1(pipe), 0); I915_WRITE(TRANSDATA_M1(pipe), 0);
I915_WRITE(TRANSDATA_N1(pipe), 0); I915_WRITE(TRANSDATA_N1(pipe), 0);
I915_WRITE(TRANSDPLINK_M1(pipe), 0); I915_WRITE(TRANSDPLINK_M1(pipe), 0);
I915_WRITE(TRANSDPLINK_N1(pipe), 0); I915_WRITE(TRANSDPLINK_N1(pipe), 0);
} }
}
intel_crtc->lowfreq_avail = false;
if (HAS_PCH_IBX(dev) || HAS_PCH_CPT(dev)) {
if (intel_crtc->pch_pll) { if (intel_crtc->pch_pll) {
I915_WRITE(intel_crtc->pch_pll->pll_reg, dpll); I915_WRITE(intel_crtc->pch_pll->pll_reg, dpll);
...@@ -5287,7 +5304,6 @@ static int haswell_crtc_mode_set(struct drm_crtc *crtc, ...@@ -5287,7 +5304,6 @@ static int haswell_crtc_mode_set(struct drm_crtc *crtc,
I915_WRITE(intel_crtc->pch_pll->pll_reg, dpll); I915_WRITE(intel_crtc->pch_pll->pll_reg, dpll);
} }
intel_crtc->lowfreq_avail = false;
if (intel_crtc->pch_pll) { if (intel_crtc->pch_pll) {
if (is_lvds && has_reduced_clock && i915_powersave) { if (is_lvds && has_reduced_clock && i915_powersave) {
I915_WRITE(intel_crtc->pch_pll->fp1_reg, fp2); I915_WRITE(intel_crtc->pch_pll->fp1_reg, fp2);
...@@ -5296,11 +5312,13 @@ static int haswell_crtc_mode_set(struct drm_crtc *crtc, ...@@ -5296,11 +5312,13 @@ static int haswell_crtc_mode_set(struct drm_crtc *crtc,
I915_WRITE(intel_crtc->pch_pll->fp1_reg, fp); I915_WRITE(intel_crtc->pch_pll->fp1_reg, fp);
} }
} }
}
intel_set_pipe_timings(intel_crtc, mode, adjusted_mode); intel_set_pipe_timings(intel_crtc, mode, adjusted_mode);
ironlake_set_m_n(crtc, mode, adjusted_mode); ironlake_set_m_n(crtc, mode, adjusted_mode);
if (HAS_PCH_IBX(dev) || HAS_PCH_CPT(dev))
if (is_cpu_edp) if (is_cpu_edp)
ironlake_set_pll_edp(crtc, adjusted_mode->clock); ironlake_set_pll_edp(crtc, adjusted_mode->clock);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment