| From 03b7b5f983091bca17e9c163832fcde56971d7d1 Mon Sep 17 00:00:00 2001 |
| From: Daniel Vetter <daniel.vetter@ffwll.ch> |
| Date: Wed, 18 May 2016 18:47:11 +0200 |
| Subject: drm/i915/psr: Try to program link training times correctly |
| MIME-Version: 1.0 |
| Content-Type: text/plain; charset=UTF-8 |
| Content-Transfer-Encoding: 8bit |
| |
| From: Daniel Vetter <daniel.vetter@ffwll.ch> |
| |
| commit 03b7b5f983091bca17e9c163832fcde56971d7d1 upstream. |
| |
| 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: Lyude <cpaul@redhat.com> |
| Cc: Lyude <cpaul@redhat.com> |
| 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: Ville Syrjälä <ville.syrjala@linux.intel.com> |
| Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com> |
| Tested-by: fritsch@kodi.tv |
| Signed-off-by: Daniel Vetter <daniel.vetter@intel.com> |
| Link: http://patchwork.freedesktop.org/patch/msgid/1463590036-17824-2-git-send-email-daniel.vetter@ffwll.ch |
| (cherry picked from commit 50db139018f9c94376d5f4db94a3bae65fdfac14) |
| Signed-off-by: Jani Nikula <jani.nikula@intel.com> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| |
| --- |
| drivers/gpu/drm/i915/intel_psr.c | 57 ++++++++++++++++++++++++++++++++------- |
| 1 file changed, 48 insertions(+), 9 deletions(-) |
| |
| --- a/drivers/gpu/drm/i915/intel_psr.c |
| +++ b/drivers/gpu/drm/i915/intel_psr.c |
| @@ -280,7 +280,10 @@ static void hsw_psr_enable_source(struct |
| * with the 5 or 6 idle patterns. |
| */ |
| 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)) |
| val |= EDP_PSR_MIN_LINK_ENTRY_TIME_8_LINES; |
| @@ -288,14 +291,50 @@ static void hsw_psr_enable_source(struct |
| if (dev_priv->psr.link_standby) |
| val |= EDP_PSR_LINK_STANDBY; |
| |
| - I915_WRITE(EDP_PSR_CTL, val | |
| - max_sleep_time << EDP_PSR_MAX_SLEEP_TIME_SHIFT | |
| - idle_frames << EDP_PSR_IDLE_FRAME_SHIFT | |
| - EDP_PSR_ENABLE); |
| - |
| - if (dev_priv->psr.psr2_support) |
| - I915_WRITE(EDP_PSR2_CTL, EDP_PSR2_ENABLE | |
| - EDP_SU_TRACK_ENABLE | EDP_PSR2_TP2_TIME_100); |
| + if (dev_priv->vbt.psr.tp1_wakeup_time > 5) |
| + val |= EDP_PSR_TP1_TIME_2500us; |
| + else if (dev_priv->vbt.psr.tp1_wakeup_time > 1) |
| + 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; |
| + |
| + I915_WRITE(EDP_PSR2_CTL, val); |
| } |
| |
| static bool intel_psr_match_conditions(struct intel_dp *intel_dp) |