From 3e68928b7d4c833726717ced2261f77479d98a47 Mon Sep 17 00:00:00 2001
From: Animesh Manna <animesh.manna@intel.com>
Date: Mon, 29 Oct 2018 15:14:10 -0700
Subject: drm/i915/icl: Enable DC9 as lowest possible state during screen-off
Git-commit: 3e68928b7d4c833726717ced2261f77479d98a47
Patch-mainline: v5.0-rc1
References: fate#326289
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
Acked-by: Thomas Zimmermann <tzimmermann@suse.de>
---
drivers/gpu/drm/i915/i915_drv.c | 20 +++++++++++++++++---
drivers/gpu/drm/i915/intel_drv.h | 3 +++
drivers/gpu/drm/i915/intel_runtime_pm.c | 32 +++++++++++++++++++++-----------
3 files changed, 41 insertions(+), 14 deletions(-)
--- a/drivers/gpu/drm/i915/i915_drv.c
+++ b/drivers/gpu/drm/i915/i915_drv.c
@@ -1834,7 +1834,7 @@ static int i915_drm_resume_early(struct
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)) {
@@ -2609,7 +2609,10 @@ static int intel_runtime_suspend(struct
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)) {
@@ -2694,7 +2697,18 @@ static int intel_runtime_resume(struct d
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 &&
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -1621,6 +1621,7 @@ void bxt_enable_dc9(struct drm_i915_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(struct intel_crtc *crtc, enum link_m_n_set m_n);
@@ -1957,6 +1958,8 @@ void intel_power_domains_suspend(struct
void intel_power_domains_verify_state(struct drm_i915_private *dev_priv);
void bxt_display_core_init(struct drm_i915_private *dev_priv, bool resume);
void bxt_display_core_uninit(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_runtime_pm_enable(struct drm_i915_private *dev_priv);
const char *
intel_display_power_domain_str(enum intel_display_power_domain domain);
--- a/drivers/gpu/drm/i915/intel_runtime_pm.c
+++ b/drivers/gpu/drm/i915/intel_runtime_pm.c
@@ -585,7 +585,9 @@ static u32 gen9_dc_mask(struct drm_i915_
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;
@@ -658,8 +660,13 @@ void bxt_enable_dc9(struct drm_i915_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);
}
@@ -720,7 +727,7 @@ static void assert_can_enable_dc6(struct
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);
@@ -3010,17 +3017,20 @@ static uint32_t get_allowed_dc_mask(cons
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;
@@ -3568,8 +3578,8 @@ static void cnl_display_core_uninit(stru
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;
@@ -3623,7 +3633,7 @@ static void icl_display_core_init(struct
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;