aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/i915/intel_psr.c
diff options
context:
space:
mode:
authorRodrigo Vivi <rodrigo.vivi@intel.com>2015-04-10 14:15:08 -0400
committerDaniel Vetter <daniel.vetter@ffwll.ch>2015-04-14 13:15:01 -0400
commit3301d4092106ff07e14d7acbf12243d782600930 (patch)
tree61e839f3cb7cdfa39878e9c43bbdc72dbfa53bec /drivers/gpu/drm/i915/intel_psr.c
parentcff5190cb989f130afa18b96cd33745b733ffae9 (diff)
drm/i915: PSR: Fix DP_PSR_NO_TRAIN_ON_EXIT logic
Since the beginning there is a missunderstanding on the meaning of this dpcd bit. This bit shouldn't indicate whether to use link standby or not, but just be used to configure TP1, TP2 and TP3 times and tell hw aux should be skiped since HW is the responsible one. Even with help of frontbuffer tracking, HW is still fully responsible for PSR exit logic with/without DP training. DP_PSR_NO_TRAIN_ON_EXIT means the source doesn't need to do the training, but it doesn't tell to avoid TP patterns, so we will send minimal TP1 and avoid TP2. It also means that sink itself can take up to 5 idle frames for training. 6 in our case since we might be off by 1. So we also increment idle_frames by 4 here. v2: Fix and improve commit message (Durga). v3: Use minimal TP1 time avoiding TP2 and increase idle frame. Cc: Durgadoss R <durgadoss.r@intel.com> Cc: Arthur Runyan <arthur.j.runyan@intel.com> Signed-off-by: Rodrigo Vivi <rodrigo.vivi@intel.com> Reviewed-by: Durgadoss R <durgadoss.r@intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Diffstat (limited to 'drivers/gpu/drm/i915/intel_psr.c')
-rw-r--r--drivers/gpu/drm/i915/intel_psr.c13
1 files changed, 9 insertions, 4 deletions
diff --git a/drivers/gpu/drm/i915/intel_psr.c b/drivers/gpu/drm/i915/intel_psr.c
index db95b392bcd4..0e3b652b5946 100644
--- a/drivers/gpu/drm/i915/intel_psr.c
+++ b/drivers/gpu/drm/i915/intel_psr.c
@@ -264,11 +264,17 @@ static void hsw_psr_enable_source(struct intel_dp *intel_dp)
264 uint32_t val = 0x0; 264 uint32_t val = 0x0;
265 const uint32_t link_entry_time = EDP_PSR_MIN_LINK_ENTRY_TIME_8_LINES; 265 const uint32_t link_entry_time = EDP_PSR_MIN_LINK_ENTRY_TIME_8_LINES;
266 266
267 if (dev_priv->psr.link_standby) { 267 if (dev_priv->psr.link_standby)
268 val |= EDP_PSR_LINK_STANDBY; 268 val |= EDP_PSR_LINK_STANDBY;
269
270 if (intel_dp->psr_dpcd[1] & DP_PSR_NO_TRAIN_ON_EXIT) {
271 /* It doesn't mean we shouldn't send TPS patters, so let's
272 send the minimal TP1 possible and skip TP2. */
273 val |= EDP_PSR_TP1_TIME_100us;
269 val |= EDP_PSR_TP2_TP3_TIME_0us; 274 val |= EDP_PSR_TP2_TP3_TIME_0us;
270 val |= EDP_PSR_TP1_TIME_0us;
271 val |= EDP_PSR_SKIP_AUX_EXIT; 275 val |= EDP_PSR_SKIP_AUX_EXIT;
276 /* Sink should be able to train with the 5 or 6 idle patterns */
277 idle_frames += 4;
272 } 278 }
273 279
274 I915_WRITE(EDP_PSR_CTL(dev), val | 280 I915_WRITE(EDP_PSR_CTL(dev), val |
@@ -381,8 +387,7 @@ void intel_psr_enable(struct intel_dp *intel_dp)
381 /* First we check VBT, but we must respect sink and source 387 /* First we check VBT, but we must respect sink and source
382 * known restrictions */ 388 * known restrictions */
383 dev_priv->psr.link_standby = dev_priv->vbt.psr.full_link; 389 dev_priv->psr.link_standby = dev_priv->vbt.psr.full_link;
384 if ((intel_dp->psr_dpcd[1] & DP_PSR_NO_TRAIN_ON_EXIT) || 390 if (IS_BROADWELL(dev) && intel_dig_port->port != PORT_A)
385 (IS_BROADWELL(dev) && intel_dig_port->port != PORT_A))
386 dev_priv->psr.link_standby = true; 391 dev_priv->psr.link_standby = true;
387 392
388 dev_priv->psr.busy_frontbuffer_bits = 0; 393 dev_priv->psr.busy_frontbuffer_bits = 0;