mirror of
https://github.com/AuxXxilium/linux_dsm_epyc7002.git
synced 2024-12-28 11:18:45 +07:00
drm/i915: Check PSR errors instead of retrain while PSR is enabled
When a PSR error happens sink sets the PSR error register and also set the link status to a error status. So in the short pulse handling it was returning earlier and doing a full detection and attempting to retrain but it fails as PSR HW is in change of the main-link. Just call intel_psr_short_pulse() before intel_dp_needs_link_retrain() is not the right fix as intel_dp_needs_link_retrain() would return true and trigger a full detection while PSR HW is still in change of main-link. Check for PSR active is also not safe as it could be inactive due a frontbuffer invalidate and still doing the PSR exit sequence. v3: added comment in intel_dp_needs_link_retrain() Cc: Dhinakaran Pandiyan <dhinakaran.pandiyan@intel.com> Reviewed-by: Rodrigo Vivi <rodrigo.vivi@intel.com> Signed-off-by: José Roberto de Souza <jose.souza@intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20181121225441.18785-2-jose.souza@intel.com
This commit is contained in:
parent
2bb06265cf
commit
2f8e7ea974
@ -4383,6 +4383,17 @@ intel_dp_needs_link_retrain(struct intel_dp *intel_dp)
|
|||||||
if (!intel_dp->link_trained)
|
if (!intel_dp->link_trained)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* While PSR source HW is enabled, it will control main-link sending
|
||||||
|
* frames, enabling and disabling it so trying to do a retrain will fail
|
||||||
|
* as the link would or not be on or it could mix training patterns
|
||||||
|
* and frame data at the same time causing retrain to fail.
|
||||||
|
* Also when exiting PSR, HW will retrain the link anyways fixing
|
||||||
|
* any link status error.
|
||||||
|
*/
|
||||||
|
if (intel_psr_enabled(intel_dp))
|
||||||
|
return false;
|
||||||
|
|
||||||
if (!intel_dp_get_link_status(intel_dp, link_status))
|
if (!intel_dp_get_link_status(intel_dp, link_status))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
@ -2047,6 +2047,7 @@ void intel_psr_irq_handler(struct drm_i915_private *dev_priv, u32 psr_iir);
|
|||||||
void intel_psr_short_pulse(struct intel_dp *intel_dp);
|
void intel_psr_short_pulse(struct intel_dp *intel_dp);
|
||||||
int intel_psr_wait_for_idle(const struct intel_crtc_state *new_crtc_state,
|
int intel_psr_wait_for_idle(const struct intel_crtc_state *new_crtc_state,
|
||||||
u32 *out_value);
|
u32 *out_value);
|
||||||
|
bool intel_psr_enabled(struct intel_dp *intel_dp);
|
||||||
|
|
||||||
/* intel_quirks.c */
|
/* intel_quirks.c */
|
||||||
void intel_init_quirks(struct drm_i915_private *dev_priv);
|
void intel_init_quirks(struct drm_i915_private *dev_priv);
|
||||||
|
@ -1147,3 +1147,18 @@ void intel_psr_short_pulse(struct intel_dp *intel_dp)
|
|||||||
exit:
|
exit:
|
||||||
mutex_unlock(&psr->lock);
|
mutex_unlock(&psr->lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool intel_psr_enabled(struct intel_dp *intel_dp)
|
||||||
|
{
|
||||||
|
struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
|
||||||
|
bool ret;
|
||||||
|
|
||||||
|
if (!CAN_PSR(dev_priv) || !intel_dp_is_edp(intel_dp))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
mutex_lock(&dev_priv->psr.lock);
|
||||||
|
ret = (dev_priv->psr.dp == intel_dp && dev_priv->psr.enabled);
|
||||||
|
mutex_unlock(&dev_priv->psr.lock);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user