@@ -6794,6 +6794,17 @@ enum skl_disp_power_wells {
#define CSR_MMIO_END_RANGE 0x8FFFF
#define CSR_MAX_MMIO_COUNT 8
+/*
+* SKL DC
+*/
+#define DC_STATE_EN 0x45504
+#define DC_STATE_EN_UPTO_DC5 (1<<0)
+#define DC_STATE_EN_UPTO_DC6 (2<<0)
+#define DC_STATE_EN_UPTO_DC5_DC6_MASK 0x3
+
+#define DC_STATE_DEBUG 0x45520
+#define DC_STATE_DEBUG_MASK_MEMORY_UP (1<<1)
+
/* Please see hsw_read_dcomp() and hsw_write_dcomp() before using this register,
* since on HSW we can't write to it using I915_WRITE. */
#define D_COMP_HSW (MCHBAR_MIRROR_BASE_SNB + 0x5F0C)
@@ -319,6 +319,53 @@ static void hsw_set_power_well(struct drm_i915_private *dev_priv,
SKL_DISPLAY_MISC_IO_POWER_DOMAINS)) | \
BIT(POWER_DOMAIN_INIT))
+static void gen9_set_dc_state_debugmask_memory_up(
+ struct drm_i915_private *dev_priv)
+{
+ uint32_t val;
+
+ /* The below bit doesn't need to be cleared ever afterwards */
+ val = I915_READ(DC_STATE_DEBUG);
+ if (!(val & DC_STATE_DEBUG_MASK_MEMORY_UP)) {
+ val |= DC_STATE_DEBUG_MASK_MEMORY_UP;
+ I915_WRITE(DC_STATE_DEBUG, val);
+ POSTING_READ(DC_STATE_DEBUG);
+ }
+}
+
+static void gen9_enable_dc5(struct drm_i915_private *dev_priv)
+{
+ struct drm_device *dev = dev_priv->dev;
+ uint32_t val;
+
+ WARN_ON(!IS_GEN9(dev));
+
+ DRM_DEBUG_KMS("Enabling DC5\n");
+
+ gen9_set_dc_state_debugmask_memory_up(dev_priv);
+
+ val = I915_READ(DC_STATE_EN);
+ val &= ~DC_STATE_EN_UPTO_DC5_DC6_MASK;
+ val |= DC_STATE_EN_UPTO_DC5;
+ I915_WRITE(DC_STATE_EN, val);
+ POSTING_READ(DC_STATE_EN);
+}
+
+static void gen9_disable_dc5(struct drm_i915_private *dev_priv)
+{
+ struct drm_device *dev = dev_priv->dev;
+ uint32_t val;
+
+ WARN_ON(!IS_GEN9(dev));
+
+ DRM_DEBUG_KMS("Disabling DC5\n");
+
+ val = I915_READ(DC_STATE_EN);
+ val &= ~DC_STATE_EN_UPTO_DC5;
+ I915_WRITE(DC_STATE_EN, val);
+ POSTING_READ(DC_STATE_EN);
+}
+
static void skl_set_power_well(struct drm_i915_private *dev_priv,
struct i915_power_well *power_well, bool enable)
{