@@ -378,72 +378,6 @@ static void hsw_set_power_well(struct drm_i915_private *dev_priv,
BXT_DISPLAY_POWERWELL_2_POWER_DOMAINS)) | \
BIT(POWER_DOMAIN_INIT))
-static void assert_can_enable_dc9(struct drm_i915_private *dev_priv)
-{
- struct drm_device *dev = dev_priv->dev;
-
- WARN(!IS_BROXTON(dev), "Platform doesn't support DC9.\n");
- WARN((I915_READ(DC_STATE_EN) & DC_STATE_EN_DC9),
- "DC9 already programmed to be enabled.\n");
- WARN(I915_READ(DC_STATE_EN) & DC_STATE_EN_UPTO_DC5,
- "DC5 still not disabled to enable DC9.\n");
- WARN(I915_READ(HSW_PWR_WELL_DRIVER), "Power well on.\n");
- WARN(intel_irqs_enabled(dev_priv), "Interrupts not disabled yet.\n");
-
- /*
- * TODO: check for the following to verify the conditions to enter DC9
- * state are satisfied:
- * 1] Check relevant display engine registers to verify if mode set
- * disable sequence was followed.
- * 2] Check if display uninitialize sequence is initialized.
- */
-}
-
-static void assert_can_disable_dc9(struct drm_i915_private *dev_priv)
-{
- WARN(intel_irqs_enabled(dev_priv), "Interrupts not disabled yet.\n");
- WARN(!(I915_READ(DC_STATE_EN) & DC_STATE_EN_DC9),
- "DC9 already programmed to be disabled.\n");
- WARN(I915_READ(DC_STATE_EN) & DC_STATE_EN_UPTO_DC5,
- "DC5 still not disabled.\n");
-
- /*
- * TODO: check for the following to verify DC9 state was indeed
- * entered before programming to disable it:
- * 1] Check relevant display engine registers to verify if mode
- * set disable sequence was followed.
- * 2] Check if display uninitialize sequence is initialized.
- */
-}
-
-void bxt_enable_dc9(struct drm_i915_private *dev_priv)
-{
- uint32_t val;
-
- assert_can_enable_dc9(dev_priv);
-
- DRM_DEBUG_KMS("Enabling DC9\n");
-
- val = I915_READ(DC_STATE_EN);
- val |= DC_STATE_EN_DC9;
- I915_WRITE(DC_STATE_EN, val);
- POSTING_READ(DC_STATE_EN);
-}
-
-void bxt_disable_dc9(struct drm_i915_private *dev_priv)
-{
- uint32_t val;
-
- assert_can_disable_dc9(dev_priv);
-
- DRM_DEBUG_KMS("Disabling DC9\n");
-
- val = I915_READ(DC_STATE_EN);
- val &= ~DC_STATE_EN_DC9;
- I915_WRITE(DC_STATE_EN, val);
- POSTING_READ(DC_STATE_EN);
-}
-
static void gen9_set_dc_state_debugmask_memory_up(
struct drm_i915_private *dev_priv)
{
@@ -582,6 +516,84 @@ void skl_disable_dc6(struct drm_i915_private *dev_priv)
POSTING_READ(DC_STATE_EN);
}
+static void assert_can_enable_dc9(struct drm_i915_private *dev_priv)
+{
+ struct drm_device *dev = dev_priv->dev;
+
+ WARN(!IS_BROXTON(dev), "Platform doesn't support DC9.\n");
+ WARN((I915_READ(DC_STATE_EN) & DC_STATE_EN_DC9),
+ "DC9 already programmed to be enabled.\n");
+ WARN(I915_READ(DC_STATE_EN) & DC_STATE_EN_UPTO_DC5,
+ "DC5 still not disabled to enable DC9.\n");
+ WARN(I915_READ(HSW_PWR_WELL_DRIVER), "Power well on.\n");
+ WARN(intel_irqs_enabled(dev_priv), "Interrupts not disabled yet.\n");
+
+ /*
+ * TODO: check for the following to verify the conditions to enter DC9
+ * state are satisfied:
+ * 1] Check relevant display engine registers to verify if mode set
+ * disable sequence was followed.
+ * 2] Check if display uninitialize sequence is initialized.
+ */
+}
+
+static void assert_can_disable_dc9(struct drm_i915_private *dev_priv)
+{
+ WARN(intel_irqs_enabled(dev_priv), "Interrupts not disabled yet.\n");
+ WARN(!(I915_READ(DC_STATE_EN) & DC_STATE_EN_DC9),
+ "DC9 already programmed to be disabled.\n");
+ WARN(I915_READ(DC_STATE_EN) & DC_STATE_EN_UPTO_DC5,
+ "DC5 still not disabled.\n");
+
+ /*
+ * TODO: check for the following to verify DC9 state was indeed
+ * entered before programming to disable it:
+ * 1] Check relevant display engine registers to verify if mode
+ * set disable sequence was followed.
+ * 2] Check if display uninitialize sequence is initialized.
+ */
+}
+
+void bxt_enable_dc9(struct drm_i915_private *dev_priv)
+{
+ uint32_t val;
+
+ /* Disallow DC5 if enabled*/
+ if (I915_READ(DC_STATE_EN) & DC_STATE_EN_UPTO_DC5) {
+ gen9_disable_dc5(dev_priv);
+ intel_csr_load_status_set(dev_priv, FW_FAILED);
+ }
+
+ assert_can_enable_dc9(dev_priv);
+
+ DRM_DEBUG_KMS("Enabling DC9\n");
+
+ val = I915_READ(DC_STATE_EN);
+ val |= DC_STATE_EN_DC9;
+ I915_WRITE(DC_STATE_EN, val);
+ POSTING_READ(DC_STATE_EN);
+}
+
+void bxt_disable_dc9(struct drm_i915_private *dev_priv)
+{
+ uint32_t val;
+
+ assert_can_disable_dc9(dev_priv);
+
+ DRM_DEBUG_KMS("Disabling DC9\n");
+
+ val = I915_READ(DC_STATE_EN);
+ val &= ~DC_STATE_EN_DC9;
+ I915_WRITE(DC_STATE_EN, val);
+ POSTING_READ(DC_STATE_EN);
+
+ /* Allow DC5 after resume */
+ if (intel_csr_load_status_get(dev_priv) != FW_LOADED) {
+ intel_csr_load_program(dev_priv->dev);
+ gen9_enable_dc5(dev_priv);
+ }
+}
+
static void skl_set_power_well(struct drm_i915_private *dev_priv,
struct i915_power_well *power_well, bool enable)
{
Before entering into DC9 state need to disallow DC5 if it is enabled. After resume based firmware loading status dc5 will be reenabled again. In suspend-resume senario transition may happen from single display to dual display or dual display to single display and both the cases during resume dc5 will be reenabled. And later if required(for dual display) again dc5 will be disabled as part of power-well code. NOTE: This patch created based on TOT and might change a little once dmc-redesign patch series merged in upstream. Currently sending for review as RFC, will modify based on review comments. v1: Initial version. v2: Based on review comment from Jon, - Used disable_dc5 function call. To avoid forward declaration moved functions definitions. v3: RFC version for upstream. Cc: Imre Deak <imre.deak@intel.com> Cc: Sunil Kamath <sunil.kamath@intel.com> Cc: Jon Bloomfield <jon.bloomfield@intel.com> Signed-off-by: Animesh Manna <animesh.manna@intel.com> --- drivers/gpu/drm/i915/intel_runtime_pm.c | 144 +++++++++++++++++--------------- 1 file changed, 78 insertions(+), 66 deletions(-)