static int intel_suspend_complete(struct drm_i915_private *dev_priv);
static int vlv_resume_prepare(struct drm_i915_private *dev_priv,
bool rpm_resume);
+static int skl_resume_prepare(struct drm_i915_private *dev_priv);
+
static int i915_drm_suspend(struct drm_device *dev)
{
if (IS_HASWELL(dev_priv) || IS_BROADWELL(dev_priv))
hsw_disable_pc8(dev_priv);
+ else if (IS_SKYLAKE(dev_priv))
+ ret = skl_resume_prepare(dev_priv);
intel_uncore_sanitize(dev);
intel_power_domains_init_hw(dev_priv);
return i915_drm_resume(drm_dev);
}
+static int skl_suspend_complete(struct drm_i915_private *dev_priv)
+{
+ /* Enabling DC6 is not a hard requirement to enter runtime D3 */
+
+ /*
+ * This is to ensure that CSR isn't identified as loaded before
+ * CSR-loading program is called during runtime-resume.
+ */
+ intel_csr_load_status_set(dev_priv, FW_UNINITIALIZED);
+
+ return 0;
+}
+
static int hsw_suspend_complete(struct drm_i915_private *dev_priv)
{
hsw_enable_pc8(dev_priv);
return 0;
}
+static int skl_resume_prepare(struct drm_i915_private *dev_priv)
+{
+ struct drm_device *dev = dev_priv->dev;
+
+ intel_csr_load_program(dev);
+
+ return 0;
+}
+
/*
* Save all Gunit registers that may be lost after a D3 and a subsequent
* S0i[R123] transition. The list of registers needing a save/restore is
if (IS_BROXTON(dev))
ret = bxt_resume_prepare(dev_priv);
+ else if (IS_SKYLAKE(dev))
+ ret = skl_resume_prepare(dev_priv);
else if (IS_HASWELL(dev_priv) || IS_BROADWELL(dev_priv))
hsw_disable_pc8(dev_priv);
else if (IS_VALLEYVIEW(dev_priv))
if (IS_BROXTON(dev))
ret = bxt_suspend_complete(dev_priv);
+ else if (IS_SKYLAKE(dev))
+ ret = skl_suspend_complete(dev_priv);
else if (IS_HASWELL(dev) || IS_BROADWELL(dev))
ret = hsw_suspend_complete(dev_priv);
else if (IS_VALLEYVIEW(dev))
* present for a given platform.
*/
-#define GEN9_ENABLE_DC5(dev) (IS_SKYLAKE(dev))
+#define GEN9_ENABLE_DC5(dev) 0
+#define SKL_ENABLE_DC6(dev) IS_SKYLAKE(dev)
#define for_each_power_well(i, power_well, domain_mask, power_domains) \
for (i = 0; \
POSTING_READ(DC_STATE_EN);
}
+static void skl_enable_dc6(struct drm_i915_private *dev_priv)
+{
+ /* TODO: Implementation to be done. */
+}
+
+static void skl_disable_dc6(struct drm_i915_private *dev_priv)
+{
+ /* TODO: Implementation to be done. */
+}
+
static void skl_set_power_well(struct drm_i915_private *dev_priv,
struct i915_power_well *power_well, bool enable)
{
!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) &&
- power_well->data == SKL_DISP_PW_2)
- gen9_disable_dc5(dev_priv);
+ if ((GEN9_ENABLE_DC5(dev) || SKL_ENABLE_DC6(dev)) &&
+ power_well->data == SKL_DISP_PW_2) {
+ 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.
+ * It's also invalid here as encoder list is still uninitialized.
+ */
+ 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);
}
POSTING_READ(HSW_PWR_WELL_DRIVER);
DRM_DEBUG_KMS("Disabling %s\n", power_well->name);
- if (GEN9_ENABLE_DC5(dev) &&
+ if ((GEN9_ENABLE_DC5(dev) || SKL_ENABLE_DC6(dev)) &&
power_well->data == SKL_DISP_PW_2) {
enum csr_state state;
-
+ /* 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)
DRM_ERROR("CSR firmware not ready (%d)\n",
state);
else
- gen9_enable_dc5(dev_priv);
+ if (SKL_ENABLE_DC6(dev))
+ skl_enable_dc6(dev_priv);
+ else
+ gen9_enable_dc5(dev_priv);
}
}
}