]> git.baikalelectronics.ru Git - kernel.git/commitdiff
drm/i915/ddi: Use power well CTL IDX instead of ID
authorImre Deak <imre.deak@intel.com>
Mon, 6 Aug 2018 09:58:39 +0000 (12:58 +0300)
committerImre Deak <imre.deak@intel.com>
Wed, 8 Aug 2018 10:51:19 +0000 (13:51 +0300)
Similarly to the previous patch use a separate request/status HW flag
index defined right after the corresponding control registers instead of
depending for this on the power well IDs. Since the set of
control/status registers varies among the different power wells (on a
single platform), also add a new i915_power_well_registers struct that
we populate and assign to each DDI power well as needed.

Also clarify a bit the code comment describing the function and layout
of the control registers.

This also fixes a problem on ICL, where we incorrectly read the KVMR
control register in hsw_power_well_requesters() even for DDI and AUX
power wells.

v2:
- Clarify platform range tags in code comments. (Paulo)
- Fix line over 80 chars checkpatch warning.

Cc: Ville Syrjala <ville.syrjala@linux.intel.com>
Cc: Paulo Zanoni <paulo.r.zanoni@intel.com>
Cc: Jani Nikula <jani.nikula@intel.com>
Signed-off-by: Imre Deak <imre.deak@intel.com>
Reviewed-by: Paulo Zanoni <paulo.r.zanoni@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20180806095843.13294-7-imre.deak@intel.com
drivers/gpu/drm/i915/gvt/handlers.c
drivers/gpu/drm/i915/i915_drv.h
drivers/gpu/drm/i915/i915_reg.h
drivers/gpu/drm/i915/intel_display.c
drivers/gpu/drm/i915/intel_runtime_pm.c

index 6b50f850dc283df67355cef90d980630cdf4356a..749c704ca3040500651806d8642c850f38a66be2 100644 (file)
@@ -1287,12 +1287,13 @@ static int power_well_ctl_mmio_write(struct intel_vgpu *vgpu,
 {
        write_vreg(vgpu, offset, p_data, bytes);
 
-       if (vgpu_vreg(vgpu, offset) & HSW_PWR_WELL_CTL_REQ(HSW_DISP_PW_GLOBAL))
+       if (vgpu_vreg(vgpu, offset) &
+           HSW_PWR_WELL_CTL_REQ(HSW_PW_CTL_IDX_GLOBAL))
                vgpu_vreg(vgpu, offset) |=
-                       HSW_PWR_WELL_CTL_STATE(HSW_DISP_PW_GLOBAL);
+                       HSW_PWR_WELL_CTL_STATE(HSW_PW_CTL_IDX_GLOBAL);
        else
                vgpu_vreg(vgpu, offset) &=
-                       ~HSW_PWR_WELL_CTL_STATE(HSW_DISP_PW_GLOBAL);
+                       ~HSW_PWR_WELL_CTL_STATE(HSW_PW_CTL_IDX_GLOBAL);
        return 0;
 }
 
@@ -2443,17 +2444,10 @@ static int init_generic_mmio_info(struct intel_gvt *gvt)
        MMIO_D(GEN6_RC6p_THRESHOLD, D_ALL);
        MMIO_D(GEN6_RC6pp_THRESHOLD, D_ALL);
        MMIO_D(GEN6_PMINTRMSK, D_ALL);
-       /*
-        * Use an arbitrary power well controlled by the PWR_WELL_CTL
-        * register.
-        */
-       MMIO_DH(HSW_PWR_WELL_CTL_BIOS(HSW_DISP_PW_GLOBAL), D_BDW, NULL,
-               power_well_ctl_mmio_write);
-       MMIO_DH(HSW_PWR_WELL_CTL_DRIVER(HSW_DISP_PW_GLOBAL), D_BDW, NULL,
-               power_well_ctl_mmio_write);
-       MMIO_DH(HSW_PWR_WELL_CTL_KVMR, D_BDW, NULL, power_well_ctl_mmio_write);
-       MMIO_DH(HSW_PWR_WELL_CTL_DEBUG(HSW_DISP_PW_GLOBAL), D_BDW, NULL,
-               power_well_ctl_mmio_write);
+       MMIO_DH(HSW_PWR_WELL_CTL1, D_BDW, NULL, power_well_ctl_mmio_write);
+       MMIO_DH(HSW_PWR_WELL_CTL2, D_BDW, NULL, power_well_ctl_mmio_write);
+       MMIO_DH(HSW_PWR_WELL_CTL3, D_BDW, NULL, power_well_ctl_mmio_write);
+       MMIO_DH(HSW_PWR_WELL_CTL4, D_BDW, NULL, power_well_ctl_mmio_write);
        MMIO_DH(HSW_PWR_WELL_CTL5, D_BDW, NULL, power_well_ctl_mmio_write);
        MMIO_DH(HSW_PWR_WELL_CTL6, D_BDW, NULL, power_well_ctl_mmio_write);
 
@@ -2804,13 +2798,8 @@ static int init_skl_mmio_info(struct intel_gvt *gvt)
        MMIO_F(_MMIO(_DPD_AUX_CH_CTL), 6 * 4, 0, 0, 0, D_SKL_PLUS, NULL,
                                                dp_aux_ch_ctl_mmio_write);
 
-       /*
-        * Use an arbitrary power well controlled by the PWR_WELL_CTL
-        * register.
-        */
-       MMIO_D(HSW_PWR_WELL_CTL_BIOS(SKL_DISP_PW_MISC_IO), D_SKL_PLUS);
-       MMIO_DH(HSW_PWR_WELL_CTL_DRIVER(SKL_DISP_PW_MISC_IO), D_SKL_PLUS, NULL,
-               skl_power_well_ctl_write);
+       MMIO_D(HSW_PWR_WELL_CTL1, D_SKL_PLUS);
+       MMIO_DH(HSW_PWR_WELL_CTL2, D_SKL_PLUS, NULL, skl_power_well_ctl_write);
 
        MMIO_D(_MMIO(0xa210), D_SKL_PLUS);
        MMIO_D(GEN9_MEDIA_PG_IDLE_HYSTERESIS, D_SKL_PLUS);
index 6fa61403d456e751db03d6773d807eb29afc28bc..0b10a30b7d96a2bb138a15daa0c6a8302cf39b2f 100644 (file)
@@ -867,6 +867,13 @@ struct i915_power_well_ops {
                           struct i915_power_well *power_well);
 };
 
+struct i915_power_well_regs {
+       i915_reg_t bios;
+       i915_reg_t driver;
+       i915_reg_t kvmr;
+       i915_reg_t debug;
+};
+
 /* Power well structure for haswell */
 struct i915_power_well_desc {
        const char *name;
@@ -890,6 +897,12 @@ struct i915_power_well_desc {
                        enum dpio_phy phy;
                } bxt;
                struct {
+                       const struct i915_power_well_regs *regs;
+                       /*
+                        * request/status flag index in the power well
+                        * constrol/status registers.
+                        */
+                       u8 idx;
                        /* Mask of pipes whose IRQ logic is backed by the pw */
                        u8 irq_pipe_mask;
                        /* The pw is backing the VGA functionality */
index ed30b4f8b948f1e9295f07288b9e9d1444d78574..4f5eb49934b4ff9889fb59923adcc399223384c3 100644 (file)
@@ -8925,46 +8925,78 @@ enum {
 #define HSW_AUD_CHICKENBIT                     _MMIO(0x65f10)
 #define   SKL_AUD_CODEC_WAKE_SIGNAL            (1 << 15)
 
-/* HSW Power Wells */
-#define _HSW_PWR_WELL_CTL1                     0x45400
-#define _HSW_PWR_WELL_CTL2                     0x45404
-#define _HSW_PWR_WELL_CTL3                     0x45408
-#define _HSW_PWR_WELL_CTL4                     0x4540C
-
-#define _ICL_PWR_WELL_CTL_AUX1                 0x45440
-#define _ICL_PWR_WELL_CTL_AUX2                 0x45444
-#define _ICL_PWR_WELL_CTL_AUX4                 0x4544C
-
-#define _ICL_PWR_WELL_CTL_DDI1                 0x45450
-#define _ICL_PWR_WELL_CTL_DDI2                 0x45454
-#define _ICL_PWR_WELL_CTL_DDI4                 0x4545C
-
 /*
- * Each power well control register contains up to 16 (request, status) HW
- * flag tuples. The register index and HW flag shift is determined by the
- * power well ID (see i915_power_well_id). There are 4 possible sources of
- * power well requests each source having its own set of control registers:
- * BIOS, DRIVER, KVMR, DEBUG.
+ * HSW - ICL power wells
+ *
+ * Platforms have up to 3 power well control register sets, each set
+ * controlling up to 16 power wells via a request/status HW flag tuple:
+ * - main (HSW_PWR_WELL_CTL[1-4])
+ * - AUX  (ICL_PWR_WELL_CTL_AUX[1-4])
+ * - DDI  (ICL_PWR_WELL_CTL_DDI[1-4])
+ * Each control register set consists of up to 4 registers used by different
+ * sources that can request a power well to be enabled:
+ * - BIOS   (HSW_PWR_WELL_CTL1/ICL_PWR_WELL_CTL_AUX1/ICL_PWR_WELL_CTL_DDI1)
+ * - DRIVER (HSW_PWR_WELL_CTL2/ICL_PWR_WELL_CTL_AUX2/ICL_PWR_WELL_CTL_DDI2)
+ * - KVMR   (HSW_PWR_WELL_CTL3)   (only in the main register set)
+ * - DEBUG  (HSW_PWR_WELL_CTL4/ICL_PWR_WELL_CTL_AUX4/ICL_PWR_WELL_CTL_DDI4)
  */
-#define _HSW_PW_REG_IDX(pw)                    ((pw) >> 4)
-#define _HSW_PW_SHIFT(pw)                      (((pw) & 0xf) * 2)
-#define HSW_PWR_WELL_CTL_BIOS(pw)      _MMIO(_PICK(_HSW_PW_REG_IDX(pw),       \
-                                                   _HSW_PWR_WELL_CTL1,        \
-                                                   _ICL_PWR_WELL_CTL_AUX1,    \
-                                                   _ICL_PWR_WELL_CTL_DDI1))
-#define HSW_PWR_WELL_CTL_DRIVER(pw)    _MMIO(_PICK(_HSW_PW_REG_IDX(pw),       \
-                                                   _HSW_PWR_WELL_CTL2,        \
-                                                   _ICL_PWR_WELL_CTL_AUX2,    \
-                                                   _ICL_PWR_WELL_CTL_DDI2))
-/* KVMR doesn't have a reg for AUX or DDI power well control */
-#define HSW_PWR_WELL_CTL_KVMR          _MMIO(_HSW_PWR_WELL_CTL3)
-#define HSW_PWR_WELL_CTL_DEBUG(pw)     _MMIO(_PICK(_HSW_PW_REG_IDX(pw),       \
-                                                   _HSW_PWR_WELL_CTL4,        \
-                                                   _ICL_PWR_WELL_CTL_AUX4,    \
-                                                   _ICL_PWR_WELL_CTL_DDI4))
-
-#define   HSW_PWR_WELL_CTL_REQ(pw)             (1 << (_HSW_PW_SHIFT(pw) + 1))
-#define   HSW_PWR_WELL_CTL_STATE(pw)           (1 << _HSW_PW_SHIFT(pw))
+#define HSW_PWR_WELL_CTL1                      _MMIO(0x45400)
+#define HSW_PWR_WELL_CTL2                      _MMIO(0x45404)
+#define HSW_PWR_WELL_CTL3                      _MMIO(0x45408)
+#define HSW_PWR_WELL_CTL4                      _MMIO(0x4540C)
+#define   HSW_PWR_WELL_CTL_REQ(pw_idx)         (0x2 << ((pw_idx) * 2))
+#define   HSW_PWR_WELL_CTL_STATE(pw_idx)       (0x1 << ((pw_idx) * 2))
+
+/* HSW/BDW power well */
+#define   HSW_PW_CTL_IDX_GLOBAL                        15
+
+/* SKL/BXT/GLK/CNL power wells */
+#define   SKL_PW_CTL_IDX_PW_2                  15
+#define   SKL_PW_CTL_IDX_PW_1                  14
+#define   CNL_PW_CTL_IDX_AUX_F                 12
+#define   CNL_PW_CTL_IDX_AUX_D                 11
+#define   GLK_PW_CTL_IDX_AUX_C                 10
+#define   GLK_PW_CTL_IDX_AUX_B                 9
+#define   GLK_PW_CTL_IDX_AUX_A                 8
+#define   CNL_PW_CTL_IDX_DDI_F                 6
+#define   SKL_PW_CTL_IDX_DDI_D                 4
+#define   SKL_PW_CTL_IDX_DDI_C                 3
+#define   SKL_PW_CTL_IDX_DDI_B                 2
+#define   SKL_PW_CTL_IDX_DDI_A_E               1
+#define   GLK_PW_CTL_IDX_DDI_A                 1
+#define   SKL_PW_CTL_IDX_MISC_IO               0
+
+/* ICL - power wells */
+#define   ICL_PW_CTL_IDX_PW_4                  3
+#define   ICL_PW_CTL_IDX_PW_3                  2
+#define   ICL_PW_CTL_IDX_PW_2                  1
+#define   ICL_PW_CTL_IDX_PW_1                  0
+
+#define ICL_PWR_WELL_CTL_AUX1                  _MMIO(0x45440)
+#define ICL_PWR_WELL_CTL_AUX2                  _MMIO(0x45444)
+#define ICL_PWR_WELL_CTL_AUX4                  _MMIO(0x4544C)
+#define   ICL_PW_CTL_IDX_AUX_TBT4              11
+#define   ICL_PW_CTL_IDX_AUX_TBT3              10
+#define   ICL_PW_CTL_IDX_AUX_TBT2              9
+#define   ICL_PW_CTL_IDX_AUX_TBT1              8
+#define   ICL_PW_CTL_IDX_AUX_F                 5
+#define   ICL_PW_CTL_IDX_AUX_E                 4
+#define   ICL_PW_CTL_IDX_AUX_D                 3
+#define   ICL_PW_CTL_IDX_AUX_C                 2
+#define   ICL_PW_CTL_IDX_AUX_B                 1
+#define   ICL_PW_CTL_IDX_AUX_A                 0
+
+#define ICL_PWR_WELL_CTL_DDI1                  _MMIO(0x45450)
+#define ICL_PWR_WELL_CTL_DDI2                  _MMIO(0x45454)
+#define ICL_PWR_WELL_CTL_DDI4                  _MMIO(0x4545C)
+#define   ICL_PW_CTL_IDX_DDI_F                 5
+#define   ICL_PW_CTL_IDX_DDI_E                 4
+#define   ICL_PW_CTL_IDX_DDI_D                 3
+#define   ICL_PW_CTL_IDX_DDI_C                 2
+#define   ICL_PW_CTL_IDX_DDI_B                 1
+#define   ICL_PW_CTL_IDX_DDI_A                 0
+
+/* HSW - power well misc debug registers */
 #define HSW_PWR_WELL_CTL5                      _MMIO(0x45410)
 #define   HSW_PWR_WELL_ENABLE_SINGLE_STEP      (1 << 31)
 #define   HSW_PWR_WELL_PWR_GATE_OVERRIDE       (1 << 20)
@@ -8980,18 +9012,26 @@ enum skl_power_gate {
 
 #define SKL_FUSE_STATUS                                _MMIO(0x42000)
 #define  SKL_FUSE_DOWNLOAD_STATUS              (1 << 31)
-/* PG0 (HW control->no power well ID), PG1..PG2 (SKL_DISP_PW1..SKL_DISP_PW2) */
-#define  SKL_PW_TO_PG(pw)                      ((pw) - SKL_DISP_PW_1 + SKL_PG1)
-/* PG0 (HW control->no power well ID), PG1..PG4 (ICL_DISP_PW1..ICL_DISP_PW4) */
-#define  ICL_PW_TO_PG(pw)                      ((pw) - ICL_DISP_PW_1 + SKL_PG1)
+/*
+ * PG0 is HW controlled, so doesn't have a corresponding power well control knob
+ * SKL_DISP_PW1_IDX..SKL_DISP_PW2_IDX -> PG1..PG2
+ */
+#define  SKL_PW_CTL_IDX_TO_PG(pw_idx)          \
+       ((pw_idx) - SKL_PW_CTL_IDX_PW_1 + SKL_PG1)
+/*
+ * PG0 is HW controlled, so doesn't have a corresponding power well control knob
+ * ICL_DISP_PW1_IDX..ICL_DISP_PW4_IDX -> PG1..PG4
+ */
+#define  ICL_PW_CTL_IDX_TO_PG(pw_idx)          \
+       ((pw_idx) - ICL_PW_CTL_IDX_PW_1 + SKL_PG1)
 #define  SKL_FUSE_PG_DIST_STATUS(pg)           (1 << (27 - (pg)))
 
-#define _CNL_AUX_REG_IDX(pw)           ((pw) - 9)
+#define _CNL_AUX_REG_IDX(pw_idx)       ((pw_idx) - GLK_PW_CTL_IDX_AUX_B)
 #define _CNL_AUX_ANAOVRD1_B            0x162250
 #define _CNL_AUX_ANAOVRD1_C            0x162210
 #define _CNL_AUX_ANAOVRD1_D            0x1622D0
 #define _CNL_AUX_ANAOVRD1_F            0x162A90
-#define CNL_AUX_ANAOVRD1(pw)           _MMIO(_PICK(_CNL_AUX_REG_IDX(pw), \
+#define CNL_AUX_ANAOVRD1(pw_idx)       _MMIO(_PICK(_CNL_AUX_REG_IDX(pw_idx), \
                                                    _CNL_AUX_ANAOVRD1_B, \
                                                    _CNL_AUX_ANAOVRD1_C, \
                                                    _CNL_AUX_ANAOVRD1_D, \
index 73c6d56ba3ec980c7a2d38c404d45c92c4f7c2f7..53e7a7e75384b278c8ab327dae0183475f85ad8c 100644 (file)
@@ -8973,7 +8973,7 @@ static void assert_can_disable_lcpll(struct drm_i915_private *dev_priv)
                I915_STATE_WARN(crtc->active, "CRTC for pipe %c enabled\n",
                     pipe_name(crtc->pipe));
 
-       I915_STATE_WARN(I915_READ(HSW_PWR_WELL_CTL_DRIVER(HSW_DISP_PW_GLOBAL)),
+       I915_STATE_WARN(I915_READ(HSW_PWR_WELL_CTL2),
                        "Display power well on\n");
        I915_STATE_WARN(I915_READ(SPLL_CTL) & SPLL_PLL_ENABLE, "SPLL enabled\n");
        I915_STATE_WARN(I915_READ(WRPLL_CTL(0)) & WRPLL_PLL_ENABLE, "WRPLL1 enabled\n");
@@ -16129,8 +16129,7 @@ intel_display_capture_error_state(struct drm_i915_private *dev_priv)
                return NULL;
 
        if (IS_HASWELL(dev_priv) || IS_BROADWELL(dev_priv))
-               error->power_well_driver =
-                       I915_READ(HSW_PWR_WELL_CTL_DRIVER(HSW_DISP_PW_GLOBAL));
+               error->power_well_driver = I915_READ(HSW_PWR_WELL_CTL2);
 
        for_each_pipe(dev_priv, i) {
                error->pipe[i].power_domain_on =
index bcdf04847b49e7923cb3af392a5a9d4372c48427..bba32df770b27d489fbfb47233762e6a81b4ce27 100644 (file)
@@ -323,26 +323,29 @@ static void hsw_power_well_pre_disable(struct drm_i915_private *dev_priv,
 static void hsw_wait_for_power_well_enable(struct drm_i915_private *dev_priv,
                                           struct i915_power_well *power_well)
 {
-       enum i915_power_well_id id = power_well->desc->id;
+       const struct i915_power_well_regs *regs = power_well->desc->hsw.regs;
+       int pw_idx = power_well->desc->hsw.idx;
 
        /* Timeout for PW1:10 us, AUX:not specified, other PWs:20 us. */
        WARN_ON(intel_wait_for_register(dev_priv,
-                                       HSW_PWR_WELL_CTL_DRIVER(id),
-                                       HSW_PWR_WELL_CTL_STATE(id),
-                                       HSW_PWR_WELL_CTL_STATE(id),
+                                       regs->driver,
+                                       HSW_PWR_WELL_CTL_STATE(pw_idx),
+                                       HSW_PWR_WELL_CTL_STATE(pw_idx),
                                        1));
 }
 
 static u32 hsw_power_well_requesters(struct drm_i915_private *dev_priv,
-                                    enum i915_power_well_id id)
+                                    const struct i915_power_well_regs *regs,
+                                    int pw_idx)
 {
-       u32 req_mask = HSW_PWR_WELL_CTL_REQ(id);
+       u32 req_mask = HSW_PWR_WELL_CTL_REQ(pw_idx);
        u32 ret;
 
-       ret = I915_READ(HSW_PWR_WELL_CTL_BIOS(id)) & req_mask ? 1 : 0;
-       ret |= I915_READ(HSW_PWR_WELL_CTL_DRIVER(id)) & req_mask ? 2 : 0;
-       ret |= I915_READ(HSW_PWR_WELL_CTL_KVMR) & req_mask ? 4 : 0;
-       ret |= I915_READ(HSW_PWR_WELL_CTL_DEBUG(id)) & req_mask ? 8 : 0;
+       ret = I915_READ(regs->bios) & req_mask ? 1 : 0;
+       ret |= I915_READ(regs->driver) & req_mask ? 2 : 0;
+       if (regs->kvmr.reg)
+               ret |= I915_READ(regs->kvmr) & req_mask ? 4 : 0;
+       ret |= I915_READ(regs->debug) & req_mask ? 8 : 0;
 
        return ret;
 }
@@ -350,7 +353,8 @@ static u32 hsw_power_well_requesters(struct drm_i915_private *dev_priv,
 static void hsw_wait_for_power_well_disable(struct drm_i915_private *dev_priv,
                                            struct i915_power_well *power_well)
 {
-       enum i915_power_well_id id = power_well->desc->id;
+       const struct i915_power_well_regs *regs = power_well->desc->hsw.regs;
+       int pw_idx = power_well->desc->hsw.idx;
        bool disabled;
        u32 reqs;
 
@@ -363,9 +367,9 @@ static void hsw_wait_for_power_well_disable(struct drm_i915_private *dev_priv,
         * Skip the wait in case any of the request bits are set and print a
         * diagnostic message.
         */
-       wait_for((disabled = !(I915_READ(HSW_PWR_WELL_CTL_DRIVER(id)) &
-                              HSW_PWR_WELL_CTL_STATE(id))) ||
-                (reqs = hsw_power_well_requesters(dev_priv, id)), 1);
+       wait_for((disabled = !(I915_READ(regs->driver) &
+                              HSW_PWR_WELL_CTL_STATE(pw_idx))) ||
+                (reqs = hsw_power_well_requesters(dev_priv, regs, pw_idx)), 1);
        if (disabled)
                return;
 
@@ -386,14 +390,15 @@ static void gen9_wait_for_power_well_fuses(struct drm_i915_private *dev_priv,
 static void hsw_power_well_enable(struct drm_i915_private *dev_priv,
                                  struct i915_power_well *power_well)
 {
-       enum i915_power_well_id id = power_well->desc->id;
+       const struct i915_power_well_regs *regs = power_well->desc->hsw.regs;
+       int pw_idx = power_well->desc->hsw.idx;
        bool wait_fuses = power_well->desc->hsw.has_fuses;
        enum skl_power_gate uninitialized_var(pg);
        u32 val;
 
        if (wait_fuses) {
-               pg = INTEL_GEN(dev_priv) >= 11 ? ICL_PW_TO_PG(id) :
-                                                SKL_PW_TO_PG(id);
+               pg = INTEL_GEN(dev_priv) >= 11 ? ICL_PW_CTL_IDX_TO_PG(pw_idx) :
+                                                SKL_PW_CTL_IDX_TO_PG(pw_idx);
                /*
                 * For PW1 we have to wait both for the PW0/PG0 fuse state
                 * before enabling the power well and PW1/PG1's own fuse
@@ -405,17 +410,17 @@ static void hsw_power_well_enable(struct drm_i915_private *dev_priv,
                        gen9_wait_for_power_well_fuses(dev_priv, SKL_PG0);
        }
 
-       val = I915_READ(HSW_PWR_WELL_CTL_DRIVER(id));
-       I915_WRITE(HSW_PWR_WELL_CTL_DRIVER(id), val | HSW_PWR_WELL_CTL_REQ(id));
+       val = I915_READ(regs->driver);
+       I915_WRITE(regs->driver, val | HSW_PWR_WELL_CTL_REQ(pw_idx));
        hsw_wait_for_power_well_enable(dev_priv, power_well);
 
        /* Display WA #1178: cnl */
        if (IS_CANNONLAKE(dev_priv) &&
-           (id == CNL_DISP_PW_AUX_B || id == CNL_DISP_PW_AUX_C ||
-            id == CNL_DISP_PW_AUX_D || id == CNL_DISP_PW_AUX_F)) {
-               val = I915_READ(CNL_AUX_ANAOVRD1(id));
+           pw_idx >= GLK_PW_CTL_IDX_AUX_B &&
+           pw_idx <= CNL_PW_CTL_IDX_AUX_F) {
+               val = I915_READ(CNL_AUX_ANAOVRD1(pw_idx));
                val |= CNL_AUX_ANAOVRD1_ENABLE | CNL_AUX_ANAOVRD1_LDO_BYPASS;
-               I915_WRITE(CNL_AUX_ANAOVRD1(id), val);
+               I915_WRITE(CNL_AUX_ANAOVRD1(pw_idx), val);
        }
 
        if (wait_fuses)
@@ -429,30 +434,31 @@ static void hsw_power_well_enable(struct drm_i915_private *dev_priv,
 static void hsw_power_well_disable(struct drm_i915_private *dev_priv,
                                   struct i915_power_well *power_well)
 {
-       enum i915_power_well_id id = power_well->desc->id;
+       const struct i915_power_well_regs *regs = power_well->desc->hsw.regs;
+       int pw_idx = power_well->desc->hsw.idx;
        u32 val;
 
        hsw_power_well_pre_disable(dev_priv,
                                   power_well->desc->hsw.irq_pipe_mask);
 
-       val = I915_READ(HSW_PWR_WELL_CTL_DRIVER(id));
-       I915_WRITE(HSW_PWR_WELL_CTL_DRIVER(id),
-                  val & ~HSW_PWR_WELL_CTL_REQ(id));
+       val = I915_READ(regs->driver);
+       I915_WRITE(regs->driver, val & ~HSW_PWR_WELL_CTL_REQ(pw_idx));
        hsw_wait_for_power_well_disable(dev_priv, power_well);
 }
 
-#define ICL_AUX_PW_TO_PORT(pw) ((pw) - ICL_DISP_PW_AUX_A)
+#define ICL_AUX_PW_TO_PORT(pw_idx)     ((pw_idx) - ICL_PW_CTL_IDX_AUX_A)
 
 static void
 icl_combo_phy_aux_power_well_enable(struct drm_i915_private *dev_priv,
                                    struct i915_power_well *power_well)
 {
-       enum i915_power_well_id id = power_well->desc->id;
-       enum port port = ICL_AUX_PW_TO_PORT(id);
+       const struct i915_power_well_regs *regs = power_well->desc->hsw.regs;
+       int pw_idx = power_well->desc->hsw.idx;
+       enum port port = ICL_AUX_PW_TO_PORT(pw_idx);
        u32 val;
 
-       val = I915_READ(HSW_PWR_WELL_CTL_DRIVER(id));
-       I915_WRITE(HSW_PWR_WELL_CTL_DRIVER(id), val | HSW_PWR_WELL_CTL_REQ(id));
+       val = I915_READ(regs->driver);
+       I915_WRITE(regs->driver, val | HSW_PWR_WELL_CTL_REQ(pw_idx));
 
        val = I915_READ(ICL_PORT_CL_DW12(port));
        I915_WRITE(ICL_PORT_CL_DW12(port), val | ICL_LANE_ENABLE_AUX);
@@ -464,16 +470,16 @@ static void
 icl_combo_phy_aux_power_well_disable(struct drm_i915_private *dev_priv,
                                     struct i915_power_well *power_well)
 {
-       enum i915_power_well_id id = power_well->desc->id;
-       enum port port = ICL_AUX_PW_TO_PORT(id);
+       const struct i915_power_well_regs *regs = power_well->desc->hsw.regs;
+       int pw_idx = power_well->desc->hsw.idx;
+       enum port port = ICL_AUX_PW_TO_PORT(pw_idx);
        u32 val;
 
        val = I915_READ(ICL_PORT_CL_DW12(port));
        I915_WRITE(ICL_PORT_CL_DW12(port), val & ~ICL_LANE_ENABLE_AUX);
 
-       val = I915_READ(HSW_PWR_WELL_CTL_DRIVER(id));
-       I915_WRITE(HSW_PWR_WELL_CTL_DRIVER(id),
-                  val & ~HSW_PWR_WELL_CTL_REQ(id));
+       val = I915_READ(regs->driver);
+       I915_WRITE(regs->driver, val & ~HSW_PWR_WELL_CTL_REQ(pw_idx));
 
        hsw_wait_for_power_well_disable(dev_priv, power_well);
 }
@@ -486,22 +492,22 @@ icl_combo_phy_aux_power_well_disable(struct drm_i915_private *dev_priv,
 static bool hsw_power_well_enabled(struct drm_i915_private *dev_priv,
                                   struct i915_power_well *power_well)
 {
-       enum i915_power_well_id id = power_well->desc->id;
-       u32 mask = HSW_PWR_WELL_CTL_REQ(id) | HSW_PWR_WELL_CTL_STATE(id);
+       const struct i915_power_well_regs *regs = power_well->desc->hsw.regs;
+       int pw_idx = power_well->desc->hsw.idx;
+       u32 mask = HSW_PWR_WELL_CTL_REQ(pw_idx) |
+                  HSW_PWR_WELL_CTL_STATE(pw_idx);
 
-       return (I915_READ(HSW_PWR_WELL_CTL_DRIVER(id)) & mask) == mask;
+       return (I915_READ(regs->driver) & mask) == mask;
 }
 
 static void assert_can_enable_dc9(struct drm_i915_private *dev_priv)
 {
-       enum i915_power_well_id id = SKL_DISP_PW_2;
-
        WARN_ONCE((I915_READ(DC_STATE_EN) & DC_STATE_EN_DC9),
                  "DC9 already programmed to be enabled.\n");
        WARN_ONCE(I915_READ(DC_STATE_EN) & DC_STATE_EN_UPTO_DC5,
                  "DC5 still not disabled to enable DC9.\n");
-       WARN_ONCE(I915_READ(HSW_PWR_WELL_CTL_DRIVER(id)) &
-                 HSW_PWR_WELL_CTL_REQ(id),
+       WARN_ONCE(I915_READ(HSW_PWR_WELL_CTL2) &
+                 HSW_PWR_WELL_CTL_REQ(SKL_PW_CTL_IDX_PW_2),
                  "Power well 2 on.\n");
        WARN_ONCE(intel_irqs_enabled(dev_priv),
                  "Interrupts not disabled yet.\n");
@@ -725,17 +731,18 @@ static void skl_enable_dc6(struct drm_i915_private *dev_priv)
 static void hsw_power_well_sync_hw(struct drm_i915_private *dev_priv,
                                   struct i915_power_well *power_well)
 {
-       enum i915_power_well_id id = power_well->desc->id;
-       u32 mask = HSW_PWR_WELL_CTL_REQ(id);
-       u32 bios_req = I915_READ(HSW_PWR_WELL_CTL_BIOS(id));
+       const struct i915_power_well_regs *regs = power_well->desc->hsw.regs;
+       int pw_idx = power_well->desc->hsw.idx;
+       u32 mask = HSW_PWR_WELL_CTL_REQ(pw_idx);
+       u32 bios_req = I915_READ(regs->bios);
 
        /* Take over the request bit if set by BIOS. */
        if (bios_req & mask) {
-               u32 drv_req = I915_READ(HSW_PWR_WELL_CTL_DRIVER(id));
+               u32 drv_req = I915_READ(regs->driver);
 
                if (!(drv_req & mask))
-                       I915_WRITE(HSW_PWR_WELL_CTL_DRIVER(id), drv_req | mask);
-               I915_WRITE(HSW_PWR_WELL_CTL_BIOS(id), bios_req & ~mask);
+                       I915_WRITE(regs->driver, drv_req | mask);
+               I915_WRITE(regs->bios, bios_req & ~mask);
        }
 }
 
@@ -2108,6 +2115,13 @@ static const struct i915_power_well_ops bxt_dpio_cmn_power_well_ops = {
        .is_enabled = bxt_dpio_cmn_power_well_enabled,
 };
 
+static const struct i915_power_well_regs hsw_power_well_regs = {
+       .bios   = HSW_PWR_WELL_CTL1,
+       .driver = HSW_PWR_WELL_CTL2,
+       .kvmr   = HSW_PWR_WELL_CTL3,
+       .debug  = HSW_PWR_WELL_CTL4,
+};
+
 static const struct i915_power_well_desc hsw_power_wells[] = {
        {
                .name = "always-on",
@@ -2122,6 +2136,8 @@ static const struct i915_power_well_desc hsw_power_wells[] = {
                .ops = &hsw_power_well_ops,
                .id = HSW_DISP_PW_GLOBAL,
                {
+                       .hsw.regs = &hsw_power_well_regs,
+                       .hsw.idx = HSW_PW_CTL_IDX_GLOBAL,
                        .hsw.has_vga = true,
                },
        },
@@ -2141,6 +2157,8 @@ static const struct i915_power_well_desc bdw_power_wells[] = {
                .ops = &hsw_power_well_ops,
                .id = HSW_DISP_PW_GLOBAL,
                {
+                       .hsw.regs = &hsw_power_well_regs,
+                       .hsw.idx = HSW_PW_CTL_IDX_GLOBAL,
                        .hsw.irq_pipe_mask = BIT(PIPE_B) | BIT(PIPE_C),
                        .hsw.has_vga = true,
                },
@@ -2310,6 +2328,8 @@ static const struct i915_power_well_desc skl_power_wells[] = {
                .ops = &hsw_power_well_ops,
                .id = SKL_DISP_PW_1,
                {
+                       .hsw.regs = &hsw_power_well_regs,
+                       .hsw.idx = SKL_PW_CTL_IDX_PW_1,
                        .hsw.has_fuses = true,
                },
        },
@@ -2319,6 +2339,10 @@ static const struct i915_power_well_desc skl_power_wells[] = {
                .domains = 0,
                .ops = &hsw_power_well_ops,
                .id = SKL_DISP_PW_MISC_IO,
+               {
+                       .hsw.regs = &hsw_power_well_regs,
+                       .hsw.idx = SKL_PW_CTL_IDX_MISC_IO,
+               },
        },
        {
                .name = "DC off",
@@ -2332,6 +2356,8 @@ static const struct i915_power_well_desc skl_power_wells[] = {
                .ops = &hsw_power_well_ops,
                .id = SKL_DISP_PW_2,
                {
+                       .hsw.regs = &hsw_power_well_regs,
+                       .hsw.idx = SKL_PW_CTL_IDX_PW_2,
                        .hsw.irq_pipe_mask = BIT(PIPE_B) | BIT(PIPE_C),
                        .hsw.has_vga = true,
                        .hsw.has_fuses = true,
@@ -2342,24 +2368,40 @@ static const struct i915_power_well_desc skl_power_wells[] = {
                .domains = SKL_DISPLAY_DDI_IO_A_E_POWER_DOMAINS,
                .ops = &hsw_power_well_ops,
                .id = SKL_DISP_PW_DDI_A_E,
+               {
+                       .hsw.regs = &hsw_power_well_regs,
+                       .hsw.idx = SKL_PW_CTL_IDX_DDI_A_E,
+               },
        },
        {
                .name = "DDI B IO power well",
                .domains = SKL_DISPLAY_DDI_IO_B_POWER_DOMAINS,
                .ops = &hsw_power_well_ops,
                .id = SKL_DISP_PW_DDI_B,
+               {
+                       .hsw.regs = &hsw_power_well_regs,
+                       .hsw.idx = SKL_PW_CTL_IDX_DDI_B,
+               },
        },
        {
                .name = "DDI C IO power well",
                .domains = SKL_DISPLAY_DDI_IO_C_POWER_DOMAINS,
                .ops = &hsw_power_well_ops,
                .id = SKL_DISP_PW_DDI_C,
+               {
+                       .hsw.regs = &hsw_power_well_regs,
+                       .hsw.idx = SKL_PW_CTL_IDX_DDI_C,
+               },
        },
        {
                .name = "DDI D IO power well",
                .domains = SKL_DISPLAY_DDI_IO_D_POWER_DOMAINS,
                .ops = &hsw_power_well_ops,
                .id = SKL_DISP_PW_DDI_D,
+               {
+                       .hsw.regs = &hsw_power_well_regs,
+                       .hsw.idx = SKL_PW_CTL_IDX_DDI_D,
+               },
        },
 };
 
@@ -2377,6 +2419,8 @@ static const struct i915_power_well_desc bxt_power_wells[] = {
                .ops = &hsw_power_well_ops,
                .id = SKL_DISP_PW_1,
                {
+                       .hsw.regs = &hsw_power_well_regs,
+                       .hsw.idx = SKL_PW_CTL_IDX_PW_1,
                        .hsw.has_fuses = true,
                },
        },
@@ -2392,6 +2436,8 @@ static const struct i915_power_well_desc bxt_power_wells[] = {
                .ops = &hsw_power_well_ops,
                .id = SKL_DISP_PW_2,
                {
+                       .hsw.regs = &hsw_power_well_regs,
+                       .hsw.idx = SKL_PW_CTL_IDX_PW_2,
                        .hsw.irq_pipe_mask = BIT(PIPE_B) | BIT(PIPE_C),
                        .hsw.has_vga = true,
                        .hsw.has_fuses = true,
@@ -2432,6 +2478,8 @@ static const struct i915_power_well_desc glk_power_wells[] = {
                .ops = &hsw_power_well_ops,
                .id = SKL_DISP_PW_1,
                {
+                       .hsw.regs = &hsw_power_well_regs,
+                       .hsw.idx = SKL_PW_CTL_IDX_PW_1,
                        .hsw.has_fuses = true,
                },
        },
@@ -2447,6 +2495,8 @@ static const struct i915_power_well_desc glk_power_wells[] = {
                .ops = &hsw_power_well_ops,
                .id = SKL_DISP_PW_2,
                {
+                       .hsw.regs = &hsw_power_well_regs,
+                       .hsw.idx = SKL_PW_CTL_IDX_PW_2,
                        .hsw.irq_pipe_mask = BIT(PIPE_B) | BIT(PIPE_C),
                        .hsw.has_vga = true,
                        .hsw.has_fuses = true,
@@ -2484,36 +2534,60 @@ static const struct i915_power_well_desc glk_power_wells[] = {
                .domains = GLK_DISPLAY_AUX_A_POWER_DOMAINS,
                .ops = &hsw_power_well_ops,
                .id = GLK_DISP_PW_AUX_A,
+               {
+                       .hsw.regs = &hsw_power_well_regs,
+                       .hsw.idx = GLK_PW_CTL_IDX_AUX_A,
+               },
        },
        {
                .name = "AUX B",
                .domains = GLK_DISPLAY_AUX_B_POWER_DOMAINS,
                .ops = &hsw_power_well_ops,
                .id = GLK_DISP_PW_AUX_B,
+               {
+                       .hsw.regs = &hsw_power_well_regs,
+                       .hsw.idx = GLK_PW_CTL_IDX_AUX_B,
+               },
        },
        {
                .name = "AUX C",
                .domains = GLK_DISPLAY_AUX_C_POWER_DOMAINS,
                .ops = &hsw_power_well_ops,
                .id = GLK_DISP_PW_AUX_C,
+               {
+                       .hsw.regs = &hsw_power_well_regs,
+                       .hsw.idx = GLK_PW_CTL_IDX_AUX_C,
+               },
        },
        {
                .name = "DDI A IO power well",
                .domains = GLK_DISPLAY_DDI_IO_A_POWER_DOMAINS,
                .ops = &hsw_power_well_ops,
                .id = GLK_DISP_PW_DDI_A,
+               {
+                       .hsw.regs = &hsw_power_well_regs,
+                       .hsw.idx = GLK_PW_CTL_IDX_DDI_A,
+               },
        },
        {
                .name = "DDI B IO power well",
                .domains = GLK_DISPLAY_DDI_IO_B_POWER_DOMAINS,
                .ops = &hsw_power_well_ops,
                .id = SKL_DISP_PW_DDI_B,
+               {
+                       .hsw.regs = &hsw_power_well_regs,
+                       .hsw.idx = SKL_PW_CTL_IDX_DDI_B,
+               },
        },
        {
                .name = "DDI C IO power well",
                .domains = GLK_DISPLAY_DDI_IO_C_POWER_DOMAINS,
                .ops = &hsw_power_well_ops,
                .id = SKL_DISP_PW_DDI_C,
+               {
+                       .hsw.regs = &hsw_power_well_regs,
+                       .hsw.idx = SKL_PW_CTL_IDX_DDI_C,
+               },
        },
 };
 
@@ -2532,6 +2606,8 @@ static const struct i915_power_well_desc cnl_power_wells[] = {
                .ops = &hsw_power_well_ops,
                .id = SKL_DISP_PW_1,
                {
+                       .hsw.regs = &hsw_power_well_regs,
+                       .hsw.idx = SKL_PW_CTL_IDX_PW_1,
                        .hsw.has_fuses = true,
                },
        },
@@ -2540,24 +2616,40 @@ static const struct i915_power_well_desc cnl_power_wells[] = {
                .domains = CNL_DISPLAY_AUX_A_POWER_DOMAINS,
                .ops = &hsw_power_well_ops,
                .id = CNL_DISP_PW_AUX_A,
+               {
+                       .hsw.regs = &hsw_power_well_regs,
+                       .hsw.idx = GLK_PW_CTL_IDX_AUX_A,
+               },
        },
        {
                .name = "AUX B",
                .domains = CNL_DISPLAY_AUX_B_POWER_DOMAINS,
                .ops = &hsw_power_well_ops,
                .id = CNL_DISP_PW_AUX_B,
+               {
+                       .hsw.regs = &hsw_power_well_regs,
+                       .hsw.idx = GLK_PW_CTL_IDX_AUX_B,
+               },
        },
        {
                .name = "AUX C",
                .domains = CNL_DISPLAY_AUX_C_POWER_DOMAINS,
                .ops = &hsw_power_well_ops,
                .id = CNL_DISP_PW_AUX_C,
+               {
+                       .hsw.regs = &hsw_power_well_regs,
+                       .hsw.idx = GLK_PW_CTL_IDX_AUX_C,
+               },
        },
        {
                .name = "AUX D",
                .domains = CNL_DISPLAY_AUX_D_POWER_DOMAINS,
                .ops = &hsw_power_well_ops,
                .id = CNL_DISP_PW_AUX_D,
+               {
+                       .hsw.regs = &hsw_power_well_regs,
+                       .hsw.idx = CNL_PW_CTL_IDX_AUX_D,
+               },
        },
        {
                .name = "DC off",
@@ -2571,6 +2663,8 @@ static const struct i915_power_well_desc cnl_power_wells[] = {
                .ops = &hsw_power_well_ops,
                .id = SKL_DISP_PW_2,
                {
+                       .hsw.regs = &hsw_power_well_regs,
+                       .hsw.idx = SKL_PW_CTL_IDX_PW_2,
                        .hsw.irq_pipe_mask = BIT(PIPE_B) | BIT(PIPE_C),
                        .hsw.has_vga = true,
                        .hsw.has_fuses = true,
@@ -2581,36 +2675,60 @@ static const struct i915_power_well_desc cnl_power_wells[] = {
                .domains = CNL_DISPLAY_DDI_A_IO_POWER_DOMAINS,
                .ops = &hsw_power_well_ops,
                .id = CNL_DISP_PW_DDI_A,
+               {
+                       .hsw.regs = &hsw_power_well_regs,
+                       .hsw.idx = GLK_PW_CTL_IDX_DDI_A,
+               },
        },
        {
                .name = "DDI B IO power well",
                .domains = CNL_DISPLAY_DDI_B_IO_POWER_DOMAINS,
                .ops = &hsw_power_well_ops,
                .id = SKL_DISP_PW_DDI_B,
+               {
+                       .hsw.regs = &hsw_power_well_regs,
+                       .hsw.idx = SKL_PW_CTL_IDX_DDI_B,
+               },
        },
        {
                .name = "DDI C IO power well",
                .domains = CNL_DISPLAY_DDI_C_IO_POWER_DOMAINS,
                .ops = &hsw_power_well_ops,
                .id = SKL_DISP_PW_DDI_C,
+               {
+                       .hsw.regs = &hsw_power_well_regs,
+                       .hsw.idx = SKL_PW_CTL_IDX_DDI_C,
+               },
        },
        {
                .name = "DDI D IO power well",
                .domains = CNL_DISPLAY_DDI_D_IO_POWER_DOMAINS,
                .ops = &hsw_power_well_ops,
                .id = SKL_DISP_PW_DDI_D,
+               {
+                       .hsw.regs = &hsw_power_well_regs,
+                       .hsw.idx = SKL_PW_CTL_IDX_DDI_D,
+               },
        },
        {
                .name = "DDI F IO power well",
                .domains = CNL_DISPLAY_DDI_F_IO_POWER_DOMAINS,
                .ops = &hsw_power_well_ops,
                .id = CNL_DISP_PW_DDI_F,
+               {
+                       .hsw.regs = &hsw_power_well_regs,
+                       .hsw.idx = CNL_PW_CTL_IDX_DDI_F,
+               },
        },
        {
                .name = "AUX F",
                .domains = CNL_DISPLAY_AUX_F_POWER_DOMAINS,
                .ops = &hsw_power_well_ops,
                .id = CNL_DISP_PW_AUX_F,
+               {
+                       .hsw.regs = &hsw_power_well_regs,
+                       .hsw.idx = CNL_PW_CTL_IDX_AUX_F,
+               },
        },
 };
 
@@ -2621,6 +2739,18 @@ static const struct i915_power_well_ops icl_combo_phy_aux_power_well_ops = {
        .is_enabled = hsw_power_well_enabled,
 };
 
+static const struct i915_power_well_regs icl_aux_power_well_regs = {
+       .bios   = ICL_PWR_WELL_CTL_AUX1,
+       .driver = ICL_PWR_WELL_CTL_AUX2,
+       .debug  = ICL_PWR_WELL_CTL_AUX4,
+};
+
+static const struct i915_power_well_regs icl_ddi_power_well_regs = {
+       .bios   = ICL_PWR_WELL_CTL_DDI1,
+       .driver = ICL_PWR_WELL_CTL_DDI2,
+       .debug  = ICL_PWR_WELL_CTL_DDI4,
+};
+
 static const struct i915_power_well_desc icl_power_wells[] = {
        {
                .name = "always-on",
@@ -2636,6 +2766,8 @@ static const struct i915_power_well_desc icl_power_wells[] = {
                .ops = &hsw_power_well_ops,
                .id = ICL_DISP_PW_1,
                {
+                       .hsw.regs = &hsw_power_well_regs,
+                       .hsw.idx = ICL_PW_CTL_IDX_PW_1,
                        .hsw.has_fuses = true,
                },
        },
@@ -2645,6 +2777,8 @@ static const struct i915_power_well_desc icl_power_wells[] = {
                .ops = &hsw_power_well_ops,
                .id = ICL_DISP_PW_2,
                {
+                       .hsw.regs = &hsw_power_well_regs,
+                       .hsw.idx = ICL_PW_CTL_IDX_PW_2,
                        .hsw.has_fuses = true,
                },
        },
@@ -2660,6 +2794,8 @@ static const struct i915_power_well_desc icl_power_wells[] = {
                .ops = &hsw_power_well_ops,
                .id = ICL_DISP_PW_3,
                {
+                       .hsw.regs = &hsw_power_well_regs,
+                       .hsw.idx = ICL_PW_CTL_IDX_PW_3,
                        .hsw.irq_pipe_mask = BIT(PIPE_B),
                        .hsw.has_vga = true,
                        .hsw.has_fuses = true,
@@ -2670,96 +2806,160 @@ static const struct i915_power_well_desc icl_power_wells[] = {
                .domains = ICL_DDI_IO_A_POWER_DOMAINS,
                .ops = &hsw_power_well_ops,
                .id = ICL_DISP_PW_DDI_A,
+               {
+                       .hsw.regs = &icl_ddi_power_well_regs,
+                       .hsw.idx = ICL_PW_CTL_IDX_DDI_A,
+               },
        },
        {
                .name = "DDI B IO",
                .domains = ICL_DDI_IO_B_POWER_DOMAINS,
                .ops = &hsw_power_well_ops,
                .id = ICL_DISP_PW_DDI_B,
+               {
+                       .hsw.regs = &icl_ddi_power_well_regs,
+                       .hsw.idx = ICL_PW_CTL_IDX_DDI_B,
+               },
        },
        {
                .name = "DDI C IO",
                .domains = ICL_DDI_IO_C_POWER_DOMAINS,
                .ops = &hsw_power_well_ops,
                .id = ICL_DISP_PW_DDI_C,
+               {
+                       .hsw.regs = &icl_ddi_power_well_regs,
+                       .hsw.idx = ICL_PW_CTL_IDX_DDI_C,
+               },
        },
        {
                .name = "DDI D IO",
                .domains = ICL_DDI_IO_D_POWER_DOMAINS,
                .ops = &hsw_power_well_ops,
                .id = ICL_DISP_PW_DDI_D,
+               {
+                       .hsw.regs = &icl_ddi_power_well_regs,
+                       .hsw.idx = ICL_PW_CTL_IDX_DDI_D,
+               },
        },
        {
                .name = "DDI E IO",
                .domains = ICL_DDI_IO_E_POWER_DOMAINS,
                .ops = &hsw_power_well_ops,
                .id = ICL_DISP_PW_DDI_E,
+               {
+                       .hsw.regs = &icl_ddi_power_well_regs,
+                       .hsw.idx = ICL_PW_CTL_IDX_DDI_E,
+               },
        },
        {
                .name = "DDI F IO",
                .domains = ICL_DDI_IO_F_POWER_DOMAINS,
                .ops = &hsw_power_well_ops,
                .id = ICL_DISP_PW_DDI_F,
+               {
+                       .hsw.regs = &icl_ddi_power_well_regs,
+                       .hsw.idx = ICL_PW_CTL_IDX_DDI_F,
+               },
        },
        {
                .name = "AUX A",
                .domains = ICL_AUX_A_IO_POWER_DOMAINS,
                .ops = &icl_combo_phy_aux_power_well_ops,
                .id = ICL_DISP_PW_AUX_A,
+               {
+                       .hsw.regs = &icl_aux_power_well_regs,
+                       .hsw.idx = ICL_PW_CTL_IDX_AUX_A,
+               },
        },
        {
                .name = "AUX B",
                .domains = ICL_AUX_B_IO_POWER_DOMAINS,
                .ops = &icl_combo_phy_aux_power_well_ops,
                .id = ICL_DISP_PW_AUX_B,
+               {
+                       .hsw.regs = &icl_aux_power_well_regs,
+                       .hsw.idx = ICL_PW_CTL_IDX_AUX_B,
+               },
        },
        {
                .name = "AUX C",
                .domains = ICL_AUX_C_IO_POWER_DOMAINS,
                .ops = &hsw_power_well_ops,
                .id = ICL_DISP_PW_AUX_C,
+               {
+                       .hsw.regs = &icl_aux_power_well_regs,
+                       .hsw.idx = ICL_PW_CTL_IDX_AUX_C,
+               },
        },
        {
                .name = "AUX D",
                .domains = ICL_AUX_D_IO_POWER_DOMAINS,
                .ops = &hsw_power_well_ops,
                .id = ICL_DISP_PW_AUX_D,
+               {
+                       .hsw.regs = &icl_aux_power_well_regs,
+                       .hsw.idx = ICL_PW_CTL_IDX_AUX_D,
+               },
        },
        {
                .name = "AUX E",
                .domains = ICL_AUX_E_IO_POWER_DOMAINS,
                .ops = &hsw_power_well_ops,
                .id = ICL_DISP_PW_AUX_E,
+               {
+                       .hsw.regs = &icl_aux_power_well_regs,
+                       .hsw.idx = ICL_PW_CTL_IDX_AUX_E,
+               },
        },
        {
                .name = "AUX F",
                .domains = ICL_AUX_F_IO_POWER_DOMAINS,
                .ops = &hsw_power_well_ops,
                .id = ICL_DISP_PW_AUX_F,
+               {
+                       .hsw.regs = &icl_aux_power_well_regs,
+                       .hsw.idx = ICL_PW_CTL_IDX_AUX_F,
+               },
        },
        {
                .name = "AUX TBT1",
                .domains = ICL_AUX_TBT1_IO_POWER_DOMAINS,
                .ops = &hsw_power_well_ops,
                .id = ICL_DISP_PW_AUX_TBT1,
+               {
+                       .hsw.regs = &icl_aux_power_well_regs,
+                       .hsw.idx = ICL_PW_CTL_IDX_AUX_TBT1,
+               },
        },
        {
                .name = "AUX TBT2",
                .domains = ICL_AUX_TBT2_IO_POWER_DOMAINS,
                .ops = &hsw_power_well_ops,
                .id = ICL_DISP_PW_AUX_TBT2,
+               {
+                       .hsw.regs = &icl_aux_power_well_regs,
+                       .hsw.idx = ICL_PW_CTL_IDX_AUX_TBT2,
+               },
        },
        {
                .name = "AUX TBT3",
                .domains = ICL_AUX_TBT3_IO_POWER_DOMAINS,
                .ops = &hsw_power_well_ops,
                .id = ICL_DISP_PW_AUX_TBT3,
+               {
+                       .hsw.regs = &icl_aux_power_well_regs,
+                       .hsw.idx = ICL_PW_CTL_IDX_AUX_TBT3,
+               },
        },
        {
                .name = "AUX TBT4",
                .domains = ICL_AUX_TBT4_IO_POWER_DOMAINS,
                .ops = &hsw_power_well_ops,
                .id = ICL_DISP_PW_AUX_TBT4,
+               {
+                       .hsw.regs = &icl_aux_power_well_regs,
+                       .hsw.idx = ICL_PW_CTL_IDX_AUX_TBT4,
+               },
        },
        {
                .name = "power well 4",
@@ -2767,6 +2967,8 @@ static const struct i915_power_well_desc icl_power_wells[] = {
                .ops = &hsw_power_well_ops,
                .id = ICL_DISP_PW_4,
                {
+                       .hsw.regs = &hsw_power_well_regs,
+                       .hsw.idx = ICL_PW_CTL_IDX_PW_4,
                        .hsw.has_fuses = true,
                        .hsw.irq_pipe_mask = BIT(PIPE_C),
                },