diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c index 760e0ce4aa26941c1ebd8d96706ccdbe3b7d7154..b1f1dec05274a97339f6541af63519862d86feb4 100644 --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c @@ -1053,10 +1053,20 @@ static int i915_pm_resume(struct device *dev) static int skl_suspend_complete(struct drm_i915_private *dev_priv) { + enum csr_state state; /* Enabling DC6 is not a hard requirement to enter runtime D3 */ skl_uninit_cdclk(dev_priv); + /* TODO: wait for a completion event or + * similar here instead of busy + * waiting using wait_for function. + */ + wait_for((state = intel_csr_load_status_get(dev_priv)) != + FW_UNINITIALIZED, 1000); + if (state == FW_LOADED) + skl_enable_dc6(dev_priv); + return 0; } @@ -1103,6 +1113,9 @@ static int skl_resume_prepare(struct drm_i915_private *dev_priv) { struct drm_device *dev = dev_priv->dev; + if (intel_csr_load_status_get(dev_priv) == FW_LOADED) + skl_disable_dc6(dev_priv); + skl_init_cdclk(dev_priv); intel_csr_load_program(dev); diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index 0598932ce6235b623df9ff6a62d74e100087f78e..d1d35c79edfdbecfaeacad1be53a1eaf8c9efd8e 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -1153,6 +1153,8 @@ void bxt_enable_dc9(struct drm_i915_private *dev_priv); void bxt_disable_dc9(struct drm_i915_private *dev_priv); void skl_init_cdclk(struct drm_i915_private *dev_priv); void skl_uninit_cdclk(struct drm_i915_private *dev_priv); +void skl_enable_dc6(struct drm_i915_private *dev_priv); +void skl_disable_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); diff --git a/drivers/gpu/drm/i915/intel_runtime_pm.c b/drivers/gpu/drm/i915/intel_runtime_pm.c index 0cfe4c14866a05f2ce031034878b5f0eedba1673..5892c0011421d7a2bb00728500a8bb0afa1dc18f 100644 --- a/drivers/gpu/drm/i915/intel_runtime_pm.c +++ b/drivers/gpu/drm/i915/intel_runtime_pm.c @@ -550,7 +550,7 @@ static void assert_can_disable_dc6(struct drm_i915_private *dev_priv) "DC6 already programmed to be disabled.\n"); } -static void skl_enable_dc6(struct drm_i915_private *dev_priv) +void skl_enable_dc6(struct drm_i915_private *dev_priv) { uint32_t val; @@ -567,7 +567,7 @@ static void skl_enable_dc6(struct drm_i915_private *dev_priv) POSTING_READ(DC_STATE_EN); } -static void skl_disable_dc6(struct drm_i915_private *dev_priv) +void skl_disable_dc6(struct drm_i915_private *dev_priv) { uint32_t val; @@ -628,10 +628,10 @@ static void skl_set_power_well(struct drm_i915_private *dev_priv, !I915_READ(HSW_PWR_WELL_BIOS), "Invalid for power well status to be enabled, unless done by the BIOS, \ when request is to disable!\n"); - if ((GEN9_ENABLE_DC5(dev) || SKL_ENABLE_DC6(dev)) && - power_well->data == SKL_DISP_PW_2) { + if (power_well->data == SKL_DISP_PW_2) { + if (GEN9_ENABLE_DC5(dev)) + gen9_disable_dc5(dev_priv); if (SKL_ENABLE_DC6(dev)) { - skl_disable_dc6(dev_priv); /* * DDI buffer programming unnecessary during driver-load/resume * as it's already done during modeset initialization then. @@ -639,8 +639,6 @@ static void skl_set_power_well(struct drm_i915_private *dev_priv, */ if (!dev_priv->power_domains.initializing) intel_prepare_ddi(dev); - } else { - gen9_disable_dc5(dev_priv); } } I915_WRITE(HSW_PWR_WELL_DRIVER, tmp | req_mask); @@ -666,7 +664,7 @@ static void skl_set_power_well(struct drm_i915_private *dev_priv, DRM_DEBUG_KMS("Disabling %s\n", power_well->name); } - if ((GEN9_ENABLE_DC5(dev) || SKL_ENABLE_DC6(dev)) && + if (GEN9_ENABLE_DC5(dev) && power_well->data == SKL_DISP_PW_2) { enum csr_state state; /* TODO: wait for a completion event or @@ -679,10 +677,7 @@ static void skl_set_power_well(struct drm_i915_private *dev_priv, DRM_DEBUG("CSR firmware not ready (%d)\n", state); else - if (SKL_ENABLE_DC6(dev)) - skl_enable_dc6(dev_priv); - else - gen9_enable_dc5(dev_priv); + gen9_enable_dc5(dev_priv); } } }