diff options
-rw-r--r-- | drivers/gpu/drm/i915/intel_runtime_pm.c | 41 |
1 files changed, 39 insertions, 2 deletions
diff --git a/drivers/gpu/drm/i915/intel_runtime_pm.c b/drivers/gpu/drm/i915/intel_runtime_pm.c index 19e6ff64ce9d..678ed3475d7e 100644 --- a/drivers/gpu/drm/i915/intel_runtime_pm.c +++ b/drivers/gpu/drm/i915/intel_runtime_pm.c | |||
@@ -470,6 +470,43 @@ static void gen9_set_dc_state_debugmask_memory_up( | |||
470 | } | 470 | } |
471 | } | 471 | } |
472 | 472 | ||
473 | static void gen9_write_dc_state(struct drm_i915_private *dev_priv, | ||
474 | u32 state) | ||
475 | { | ||
476 | int rewrites = 0; | ||
477 | int rereads = 0; | ||
478 | u32 v; | ||
479 | |||
480 | I915_WRITE(DC_STATE_EN, state); | ||
481 | |||
482 | /* It has been observed that disabling the dc6 state sometimes | ||
483 | * doesn't stick and dmc keeps returning old value. Make sure | ||
484 | * the write really sticks enough times and also force rewrite until | ||
485 | * we are confident that state is exactly what we want. | ||
486 | */ | ||
487 | do { | ||
488 | v = I915_READ(DC_STATE_EN); | ||
489 | |||
490 | if (v != state) { | ||
491 | I915_WRITE(DC_STATE_EN, state); | ||
492 | rewrites++; | ||
493 | rereads = 0; | ||
494 | } else if (rereads++ > 5) { | ||
495 | break; | ||
496 | } | ||
497 | |||
498 | } while (rewrites < 100); | ||
499 | |||
500 | if (v != state) | ||
501 | DRM_ERROR("Writing dc state to 0x%x failed, now 0x%x\n", | ||
502 | state, v); | ||
503 | |||
504 | /* Most of the times we need one retry, avoid spam */ | ||
505 | if (rewrites > 1) | ||
506 | DRM_DEBUG_KMS("Rewrote dc state to 0x%x %d times\n", | ||
507 | state, rewrites); | ||
508 | } | ||
509 | |||
473 | static void gen9_set_dc_state(struct drm_i915_private *dev_priv, uint32_t state) | 510 | static void gen9_set_dc_state(struct drm_i915_private *dev_priv, uint32_t state) |
474 | { | 511 | { |
475 | uint32_t val; | 512 | uint32_t val; |
@@ -502,8 +539,8 @@ static void gen9_set_dc_state(struct drm_i915_private *dev_priv, uint32_t state) | |||
502 | 539 | ||
503 | val &= ~mask; | 540 | val &= ~mask; |
504 | val |= state; | 541 | val |= state; |
505 | I915_WRITE(DC_STATE_EN, val); | 542 | |
506 | POSTING_READ(DC_STATE_EN); | 543 | gen9_write_dc_state(dev_priv, val); |
507 | 544 | ||
508 | dev_priv->csr.dc_state = val & mask; | 545 | dev_priv->csr.dc_state = val & mask; |
509 | } | 546 | } |