diff mbox

[06/10] drm/i915/ddi: Use power well CTL IDX instead of ID

Message ID 20180720141504.22832-7-imre.deak@intel.com (mailing list archive)
State New, archived
Headers show

Commit Message

Imre Deak July 20, 2018, 2:15 p.m. UTC
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.

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>
---
 drivers/gpu/drm/i915/gvt/handlers.c     |  30 +---
 drivers/gpu/drm/i915/i915_drv.h         |  13 ++
 drivers/gpu/drm/i915/i915_reg.h         | 126 ++++++++-----
 drivers/gpu/drm/i915/intel_display.c    |   5 +-
 drivers/gpu/drm/i915/intel_runtime_pm.c | 302 ++++++++++++++++++++++++++------
 5 files changed, 359 insertions(+), 117 deletions(-)

Comments

Zanoni, Paulo R Aug. 2, 2018, 8:40 p.m. UTC | #1
Em Sex, 2018-07-20 às 17:15 +0300, Imre Deak escreveu:
> 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.
> 
> 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>
> ---
>  drivers/gpu/drm/i915/gvt/handlers.c     |  30 +---
>  drivers/gpu/drm/i915/i915_drv.h         |  13 ++
>  drivers/gpu/drm/i915/i915_reg.h         | 126 ++++++++-----
>  drivers/gpu/drm/i915/intel_display.c    |   5 +-
>  drivers/gpu/drm/i915/intel_runtime_pm.c | 302
> ++++++++++++++++++++++++++------
>  5 files changed, 359 insertions(+), 117 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/gvt/handlers.c
> b/drivers/gpu/drm/i915/gvt/handlers.c
> index 7a58ca555197..79e748569d31 100644
> --- a/drivers/gpu/drm/i915/gvt/handlers.c
> +++ b/drivers/gpu/drm/i915/gvt/handlers.c
> @@ -1287,12 +1287,12 @@ 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_GLOBA
> L);
>  	return 0;
>  }
>  
> @@ -2443,17 +2443,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 +2797,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_w
> rite);
>  
> -	/*
> -	 * 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);
> diff --git a/drivers/gpu/drm/i915/i915_drv.h
> b/drivers/gpu/drm/i915/i915_drv.h
> index d31a8ef05d18..d73ce0a7b8f7 100644
> --- a/drivers/gpu/drm/i915/i915_drv.h
> +++ b/drivers/gpu/drm/i915/i915_drv.h
> @@ -861,6 +861,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;
> @@ -884,6 +891,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
> */
> diff --git a/drivers/gpu/drm/i915/i915_reg.h
> b/drivers/gpu/drm/i915/i915_reg.h
> index f76bb4f3c944..b7022fb8d524 100644
> --- a/drivers/gpu/drm/i915/i915_reg.h
> +++ b/drivers/gpu/drm/i915/i915_reg.h
> @@ -8842,46 +8842,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_CT
> L1,	       \
> -						    _ICL_PWR_WELL_CT
> L_AUX1,    \
> -						    _ICL_PWR_WELL_CT
> L_DDI1))
> -#define HSW_PWR_WELL_CTL_DRIVER(pw)	_MMIO(_PICK(_HSW_PW_REG_I
> DX(pw),       \
> -						    _HSW_PWR_WELL_CT
> L2,	       \
> -						    _ICL_PWR_WELL_CT
> L_AUX2,    \
> -						    _ICL_PWR_WELL_CT
> L_DDI2))
> -/* KVMR doesn't have a reg for AUX or DDI power well control */
> -#define HSW_PWR_WELL_CTL_KVMR		_MMIO(_HSW_PWR_WELL_CTL
> 3)
> -#define HSW_PWR_WELL_CTL_DEBUG(pw)	_MMIO(_PICK(_HSW_PW_REG_ID
> X(pw),       \
> -						    _HSW_PWR_WELL_CT
> L4,	       \
> -						    _ICL_PWR_WELL_CT
> L_AUX4,    \
> -						    _ICL_PWR_WELL_CT
> L_DDI4))
> +#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))
>  
> -#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))
> +/* 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 */

Single nitpick for a big patch: my OCD tells me to put a space before
'-' or remove it completely because "ICL-" as is can be read as "ICL
and older" to the distracted reader.

Reviewed-by: Paulo Zanoni <paulo.r.zanoni@intel.com>


> +#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)
> @@ -8897,18 +8929,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_ANAOVRD
> 1_B, \
>  						    _CNL_AUX_ANAOVRD
> 1_C, \
>  						    _CNL_AUX_ANAOVRD
> 1_D, \
> diff --git a/drivers/gpu/drm/i915/intel_display.c
> b/drivers/gpu/drm/i915/intel_display.c
> index 87e4cfbfd096..640ec5df4d62 100644
> --- a/drivers/gpu/drm/i915/intel_display.c
> +++ b/drivers/gpu/drm/i915/intel_display.c
> @@ -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_P
> W_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");
> @@ -16052,8 +16052,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_P
> W_GLOBAL));
> +		error->power_well_driver =
> I915_READ(HSW_PWR_WELL_CTL2);
>  
>  	for_each_pipe(dev_priv, i) {
>  		error->pipe[i].power_domain_on =
> diff --git a/drivers/gpu/drm/i915/intel_runtime_pm.c
> b/drivers/gpu/drm/i915/intel_runtime_pm.c
> index 05d8cdab08cc..5527504d664f 100644
> --- a/drivers/gpu/drm/i915/intel_runtime_pm.c
> +++ b/drivers/gpu/drm/i915/intel_runtime_pm.c
> @@ -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_id
> x),
> +					HSW_PWR_WELL_CTL_STATE(pw_id
> x),
>  					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_P
> G(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),
>  		},
Imre Deak Aug. 3, 2018, 9:13 a.m. UTC | #2
On Thu, Aug 02, 2018 at 01:40:55PM -0700, Paulo Zanoni wrote:
> Em Sex, 2018-07-20 às 17:15 +0300, Imre Deak escreveu:
> > 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.
> > 
> > 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>
> > ---
> >  drivers/gpu/drm/i915/gvt/handlers.c     |  30 +---
> >  drivers/gpu/drm/i915/i915_drv.h         |  13 ++
> >  drivers/gpu/drm/i915/i915_reg.h         | 126 ++++++++-----
> >  drivers/gpu/drm/i915/intel_display.c    |   5 +-
> >  drivers/gpu/drm/i915/intel_runtime_pm.c | 302
> > ++++++++++++++++++++++++++------
> >  5 files changed, 359 insertions(+), 117 deletions(-)
> > 
> > diff --git a/drivers/gpu/drm/i915/gvt/handlers.c
> > b/drivers/gpu/drm/i915/gvt/handlers.c
> > index 7a58ca555197..79e748569d31 100644
> > --- a/drivers/gpu/drm/i915/gvt/handlers.c
> > +++ b/drivers/gpu/drm/i915/gvt/handlers.c
> > @@ -1287,12 +1287,12 @@ 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_GLOBA
> > L);
> >  	return 0;
> >  }
> >  
> > @@ -2443,17 +2443,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 +2797,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_w
> > rite);
> >  
> > -	/*
> > -	 * 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);
> > diff --git a/drivers/gpu/drm/i915/i915_drv.h
> > b/drivers/gpu/drm/i915/i915_drv.h
> > index d31a8ef05d18..d73ce0a7b8f7 100644
> > --- a/drivers/gpu/drm/i915/i915_drv.h
> > +++ b/drivers/gpu/drm/i915/i915_drv.h
> > @@ -861,6 +861,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;
> > @@ -884,6 +891,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
> > */
> > diff --git a/drivers/gpu/drm/i915/i915_reg.h
> > b/drivers/gpu/drm/i915/i915_reg.h
> > index f76bb4f3c944..b7022fb8d524 100644
> > --- a/drivers/gpu/drm/i915/i915_reg.h
> > +++ b/drivers/gpu/drm/i915/i915_reg.h
> > @@ -8842,46 +8842,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_CT
> > L1,	       \
> > -						    _ICL_PWR_WELL_CT
> > L_AUX1,    \
> > -						    _ICL_PWR_WELL_CT
> > L_DDI1))
> > -#define HSW_PWR_WELL_CTL_DRIVER(pw)	_MMIO(_PICK(_HSW_PW_REG_I
> > DX(pw),       \
> > -						    _HSW_PWR_WELL_CT
> > L2,	       \
> > -						    _ICL_PWR_WELL_CT
> > L_AUX2,    \
> > -						    _ICL_PWR_WELL_CT
> > L_DDI2))
> > -/* KVMR doesn't have a reg for AUX or DDI power well control */
> > -#define HSW_PWR_WELL_CTL_KVMR		_MMIO(_HSW_PWR_WELL_CTL
> > 3)
> > -#define HSW_PWR_WELL_CTL_DEBUG(pw)	_MMIO(_PICK(_HSW_PW_REG_ID
> > X(pw),       \
> > -						    _HSW_PWR_WELL_CT
> > L4,	       \
> > -						    _ICL_PWR_WELL_CT
> > L_AUX4,    \
> > -						    _ICL_PWR_WELL_CT
> > L_DDI4))
> > +#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))
> >  
> > -#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))
> > +/* 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 */
> 
> Single nitpick for a big patch: my OCD tells me to put a space before
> '-' or remove it completely because "ICL-" as is can be read as "ICL
> and older" to the distracted reader.

Ok.

> 
> Reviewed-by: Paulo Zanoni <paulo.r.zanoni@intel.com>
> 
> 
> > +#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)
> > @@ -8897,18 +8929,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_ANAOVRD
> > 1_B, \
> >  						    _CNL_AUX_ANAOVRD
> > 1_C, \
> >  						    _CNL_AUX_ANAOVRD
> > 1_D, \
> > diff --git a/drivers/gpu/drm/i915/intel_display.c
> > b/drivers/gpu/drm/i915/intel_display.c
> > index 87e4cfbfd096..640ec5df4d62 100644
> > --- a/drivers/gpu/drm/i915/intel_display.c
> > +++ b/drivers/gpu/drm/i915/intel_display.c
> > @@ -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_P
> > W_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");
> > @@ -16052,8 +16052,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_P
> > W_GLOBAL));
> > +		error->power_well_driver =
> > I915_READ(HSW_PWR_WELL_CTL2);
> >  
> >  	for_each_pipe(dev_priv, i) {
> >  		error->pipe[i].power_domain_on =
> > diff --git a/drivers/gpu/drm/i915/intel_runtime_pm.c
> > b/drivers/gpu/drm/i915/intel_runtime_pm.c
> > index 05d8cdab08cc..5527504d664f 100644
> > --- a/drivers/gpu/drm/i915/intel_runtime_pm.c
> > +++ b/drivers/gpu/drm/i915/intel_runtime_pm.c
> > @@ -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_id
> > x),
> > +					HSW_PWR_WELL_CTL_STATE(pw_id
> > x),
> >  					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_P
> > G(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),
> >  		},
diff mbox

Patch

diff --git a/drivers/gpu/drm/i915/gvt/handlers.c b/drivers/gpu/drm/i915/gvt/handlers.c
index 7a58ca555197..79e748569d31 100644
--- a/drivers/gpu/drm/i915/gvt/handlers.c
+++ b/drivers/gpu/drm/i915/gvt/handlers.c
@@ -1287,12 +1287,12 @@  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 +2443,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 +2797,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);
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index d31a8ef05d18..d73ce0a7b8f7 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -861,6 +861,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;
@@ -884,6 +891,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 */
diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
index f76bb4f3c944..b7022fb8d524 100644
--- a/drivers/gpu/drm/i915/i915_reg.h
+++ b/drivers/gpu/drm/i915/i915_reg.h
@@ -8842,46 +8842,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_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))
 
-#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))
+/* 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)
@@ -8897,18 +8929,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, \
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 87e4cfbfd096..640ec5df4d62 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -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");
@@ -16052,8 +16052,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 =
diff --git a/drivers/gpu/drm/i915/intel_runtime_pm.c b/drivers/gpu/drm/i915/intel_runtime_pm.c
index 05d8cdab08cc..5527504d664f 100644
--- a/drivers/gpu/drm/i915/intel_runtime_pm.c
+++ b/drivers/gpu/drm/i915/intel_runtime_pm.c
@@ -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),
 		},