Commit 50db1390 authored by Daniel Vetter's avatar Daniel Vetter

drm/i915/psr: Try to program link training times correctly

The default of 0 is 500us of link training, but that's not enough for
some platforms. Decoding this correctly means we're using 2.5ms of
link training on these platforms, which fixes flickering issues
associated with enabling PSR.

v2: Unbotch the math a bit.

v3: Drop debug hunk.

v4: Improve commit message.
Tested-by: default avatarLyude <cpaul@redhat.com>
Cc: Lyude <cpaul@redhat.com>
Cc: stable@vger.kernel.org
Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=95176
Cc: Rodrigo Vivi <rodrigo.vivi@intel.com>
Cc: Sonika Jindal <sonika.jindal@intel.com>
Cc: Durgadoss R <durgadoss.r@intel.com>
Cc: "Pandiyan, Dhinakaran" <dhinakaran.pandiyan@intel.com>
Tested-by: default avatarVille Syrjälä <ville.syrjala@linux.intel.com>
Reviewed-by: default avatarVille Syrjälä <ville.syrjala@linux.intel.com>
Tested-by: fritsch@kodi.tv
Signed-off-by: default avatarDaniel Vetter <daniel.vetter@intel.com>
Link: http://patchwork.freedesktop.org/patch/msgid/1463590036-17824-2-git-send-email-daniel.vetter@ffwll.ch
parent 72778cb2
...@@ -280,7 +280,10 @@ static void hsw_psr_enable_source(struct intel_dp *intel_dp) ...@@ -280,7 +280,10 @@ static void hsw_psr_enable_source(struct intel_dp *intel_dp)
* with the 5 or 6 idle patterns. * with the 5 or 6 idle patterns.
*/ */
uint32_t idle_frames = max(6, dev_priv->vbt.psr.idle_frames); uint32_t idle_frames = max(6, dev_priv->vbt.psr.idle_frames);
uint32_t val = 0x0; uint32_t val = EDP_PSR_ENABLE;
val |= max_sleep_time << EDP_PSR_MAX_SLEEP_TIME_SHIFT;
val |= idle_frames << EDP_PSR_IDLE_FRAME_SHIFT;
if (IS_HASWELL(dev)) if (IS_HASWELL(dev))
val |= EDP_PSR_MIN_LINK_ENTRY_TIME_8_LINES; val |= EDP_PSR_MIN_LINK_ENTRY_TIME_8_LINES;
...@@ -288,14 +291,50 @@ static void hsw_psr_enable_source(struct intel_dp *intel_dp) ...@@ -288,14 +291,50 @@ static void hsw_psr_enable_source(struct intel_dp *intel_dp)
if (dev_priv->psr.link_standby) if (dev_priv->psr.link_standby)
val |= EDP_PSR_LINK_STANDBY; val |= EDP_PSR_LINK_STANDBY;
I915_WRITE(EDP_PSR_CTL, val | if (dev_priv->vbt.psr.tp1_wakeup_time > 5)
max_sleep_time << EDP_PSR_MAX_SLEEP_TIME_SHIFT | val |= EDP_PSR_TP1_TIME_2500us;
idle_frames << EDP_PSR_IDLE_FRAME_SHIFT | else if (dev_priv->vbt.psr.tp1_wakeup_time > 1)
EDP_PSR_ENABLE); val |= EDP_PSR_TP1_TIME_500us;
else if (dev_priv->vbt.psr.tp1_wakeup_time > 0)
val |= EDP_PSR_TP1_TIME_100us;
else
val |= EDP_PSR_TP1_TIME_0us;
if (dev_priv->vbt.psr.tp2_tp3_wakeup_time > 5)
val |= EDP_PSR_TP2_TP3_TIME_2500us;
else if (dev_priv->vbt.psr.tp2_tp3_wakeup_time > 1)
val |= EDP_PSR_TP2_TP3_TIME_500us;
else if (dev_priv->vbt.psr.tp2_tp3_wakeup_time > 0)
val |= EDP_PSR_TP2_TP3_TIME_100us;
else
val |= EDP_PSR_TP2_TP3_TIME_0us;
if (intel_dp_source_supports_hbr2(intel_dp) &&
drm_dp_tps3_supported(intel_dp->dpcd))
val |= EDP_PSR_TP1_TP3_SEL;
else
val |= EDP_PSR_TP1_TP2_SEL;
I915_WRITE(EDP_PSR_CTL, val);
if (!dev_priv->psr.psr2_support)
return;
/* FIXME: selective update is probably totally broken because it doesn't
* mesh at all with our frontbuffer tracking. And the hw alone isn't
* good enough. */
val = EDP_PSR2_ENABLE | EDP_SU_TRACK_ENABLE;
if (dev_priv->vbt.psr.tp2_tp3_wakeup_time > 5)
val |= EDP_PSR2_TP2_TIME_2500;
else if (dev_priv->vbt.psr.tp2_tp3_wakeup_time > 1)
val |= EDP_PSR2_TP2_TIME_500;
else if (dev_priv->vbt.psr.tp2_tp3_wakeup_time > 0)
val |= EDP_PSR2_TP2_TIME_100;
else
val |= EDP_PSR2_TP2_TIME_50;
if (dev_priv->psr.psr2_support) I915_WRITE(EDP_PSR2_CTL, val);
I915_WRITE(EDP_PSR2_CTL, EDP_PSR2_ENABLE |
EDP_SU_TRACK_ENABLE | EDP_PSR2_TP2_TIME_100);
} }
static bool intel_psr_match_conditions(struct intel_dp *intel_dp) static bool intel_psr_match_conditions(struct intel_dp *intel_dp)
......
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