aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorRodrigo Vivi <rodrigo.vivi@intel.com>2014-11-19 10:37:00 -0500
committerDaniel Vetter <daniel.vetter@ffwll.ch>2014-12-03 03:35:08 -0500
commite2bbc343de8ea463af9da810b6e5e32dbd636b44 (patch)
tree6be98742806f0e921aff1a6f8ef1bc049e1d9577 /drivers
parentc8f7df58f711e02b0788b75c054c6d32056ea170 (diff)
drm/i915: PSR VLV/CHV: Introduce setup, enable and disable functions
The biggest difference from HSW/BDW PSR here is that VLV enable_source function enables PSR but let it in Inactive state. So it might be called on early stage along with setup and enable_sink ones. v2: Rebase over intel_psr.c; Remove docs from static functions; Merge vlv_psr_active_on_pipe; Timeout for psr transition is 250us; Remove SRC_TRASMITTER_STATE; v3: Rebase after is_psr_enabled function got removed; Get SRC_TRANSMITTER_STATE back to be on the safe side since default for panels is to require link training on exit when main link off; As pointed out by Durgadoss msecs_to_jiffies used on wait_for only uses int, so let's use 1 instead. Althought the 1/4 of this is needed for the transition let's use 1 for simplicity; Cc: Durgadoss R <durgadoss.r@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')
-rw-r--r--drivers/gpu/drm/i915/intel_psr.c155
1 files changed, 130 insertions, 25 deletions
diff --git a/drivers/gpu/drm/i915/intel_psr.c b/drivers/gpu/drm/i915/intel_psr.c
index 576ad0222221..30f341ace83d 100644
--- a/drivers/gpu/drm/i915/intel_psr.c
+++ b/drivers/gpu/drm/i915/intel_psr.c
@@ -61,6 +61,17 @@ static bool is_edp_psr(struct intel_dp *intel_dp)
61 return intel_dp->psr_dpcd[0] & DP_PSR_IS_SUPPORTED; 61 return intel_dp->psr_dpcd[0] & DP_PSR_IS_SUPPORTED;
62} 62}
63 63
64static bool vlv_is_psr_active_on_pipe(struct drm_device *dev, int pipe)
65{
66 struct drm_i915_private *dev_priv = dev->dev_private;
67 uint32_t val;
68
69 val = I915_READ(VLV_PSRSTAT(pipe)) &
70 VLV_EDP_PSR_CURR_STATE_MASK;
71 return (val == VLV_EDP_PSR_ACTIVE_NORFB_UP) ||
72 (val == VLV_EDP_PSR_ACTIVE_SF_UPDATE);
73}
74
64static void intel_psr_write_vsc(struct intel_dp *intel_dp, 75static void intel_psr_write_vsc(struct intel_dp *intel_dp,
65 struct edp_vsc_psr *vsc_psr) 76 struct edp_vsc_psr *vsc_psr)
66{ 77{
@@ -90,7 +101,23 @@ static void intel_psr_write_vsc(struct intel_dp *intel_dp,
90 POSTING_READ(ctl_reg); 101 POSTING_READ(ctl_reg);
91} 102}
92 103
93static void intel_psr_setup_vsc(struct intel_dp *intel_dp) 104static void vlv_psr_setup_vsc(struct intel_dp *intel_dp)
105{
106 struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp);
107 struct drm_device *dev = intel_dig_port->base.base.dev;
108 struct drm_i915_private *dev_priv = dev->dev_private;
109 struct drm_crtc *crtc = intel_dig_port->base.base.crtc;
110 enum pipe pipe = to_intel_crtc(crtc)->pipe;
111 uint32_t val;
112
113 /* VLV auto-generate VSC package as per EDP 1.3 spec, Table 3.10 */
114 val = I915_READ(VLV_VSCSDP(pipe));
115 val &= ~VLV_EDP_PSR_SDP_FREQ_MASK;
116 val |= VLV_EDP_PSR_SDP_FREQ_EVFRAME;
117 I915_WRITE(VLV_VSCSDP(pipe), val);
118}
119
120static void hsw_psr_setup_vsc(struct intel_dp *intel_dp)
94{ 121{
95 struct edp_vsc_psr psr_vsc; 122 struct edp_vsc_psr psr_vsc;
96 123
@@ -103,7 +130,13 @@ static void intel_psr_setup_vsc(struct intel_dp *intel_dp)
103 intel_psr_write_vsc(intel_dp, &psr_vsc); 130 intel_psr_write_vsc(intel_dp, &psr_vsc);
104} 131}
105 132
106static void intel_psr_enable_sink(struct intel_dp *intel_dp) 133static void vlv_psr_enable_sink(struct intel_dp *intel_dp)
134{
135 drm_dp_dpcd_writeb(&intel_dp->aux, DP_PSR_EN_CFG,
136 DP_PSR_ENABLE);
137}
138
139static void hsw_psr_enable_sink(struct intel_dp *intel_dp)
107{ 140{
108 struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp); 141 struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp);
109 struct drm_device *dev = dig_port->base.base.dev; 142 struct drm_device *dev = dig_port->base.base.dev;
@@ -147,7 +180,22 @@ static void intel_psr_enable_sink(struct intel_dp *intel_dp)
147 (aux_clock_divider << DP_AUX_CH_CTL_BIT_CLOCK_2X_SHIFT)); 180 (aux_clock_divider << DP_AUX_CH_CTL_BIT_CLOCK_2X_SHIFT));
148} 181}
149 182
150static void intel_psr_enable_source(struct intel_dp *intel_dp) 183static void vlv_psr_enable_source(struct intel_dp *intel_dp)
184{
185 struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp);
186 struct drm_device *dev = dig_port->base.base.dev;
187 struct drm_i915_private *dev_priv = dev->dev_private;
188 struct drm_crtc *crtc = dig_port->base.base.crtc;
189 enum pipe pipe = to_intel_crtc(crtc)->pipe;
190
191 /* Transition from PSR_state 0 to PSR_state 1, i.e. PSR Inactive */
192 I915_WRITE(VLV_PSRCTL(pipe),
193 VLV_EDP_PSR_MODE_SW_TIMER |
194 VLV_EDP_PSR_SRC_TRANSMITTER_STATE |
195 VLV_EDP_PSR_ENABLE);
196}
197
198static void hsw_psr_enable_source(struct intel_dp *intel_dp)
151{ 199{
152 struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp); 200 struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp);
153 struct drm_device *dev = dig_port->base.base.dev; 201 struct drm_device *dev = dig_port->base.base.dev;
@@ -225,7 +273,7 @@ static bool intel_psr_match_conditions(struct intel_dp *intel_dp)
225 return true; 273 return true;
226} 274}
227 275
228static void intel_psr_do_enable(struct intel_dp *intel_dp) 276static void intel_psr_activate(struct intel_dp *intel_dp)
229{ 277{
230 struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp); 278 struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp);
231 struct drm_device *dev = intel_dig_port->base.base.dev; 279 struct drm_device *dev = intel_dig_port->base.base.dev;
@@ -235,9 +283,12 @@ static void intel_psr_do_enable(struct intel_dp *intel_dp)
235 WARN_ON(dev_priv->psr.active); 283 WARN_ON(dev_priv->psr.active);
236 lockdep_assert_held(&dev_priv->psr.lock); 284 lockdep_assert_held(&dev_priv->psr.lock);
237 285
238 /* Enable/Re-enable PSR on the host */ 286 /* Enable/Re-enable PSR on the host
239 intel_psr_enable_source(intel_dp); 287 * On HSW+ after we enable PSR on source it will activate it
240 288 * as soon as it match configure idle_frame count. So
289 * we just actually enable it here on activation time.
290 */
291 hsw_psr_enable_source(intel_dp);
241 dev_priv->psr.active = true; 292 dev_priv->psr.active = true;
242} 293}
243 294
@@ -274,37 +325,67 @@ void intel_psr_enable(struct intel_dp *intel_dp)
274 325
275 dev_priv->psr.busy_frontbuffer_bits = 0; 326 dev_priv->psr.busy_frontbuffer_bits = 0;
276 327
277 intel_psr_setup_vsc(intel_dp); 328 if (HAS_DDI(dev)) {
329 hsw_psr_setup_vsc(intel_dp);
278 330
279 /* Avoid continuous PSR exit by masking memup and hpd */ 331 /* Avoid continuous PSR exit by masking memup and hpd */
280 I915_WRITE(EDP_PSR_DEBUG_CTL(dev), EDP_PSR_DEBUG_MASK_MEMUP | 332 I915_WRITE(EDP_PSR_DEBUG_CTL(dev), EDP_PSR_DEBUG_MASK_MEMUP |
281 EDP_PSR_DEBUG_MASK_HPD | EDP_PSR_DEBUG_MASK_LPSP); 333 EDP_PSR_DEBUG_MASK_HPD | EDP_PSR_DEBUG_MASK_LPSP);
282 334
283 /* Enable PSR on the panel */ 335 /* Enable PSR on the panel */
284 intel_psr_enable_sink(intel_dp); 336 hsw_psr_enable_sink(intel_dp);
337 } else {
338 vlv_psr_setup_vsc(intel_dp);
339
340 /* Enable PSR on the panel */
341 vlv_psr_enable_sink(intel_dp);
342
343 /* On HSW+ enable_source also means go to PSR entry/active
344 * state as soon as idle_frame achieved and here would be
345 * to soon. However on VLV enable_source just enable PSR
346 * but let it on inactive state. So we might do this prior
347 * to active transition, i.e. here.
348 */
349 vlv_psr_enable_source(intel_dp);
350 }
285 351
286 dev_priv->psr.enabled = intel_dp; 352 dev_priv->psr.enabled = intel_dp;
287unlock: 353unlock:
288 mutex_unlock(&dev_priv->psr.lock); 354 mutex_unlock(&dev_priv->psr.lock);
289} 355}
290 356
291/** 357static void vlv_psr_disable(struct intel_dp *intel_dp)
292 * intel_psr_disable - Disable PSR
293 * @intel_dp: Intel DP
294 *
295 * This function needs to be called before disabling pipe.
296 */
297void intel_psr_disable(struct intel_dp *intel_dp)
298{ 358{
299 struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp); 359 struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp);
300 struct drm_device *dev = intel_dig_port->base.base.dev; 360 struct drm_device *dev = intel_dig_port->base.base.dev;
301 struct drm_i915_private *dev_priv = dev->dev_private; 361 struct drm_i915_private *dev_priv = dev->dev_private;
362 struct intel_crtc *intel_crtc =
363 to_intel_crtc(intel_dig_port->base.base.crtc);
364 uint32_t val;
302 365
303 mutex_lock(&dev_priv->psr.lock); 366 if (dev_priv->psr.active) {
304 if (!dev_priv->psr.enabled) { 367 /* Put VLV PSR back to PSR_state 0 that is PSR Disabled. */
305 mutex_unlock(&dev_priv->psr.lock); 368 if (wait_for((I915_READ(VLV_PSRSTAT(intel_crtc->pipe)) &
306 return; 369 VLV_EDP_PSR_IN_TRANS) == 0, 1))
370 WARN(1, "PSR transition took longer than expected\n");
371
372 val = I915_READ(VLV_PSRCTL(intel_crtc->pipe));
373 val &= ~VLV_EDP_PSR_ACTIVE_ENTRY;
374 val &= ~VLV_EDP_PSR_ENABLE;
375 val &= ~VLV_EDP_PSR_MODE_MASK;
376 I915_WRITE(VLV_PSRCTL(intel_crtc->pipe), val);
377
378 dev_priv->psr.active = false;
379 } else {
380 WARN_ON(vlv_is_psr_active_on_pipe(dev, intel_crtc->pipe));
307 } 381 }
382}
383
384static void hsw_psr_disable(struct intel_dp *intel_dp)
385{
386 struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp);
387 struct drm_device *dev = intel_dig_port->base.base.dev;
388 struct drm_i915_private *dev_priv = dev->dev_private;
308 389
309 if (dev_priv->psr.active) { 390 if (dev_priv->psr.active) {
310 I915_WRITE(EDP_PSR_CTL(dev), 391 I915_WRITE(EDP_PSR_CTL(dev),
@@ -319,6 +400,30 @@ void intel_psr_disable(struct intel_dp *intel_dp)
319 } else { 400 } else {
320 WARN_ON(I915_READ(EDP_PSR_CTL(dev)) & EDP_PSR_ENABLE); 401 WARN_ON(I915_READ(EDP_PSR_CTL(dev)) & EDP_PSR_ENABLE);
321 } 402 }
403}
404
405/**
406 * intel_psr_disable - Disable PSR
407 * @intel_dp: Intel DP
408 *
409 * This function needs to be called before disabling pipe.
410 */
411void intel_psr_disable(struct intel_dp *intel_dp)
412{
413 struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp);
414 struct drm_device *dev = intel_dig_port->base.base.dev;
415 struct drm_i915_private *dev_priv = dev->dev_private;
416
417 mutex_lock(&dev_priv->psr.lock);
418 if (!dev_priv->psr.enabled) {
419 mutex_unlock(&dev_priv->psr.lock);
420 return;
421 }
422
423 if (HAS_DDI(dev))
424 hsw_psr_disable(intel_dp);
425 else
426 vlv_psr_disable(intel_dp);
322 427
323 dev_priv->psr.enabled = NULL; 428 dev_priv->psr.enabled = NULL;
324 mutex_unlock(&dev_priv->psr.lock); 429 mutex_unlock(&dev_priv->psr.lock);
@@ -357,7 +462,7 @@ static void intel_psr_work(struct work_struct *work)
357 if (dev_priv->psr.busy_frontbuffer_bits) 462 if (dev_priv->psr.busy_frontbuffer_bits)
358 goto unlock; 463 goto unlock;
359 464
360 intel_psr_do_enable(intel_dp); 465 intel_psr_activate(intel_dp);
361unlock: 466unlock:
362 mutex_unlock(&dev_priv->psr.lock); 467 mutex_unlock(&dev_priv->psr.lock);
363} 468}