mirror of
https://github.com/torvalds/linux.git
synced 2024-12-25 12:21:37 +00:00
drm/i915: robustify edp_pll_on/off
With the previous patch to clean up where exactly these two functions are getting called, this patch can tackle the enable/disable code itself: - WARN if the port enable bit is in the wrong state or if the edp pll bit is in the wrong state, just for paranoia's sake. - Don't disable the edp pll harder in the modeset functions just for fun. - Don't set the edp pll enable flag in intel_dp->DP in modeset, do that while changing the actual hw state. We do the same with the actual port enable bit, so this is a bit more consistent. - Track the current DP register value when setting things up and add some comments how intel_dp->DP is used in the disable code. v2: Be more careful with resetting intel_dp->DP - otherwise dpms off->on will fail spectacularly, becuase we enable the eDP port when we should only enable the eDP pll. Reviewed-by: Paulo Zanoni <paulo.r.zanoni@intel.com> Signed-Off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
This commit is contained in:
parent
2bd2ad643d
commit
0767935e86
@ -887,7 +887,6 @@ intel_dp_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode,
|
||||
intel_dp->DP |= intel_crtc->pipe << 29;
|
||||
|
||||
/* don't miss out required setting for eDP */
|
||||
intel_dp->DP |= DP_PLL_ENABLE;
|
||||
if (adjusted_mode->clock < 200000)
|
||||
intel_dp->DP |= DP_PLL_FREQ_160MHZ;
|
||||
else
|
||||
@ -909,7 +908,6 @@ intel_dp_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode,
|
||||
|
||||
if (is_cpu_edp(intel_dp)) {
|
||||
/* don't miss out required setting for eDP */
|
||||
intel_dp->DP |= DP_PLL_ENABLE;
|
||||
if (adjusted_mode->clock < 200000)
|
||||
intel_dp->DP |= DP_PLL_FREQ_160MHZ;
|
||||
else
|
||||
@ -1192,8 +1190,15 @@ static void ironlake_edp_pll_on(struct intel_dp *intel_dp)
|
||||
|
||||
DRM_DEBUG_KMS("\n");
|
||||
dpa_ctl = I915_READ(DP_A);
|
||||
dpa_ctl |= DP_PLL_ENABLE;
|
||||
I915_WRITE(DP_A, dpa_ctl);
|
||||
WARN(dpa_ctl & DP_PLL_ENABLE, "dp pll on, should be off\n");
|
||||
WARN(dpa_ctl & DP_PORT_EN, "dp port still on, should be off\n");
|
||||
|
||||
/* We don't adjust intel_dp->DP while tearing down the link, to
|
||||
* facilitate link retraining (e.g. after hotplug). Hence clear all
|
||||
* enable bits here to ensure that we don't enable too much. */
|
||||
intel_dp->DP &= ~(DP_PORT_EN | DP_AUDIO_OUTPUT_ENABLE);
|
||||
intel_dp->DP |= DP_PLL_ENABLE;
|
||||
I915_WRITE(DP_A, intel_dp->DP);
|
||||
POSTING_READ(DP_A);
|
||||
udelay(200);
|
||||
}
|
||||
@ -1209,6 +1214,13 @@ static void ironlake_edp_pll_off(struct intel_dp *intel_dp)
|
||||
to_intel_crtc(crtc)->pipe);
|
||||
|
||||
dpa_ctl = I915_READ(DP_A);
|
||||
WARN((dpa_ctl & DP_PLL_ENABLE) == 0,
|
||||
"dp pll off, should be on\n");
|
||||
WARN(dpa_ctl & DP_PORT_EN, "dp port still on, should be off\n");
|
||||
|
||||
/* We can't rely on the value tracked for the DP register in
|
||||
* intel_dp->DP because link_down must not change that (otherwise link
|
||||
* re-training will fail. */
|
||||
dpa_ctl &= ~DP_PLL_ENABLE;
|
||||
I915_WRITE(DP_A, dpa_ctl);
|
||||
POSTING_READ(DP_A);
|
||||
@ -1893,13 +1905,6 @@ intel_dp_link_down(struct intel_dp *intel_dp)
|
||||
|
||||
DRM_DEBUG_KMS("\n");
|
||||
|
||||
if (is_edp(intel_dp)) {
|
||||
DP &= ~DP_PLL_ENABLE;
|
||||
I915_WRITE(intel_dp->output_reg, DP);
|
||||
POSTING_READ(intel_dp->output_reg);
|
||||
udelay(100);
|
||||
}
|
||||
|
||||
if (HAS_PCH_CPT(dev) && (IS_GEN7(dev) || !is_cpu_edp(intel_dp))) {
|
||||
DP &= ~DP_LINK_TRAIN_MASK_CPT;
|
||||
I915_WRITE(intel_dp->output_reg, DP | DP_LINK_TRAIN_PAT_IDLE_CPT);
|
||||
@ -2443,6 +2448,8 @@ intel_dp_init(struct drm_device *dev, int output_reg, enum port port)
|
||||
|
||||
intel_dp->output_reg = output_reg;
|
||||
intel_dp->port = port;
|
||||
/* Preserve the current hw state. */
|
||||
intel_dp->DP = I915_READ(intel_dp->output_reg);
|
||||
|
||||
intel_connector = kzalloc(sizeof(struct intel_connector), GFP_KERNEL);
|
||||
if (!intel_connector) {
|
||||
|
Loading…
Reference in New Issue
Block a user