[Intel-gfx] [PATCH] drm/i915/ehl: Add power wells support for Elkhart Lake

Imre Deak imre.deak at intel.com
Mon Jun 17 12:31:44 UTC 2019


Hi,

On Fri, Jun 14, 2019 at 07:06:49PM -0700, Vivek Kasireddy wrote:
> The number of power wells and the relevant sequences are common between
> ICL and EHL since they both are Gen 11. The only significant differences
> are that EHL does not have DDI E and DDI D and type C/TBT ports.

EHL could just reuse icl_power_wells[]. No power wells be used on EHL
that don't exist on it (since we'll not register port E/D or use the
ports in TBT/DP-alt mode).

--Imre

> 
> Cc: Clint Taylor <clinton.a.taylor at intel.com>
> Cc: José Roberto de Souza <jose.souza at intel.com>
> Cc: Matt Roper <matthew.d.roper at intel.com>
> Cc: Imre Deak <imre.deak at intel.com>
> Signed-off-by: Vivek Kasireddy <vivek.kasireddy at intel.com>
> ---
>  drivers/gpu/drm/i915/intel_display_power.c | 210 ++++++++++++++++++++-
>  1 file changed, 209 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/gpu/drm/i915/intel_display_power.c b/drivers/gpu/drm/i915/intel_display_power.c
> index c672c8080a93..e3ed77b843d2 100644
> --- a/drivers/gpu/drm/i915/intel_display_power.c
> +++ b/drivers/gpu/drm/i915/intel_display_power.c
> @@ -2397,6 +2397,66 @@ void intel_display_power_put(struct drm_i915_private *dev_priv,
>  #define ICL_AUX_TBT4_IO_POWER_DOMAINS (			\
>  	BIT_ULL(POWER_DOMAIN_AUX_TBT4))
>  
> +#define EHL_PW_4_POWER_DOMAINS (			\
> +	BIT_ULL(POWER_DOMAIN_PIPE_C) |			\
> +	BIT_ULL(POWER_DOMAIN_PIPE_C_PANEL_FITTER) |	\
> +	BIT_ULL(POWER_DOMAIN_INIT))
> +	/* VDSC/joining */
> +#define EHL_PW_3_POWER_DOMAINS (			\
> +	EHL_PW_4_POWER_DOMAINS |			\
> +	BIT_ULL(POWER_DOMAIN_PIPE_B) |			\
> +	BIT_ULL(POWER_DOMAIN_TRANSCODER_A) |		\
> +	BIT_ULL(POWER_DOMAIN_TRANSCODER_B) |		\
> +	BIT_ULL(POWER_DOMAIN_TRANSCODER_C) |		\
> +	BIT_ULL(POWER_DOMAIN_PIPE_B_PANEL_FITTER) |	\
> +	BIT_ULL(POWER_DOMAIN_PORT_DDI_B_LANES) |	\
> +	BIT_ULL(POWER_DOMAIN_PORT_DDI_B_IO) |		\
> +	BIT_ULL(POWER_DOMAIN_PORT_DDI_C_LANES) |	\
> +	BIT_ULL(POWER_DOMAIN_PORT_DDI_C_IO) |		\
> +	BIT_ULL(POWER_DOMAIN_PORT_DDI_D_LANES) |	\
> +	BIT_ULL(POWER_DOMAIN_PORT_DDI_D_IO) |		\
> +	BIT_ULL(POWER_DOMAIN_AUX_B) |			\
> +	BIT_ULL(POWER_DOMAIN_AUX_C) |			\
> +	BIT_ULL(POWER_DOMAIN_AUX_D) |			\
> +	BIT_ULL(POWER_DOMAIN_VGA) |			\
> +	BIT_ULL(POWER_DOMAIN_AUDIO) |			\
> +	BIT_ULL(POWER_DOMAIN_INIT))
> +	/*
> +	 * - transcoder WD
> +	 * - KVMR (HW control)
> +	 */
> +#define EHL_PW_2_POWER_DOMAINS (			\
> +	EHL_PW_3_POWER_DOMAINS |			\
> +	BIT_ULL(POWER_DOMAIN_TRANSCODER_EDP_VDSC) |		\
> +	BIT_ULL(POWER_DOMAIN_INIT))
> +	/*
> +	 * - KVMR (HW control)
> +	 */
> +#define EHL_DISPLAY_DC_OFF_POWER_DOMAINS (		\
> +	EHL_PW_2_POWER_DOMAINS |			\
> +	BIT_ULL(POWER_DOMAIN_MODESET) |			\
> +	BIT_ULL(POWER_DOMAIN_AUX_A) |			\
> +	BIT_ULL(POWER_DOMAIN_INIT))
> +
> +#define EHL_DDI_IO_A_POWER_DOMAINS (			\
> +	BIT_ULL(POWER_DOMAIN_PORT_DDI_A_IO))
> +#define EHL_DDI_IO_B_POWER_DOMAINS (			\
> +	BIT_ULL(POWER_DOMAIN_PORT_DDI_B_IO))
> +#define EHL_DDI_IO_C_POWER_DOMAINS (			\
> +	BIT_ULL(POWER_DOMAIN_PORT_DDI_C_IO))
> +#define EHL_DDI_IO_D_POWER_DOMAINS (			\
> +	BIT_ULL(POWER_DOMAIN_PORT_DDI_D_IO))
> +
> +#define EHL_AUX_A_IO_POWER_DOMAINS (			\
> +	BIT_ULL(POWER_DOMAIN_AUX_IO_A) |		\
> +	BIT_ULL(POWER_DOMAIN_AUX_A))
> +#define EHL_AUX_B_IO_POWER_DOMAINS (			\
> +	BIT_ULL(POWER_DOMAIN_AUX_B))
> +#define EHL_AUX_C_IO_POWER_DOMAINS (			\
> +	BIT_ULL(POWER_DOMAIN_AUX_C))
> +#define EHL_AUX_D_IO_POWER_DOMAINS (			\
> +	BIT_ULL(POWER_DOMAIN_AUX_D))
> +
>  static const struct i915_power_well_ops i9xx_always_on_power_well_ops = {
>  	.sync_hw = i9xx_power_well_sync_hw_noop,
>  	.enable = i9xx_always_on_power_well_noop,
> @@ -3354,6 +3414,152 @@ static const struct i915_power_well_desc icl_power_wells[] = {
>  	},
>  };
>  
> +static const struct i915_power_well_desc ehl_power_wells[] = {
> +	{
> +		.name = "always-on",
> +		.always_on = true,
> +		.domains = POWER_DOMAIN_MASK,
> +		.ops = &i9xx_always_on_power_well_ops,
> +		.id = DISP_PW_ID_NONE,
> +	},
> +	{
> +		.name = "power well 1",
> +		/* Handled by the DMC firmware */
> +		.always_on = true,
> +		.domains = 0,
> +		.ops = &hsw_power_well_ops,
> +		.id = SKL_DISP_PW_1,
> +		{
> +			.hsw.regs = &hsw_power_well_regs,
> +			.hsw.idx = ICL_PW_CTL_IDX_PW_1,
> +			.hsw.has_fuses = true,
> +		},
> +	},
> +	{
> +		.name = "DC off",
> +		.domains = EHL_DISPLAY_DC_OFF_POWER_DOMAINS,
> +		.ops = &gen9_dc_off_power_well_ops,
> +		.id = DISP_PW_ID_NONE,
> +	},
> +	{
> +		.name = "power well 2",
> +		.domains = EHL_PW_2_POWER_DOMAINS,
> +		.ops = &hsw_power_well_ops,
> +		.id = SKL_DISP_PW_2,
> +		{
> +			.hsw.regs = &hsw_power_well_regs,
> +			.hsw.idx = ICL_PW_CTL_IDX_PW_2,
> +			.hsw.has_fuses = true,
> +		},
> +	},
> +	{
> +		.name = "power well 3",
> +		.domains = EHL_PW_3_POWER_DOMAINS,
> +		.ops = &hsw_power_well_ops,
> +		.id = DISP_PW_ID_NONE,
> +		{
> +			.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,
> +		},
> +	},
> +	{
> +		.name = "DDI A IO",
> +		.domains = EHL_DDI_IO_A_POWER_DOMAINS,
> +		.ops = &hsw_power_well_ops,
> +		.id = DISP_PW_ID_NONE,
> +		{
> +			.hsw.regs = &icl_ddi_power_well_regs,
> +			.hsw.idx = ICL_PW_CTL_IDX_DDI_A,
> +		},
> +	},
> +	{
> +		.name = "DDI B IO",
> +		.domains = EHL_DDI_IO_B_POWER_DOMAINS,
> +		.ops = &hsw_power_well_ops,
> +		.id = DISP_PW_ID_NONE,
> +		{
> +			.hsw.regs = &icl_ddi_power_well_regs,
> +			.hsw.idx = ICL_PW_CTL_IDX_DDI_B,
> +		},
> +	},
> +	{
> +		.name = "DDI C IO",
> +		.domains = EHL_DDI_IO_C_POWER_DOMAINS,
> +		.ops = &hsw_power_well_ops,
> +		.id = DISP_PW_ID_NONE,
> +		{
> +			.hsw.regs = &icl_ddi_power_well_regs,
> +			.hsw.idx = ICL_PW_CTL_IDX_DDI_C,
> +		},
> +	},
> +	{
> +		.name = "DDI D IO",
> +		.domains = EHL_DDI_IO_D_POWER_DOMAINS,
> +		.ops = &hsw_power_well_ops,
> +		.id = DISP_PW_ID_NONE,
> +		{
> +			.hsw.regs = &icl_ddi_power_well_regs,
> +			.hsw.idx = ICL_PW_CTL_IDX_DDI_D,
> +		},
> +	},
> +	{
> +		.name = "AUX A",
> +		.domains = EHL_AUX_A_IO_POWER_DOMAINS,
> +		.ops = &icl_combo_phy_aux_power_well_ops,
> +		.id = DISP_PW_ID_NONE,
> +		{
> +			.hsw.regs = &icl_aux_power_well_regs,
> +			.hsw.idx = ICL_PW_CTL_IDX_AUX_A,
> +		},
> +	},
> +	{
> +		.name = "AUX B",
> +		.domains = EHL_AUX_B_IO_POWER_DOMAINS,
> +		.ops = &icl_combo_phy_aux_power_well_ops,
> +		.id = DISP_PW_ID_NONE,
> +		{
> +			.hsw.regs = &icl_aux_power_well_regs,
> +			.hsw.idx = ICL_PW_CTL_IDX_AUX_B,
> +		},
> +	},
> +	{
> +		.name = "AUX C",
> +		.domains = EHL_AUX_C_IO_POWER_DOMAINS,
> +		.ops = &icl_combo_phy_aux_power_well_ops,
> +		.id = DISP_PW_ID_NONE,
> +		{
> +			.hsw.regs = &icl_aux_power_well_regs,
> +			.hsw.idx = ICL_PW_CTL_IDX_AUX_C,
> +		},
> +	},
> +	{
> +		.name = "AUX D",
> +		.domains = EHL_AUX_D_IO_POWER_DOMAINS,
> +		.ops = &icl_combo_phy_aux_power_well_ops,
> +		.id = DISP_PW_ID_NONE,
> +		{
> +			.hsw.regs = &icl_aux_power_well_regs,
> +			.hsw.idx = ICL_PW_CTL_IDX_AUX_D,
> +		},
> +	},
> +	{
> +		.name = "power well 4",
> +		.domains = EHL_PW_4_POWER_DOMAINS,
> +		.ops = &hsw_power_well_ops,
> +		.id = DISP_PW_ID_NONE,
> +		{
> +			.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),
> +		},
> +	},
> +};
> +
> +
>  static int
>  sanitize_disable_power_well_option(const struct drm_i915_private *dev_priv,
>  				   int disable_power_well)
> @@ -3481,8 +3687,10 @@ int intel_power_domains_init(struct drm_i915_private *dev_priv)
>  	 * The enabling order will be from lower to higher indexed wells,
>  	 * the disabling order is reversed.
>  	 */
> -	if (IS_GEN(dev_priv, 11)) {
> +	if (IS_ICELAKE(dev_priv)) {
>  		err = set_power_wells(power_domains, icl_power_wells);
> +	} else if (IS_ELKHARTLAKE(dev_priv)) {
> +		err = set_power_wells(power_domains, ehl_power_wells);
>  	} else if (IS_CANNONLAKE(dev_priv)) {
>  		err = set_power_wells(power_domains, cnl_power_wells);
>  
> -- 
> 2.21.0
> 


More information about the Intel-gfx mailing list