drm/i915/icl: Enable DC9 as lowest possible state during screen-off
authorAnimesh Manna <animesh.manna@intel.com>
Mon, 29 Oct 2018 22:14:10 +0000 (15:14 -0700)
committerRodrigo Vivi <rodrigo.vivi@intel.com>
Tue, 30 Oct 2018 17:55:10 +0000 (10:55 -0700)
ICL supports DC5, DC6, and DC9. Enable DC9 during screen-off, and enable
DC5/6 when appropriate.

v2: (James Ausmus)
 - Also handle ICL as GEN9_LP in i915_drm_suspend_late and
   i915_drm_suspend_early
 - Add DC9 to gen9_dc_mask for ICL
 - Re-order GEN checks for newest platform first
 - Use INTEL_GEN instead of INTEL_INFO->gen
 - Use INTEL_GEN >= 11 instead of IS_ICELAKE
 - Consolidate GEN checks

v3: (James Ausmus)
 - Also allow DC6 for ICL (Imre, Art)
 - Simplify !(GEN >= 11) to GEN < 11 (Imre)

v4: (James Ausmus)
 - Don't call intel_power_sequencer_reset after DC9 for Gen11+, as the
   PPS regs are Always On
 - Rebase against upstream changes

v5: (Anusha Srivatsa)
- rebased against the latest upstream changes.

v6: (Anusha Srivatsa)
- rebased.Use INTEL_GEN consistently.
- Simplify the code (Rodrigo)

v7: rebased. Change order according to platforms(Jyoti)

v8: rebased. Change the check from platform specific to
HAS_PCH_SPLIT(). Add comment in code to be more clear.(Rodrigo)

Cc: Imre Deak <imre.deak@intel.com>
Cc: Rodrigo Vivi <rodrigo.vivi@intel.com>
Signed-off-by: Animesh Manna <animesh.manna@intel.com>
Signed-off-by: James Ausmus <james.ausmus@intel.com>
Signed-off-by: Anusha Srivatsa <anusha.srivatsa@intel.com>
Tested-by: Jyoti Yadav <jyoti.r.yadav@intel.com>
Reviewed-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
Signed-off-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20181029221410.4423-1-anusha.srivatsa@intel.com
drivers/gpu/drm/i915/i915_drv.c
drivers/gpu/drm/i915/intel_drv.h
drivers/gpu/drm/i915/intel_runtime_pm.c

index f6416b1d3452f88c05cc9a0fa0ff28fa24e957ed..198d625f287112949eab00dbd3354067c84548c9 100644 (file)
@@ -2152,7 +2152,7 @@ static int i915_drm_resume_early(struct drm_device *dev)
 
        intel_uncore_resume_early(dev_priv);
 
-       if (IS_GEN9_LP(dev_priv)) {
+       if (INTEL_GEN(dev_priv) >= 11 || IS_GEN9_LP(dev_priv)) {
                gen9_sanitize_dc_state(dev_priv);
                bxt_disable_dc9(dev_priv);
        } else if (IS_HASWELL(dev_priv) || IS_BROADWELL(dev_priv)) {
@@ -2919,7 +2919,10 @@ static int intel_runtime_suspend(struct device *kdev)
        intel_uncore_suspend(dev_priv);
 
        ret = 0;
-       if (IS_GEN9_LP(dev_priv)) {
+       if (INTEL_GEN(dev_priv) >= 11) {
+               icl_display_core_uninit(dev_priv);
+               bxt_enable_dc9(dev_priv);
+       } else if (IS_GEN9_LP(dev_priv)) {
                bxt_display_core_uninit(dev_priv);
                bxt_enable_dc9(dev_priv);
        } else if (IS_HASWELL(dev_priv) || IS_BROADWELL(dev_priv)) {
@@ -3004,7 +3007,18 @@ static int intel_runtime_resume(struct device *kdev)
        if (intel_uncore_unclaimed_mmio(dev_priv))
                DRM_DEBUG_DRIVER("Unclaimed access during suspend, bios?\n");
 
-       if (IS_GEN9_LP(dev_priv)) {
+       if (INTEL_GEN(dev_priv) >= 11) {
+               bxt_disable_dc9(dev_priv);
+               icl_display_core_init(dev_priv, true);
+               if (dev_priv->csr.dmc_payload) {
+                       if (dev_priv->csr.allowed_dc_mask &
+                           DC_STATE_EN_UPTO_DC6)
+                               skl_enable_dc6(dev_priv);
+                       else if (dev_priv->csr.allowed_dc_mask &
+                                DC_STATE_EN_UPTO_DC5)
+                               gen9_enable_dc5(dev_priv);
+               }
+       } else if (IS_GEN9_LP(dev_priv)) {
                bxt_disable_dc9(dev_priv);
                bxt_display_core_init(dev_priv, true);
                if (dev_priv->csr.dmc_payload &&
index 268afb6d2746337fb9c84d35d1c18a51aa397a56..e4eaa40bd5f1388728b0225b735811f4786e6cc9 100644 (file)
@@ -1695,6 +1695,7 @@ void bxt_enable_dc9(struct drm_i915_private *dev_priv);
 void bxt_disable_dc9(struct drm_i915_private *dev_priv);
 void gen9_enable_dc5(struct drm_i915_private *dev_priv);
 unsigned int skl_cdclk_get_vco(unsigned int freq);
+void skl_enable_dc6(struct drm_i915_private *dev_priv);
 void intel_dp_get_m_n(struct intel_crtc *crtc,
                      struct intel_crtc_state *pipe_config);
 void intel_dp_set_m_n(const struct intel_crtc_state *crtc_state,
@@ -2045,6 +2046,8 @@ int intel_power_domains_init(struct drm_i915_private *);
 void intel_power_domains_cleanup(struct drm_i915_private *dev_priv);
 void intel_power_domains_init_hw(struct drm_i915_private *dev_priv, bool resume);
 void intel_power_domains_fini_hw(struct drm_i915_private *dev_priv);
+void icl_display_core_init(struct drm_i915_private *dev_priv, bool resume);
+void icl_display_core_uninit(struct drm_i915_private *dev_priv);
 void intel_power_domains_enable(struct drm_i915_private *dev_priv);
 void intel_power_domains_disable(struct drm_i915_private *dev_priv);
 
index 5f5416eb9644cc7af3eef64db4fb5d2de9e25f79..b1901a6c17bec8661ab8a184cf38c6720d2479ac 100644 (file)
@@ -560,7 +560,9 @@ static u32 gen9_dc_mask(struct drm_i915_private *dev_priv)
        u32 mask;
 
        mask = DC_STATE_EN_UPTO_DC5;
-       if (IS_GEN9_LP(dev_priv))
+       if (INTEL_GEN(dev_priv) >= 11)
+               mask |= DC_STATE_EN_UPTO_DC6 | DC_STATE_EN_DC9;
+       else if (IS_GEN9_LP(dev_priv))
                mask |= DC_STATE_EN_DC9;
        else
                mask |= DC_STATE_EN_UPTO_DC6;
@@ -633,8 +635,13 @@ void bxt_enable_dc9(struct drm_i915_private *dev_priv)
        assert_can_enable_dc9(dev_priv);
 
        DRM_DEBUG_KMS("Enabling DC9\n");
-
-       intel_power_sequencer_reset(dev_priv);
+       /*
+        * Power sequencer reset is not needed on
+        * platforms with South Display Engine on PCH,
+        * because PPS registers are always on.
+        */
+       if (!HAS_PCH_SPLIT(dev_priv))
+               intel_power_sequencer_reset(dev_priv);
        gen9_set_dc_state(dev_priv, DC_STATE_EN_DC9);
 }
 
@@ -716,7 +723,7 @@ static void assert_can_enable_dc6(struct drm_i915_private *dev_priv)
        assert_csr_loaded(dev_priv);
 }
 
-static void skl_enable_dc6(struct drm_i915_private *dev_priv)
+void skl_enable_dc6(struct drm_i915_private *dev_priv)
 {
        assert_can_enable_dc6(dev_priv);
 
@@ -2978,17 +2985,20 @@ static uint32_t get_allowed_dc_mask(const struct drm_i915_private *dev_priv,
        int requested_dc;
        int max_dc;
 
-       if (IS_GEN9_BC(dev_priv) || INTEL_INFO(dev_priv)->gen >= 10) {
+       if (INTEL_GEN(dev_priv) >= 11) {
                max_dc = 2;
-               mask = 0;
-       } else if (IS_GEN9_LP(dev_priv)) {
-               max_dc = 1;
                /*
                 * DC9 has a separate HW flow from the rest of the DC states,
                 * not depending on the DMC firmware. It's needed by system
                 * suspend/resume, so allow it unconditionally.
                 */
                mask = DC_STATE_EN_DC9;
+       } else if (IS_GEN10(dev_priv) || IS_GEN9_BC(dev_priv)) {
+               max_dc = 2;
+               mask = 0;
+       } else if (IS_GEN9_LP(dev_priv)) {
+               max_dc = 1;
+               mask = DC_STATE_EN_DC9;
        } else {
                max_dc = 0;
                mask = 0;
@@ -3539,8 +3549,8 @@ static void cnl_display_core_uninit(struct drm_i915_private *dev_priv)
        I915_WRITE(CHICKEN_MISC_2, val);
 }
 
-static void icl_display_core_init(struct drm_i915_private *dev_priv,
-                                 bool resume)
+void icl_display_core_init(struct drm_i915_private *dev_priv,
+                          bool resume)
 {
        struct i915_power_domains *power_domains = &dev_priv->power_domains;
        struct i915_power_well *well;
@@ -3592,7 +3602,7 @@ static void icl_display_core_init(struct drm_i915_private *dev_priv,
                intel_csr_load_program(dev_priv);
 }
 
-static void icl_display_core_uninit(struct drm_i915_private *dev_priv)
+void icl_display_core_uninit(struct drm_i915_private *dev_priv)
 {
        struct i915_power_domains *power_domains = &dev_priv->power_domains;
        struct i915_power_well *well;