{ .name = _name, .domain_list = _domain_list, ## __VA_ARGS__ }
+struct i915_power_well_desc_list {
+ const struct i915_power_well_desc *list;
+ u8 count;
+};
+
+#define I915_PW_DESCRIPTORS(x) __LIST(x)
+
+
I915_DECL_PW_DOMAINS(i9xx_pwdoms_always_on, I915_PW_DOMAINS_ALL);
-static const struct i915_power_well_desc i9xx_always_on_power_well[] = {
+static const struct i915_power_well_desc i9xx_power_wells_always_on[] = {
{
.instances = &I915_PW_INSTANCES(
I915_PW("always-on", &i9xx_pwdoms_always_on),
},
};
+static const struct i915_power_well_desc_list i9xx_power_wells[] = {
+ I915_PW_DESCRIPTORS(i9xx_power_wells_always_on),
+};
+
I915_DECL_PW_DOMAINS(i830_pwdoms_pipes,
POWER_DOMAIN_PIPE_A,
POWER_DOMAIN_PIPE_B,
POWER_DOMAIN_TRANSCODER_B,
POWER_DOMAIN_INIT);
-static const struct i915_power_well_desc i830_power_wells[] = {
+static const struct i915_power_well_desc i830_power_wells_main[] = {
{
- .instances = &I915_PW_INSTANCES(
- I915_PW("always-on", &i9xx_pwdoms_always_on),
- ),
- .ops = &i9xx_always_on_power_well_ops,
- .always_on = true,
- }, {
.instances = &I915_PW_INSTANCES(
I915_PW("pipes", &i830_pwdoms_pipes),
),
},
};
+static const struct i915_power_well_desc_list i830_power_wells[] = {
+ I915_PW_DESCRIPTORS(i9xx_power_wells_always_on),
+ I915_PW_DESCRIPTORS(i830_power_wells_main),
+};
+
I915_DECL_PW_DOMAINS(hsw_pwdoms_display,
POWER_DOMAIN_PIPE_B,
POWER_DOMAIN_PIPE_C,
POWER_DOMAIN_AUDIO_PLAYBACK,
POWER_DOMAIN_INIT);
-static const struct i915_power_well_desc hsw_power_wells[] = {
+static const struct i915_power_well_desc hsw_power_wells_main[] = {
{
- .instances = &I915_PW_INSTANCES(
- I915_PW("always-on", &i9xx_pwdoms_always_on),
- ),
- .ops = &i9xx_always_on_power_well_ops,
- .always_on = true,
- }, {
.instances = &I915_PW_INSTANCES(
I915_PW("display", &hsw_pwdoms_display,
.hsw.idx = HSW_PW_CTL_IDX_GLOBAL,
},
};
+static const struct i915_power_well_desc_list hsw_power_wells[] = {
+ I915_PW_DESCRIPTORS(i9xx_power_wells_always_on),
+ I915_PW_DESCRIPTORS(hsw_power_wells_main),
+};
+
I915_DECL_PW_DOMAINS(bdw_pwdoms_display,
POWER_DOMAIN_PIPE_B,
POWER_DOMAIN_PIPE_C,
POWER_DOMAIN_AUDIO_PLAYBACK,
POWER_DOMAIN_INIT);
-static const struct i915_power_well_desc bdw_power_wells[] = {
+static const struct i915_power_well_desc bdw_power_wells_main[] = {
{
- .instances = &I915_PW_INSTANCES(
- I915_PW("always-on", &i9xx_pwdoms_always_on),
- ),
- .ops = &i9xx_always_on_power_well_ops,
- .always_on = true,
- }, {
.instances = &I915_PW_INSTANCES(
I915_PW("display", &bdw_pwdoms_display,
.hsw.idx = HSW_PW_CTL_IDX_GLOBAL,
},
};
+static const struct i915_power_well_desc_list bdw_power_wells[] = {
+ I915_PW_DESCRIPTORS(i9xx_power_wells_always_on),
+ I915_PW_DESCRIPTORS(bdw_power_wells_main),
+};
+
I915_DECL_PW_DOMAINS(vlv_pwdoms_display,
POWER_DOMAIN_DISPLAY_CORE,
POWER_DOMAIN_PIPE_A,
POWER_DOMAIN_AUX_C,
POWER_DOMAIN_INIT);
-static const struct i915_power_well_desc vlv_power_wells[] = {
+static const struct i915_power_well_desc vlv_power_wells_main[] = {
{
- .instances = &I915_PW_INSTANCES(
- I915_PW("always-on", &i9xx_pwdoms_always_on),
- ),
- .ops = &i9xx_always_on_power_well_ops,
- .always_on = true,
- }, {
.instances = &I915_PW_INSTANCES(
I915_PW("display", &vlv_pwdoms_display,
.vlv.idx = PUNIT_PWGT_IDX_DISP2D,
},
};
+static const struct i915_power_well_desc_list vlv_power_wells[] = {
+ I915_PW_DESCRIPTORS(i9xx_power_wells_always_on),
+ I915_PW_DESCRIPTORS(vlv_power_wells_main),
+};
+
I915_DECL_PW_DOMAINS(chv_pwdoms_display,
POWER_DOMAIN_DISPLAY_CORE,
POWER_DOMAIN_PIPE_A,
POWER_DOMAIN_AUX_D,
POWER_DOMAIN_INIT);
-static const struct i915_power_well_desc chv_power_wells[] = {
+static const struct i915_power_well_desc chv_power_wells_main[] = {
{
- .instances = &I915_PW_INSTANCES(
- I915_PW("always-on", &i9xx_pwdoms_always_on),
- ),
- .ops = &i9xx_always_on_power_well_ops,
- .always_on = true,
- }, {
/*
* Pipe A power well is the new disp2d well. Pipe B and C
* power wells don't actually exist. Pipe A power well is
},
};
+static const struct i915_power_well_desc_list chv_power_wells[] = {
+ I915_PW_DESCRIPTORS(i9xx_power_wells_always_on),
+ I915_PW_DESCRIPTORS(chv_power_wells_main),
+};
+
#define SKL_PW_2_POWER_DOMAINS \
POWER_DOMAIN_PIPE_B, \
POWER_DOMAIN_PIPE_C, \
POWER_DOMAIN_PORT_DDI_IO_D,
POWER_DOMAIN_INIT);
-static const struct i915_power_well_desc skl_power_wells[] = {
+static const struct i915_power_well_desc skl_power_wells_pw_1[] = {
{
- .instances = &I915_PW_INSTANCES(
- I915_PW("always-on", &i9xx_pwdoms_always_on),
- ),
- .ops = &i9xx_always_on_power_well_ops,
- .always_on = true,
- }, {
/* Handled by the DMC firmware */
.instances = &I915_PW_INSTANCES(
I915_PW("PW_1", I915_PW_DOMAINS_NONE,
.ops = &hsw_power_well_ops,
.always_on = true,
.has_fuses = true,
- }, {
+ },
+};
+
+static const struct i915_power_well_desc skl_power_wells_main[] = {
+ {
/* Handled by the DMC firmware */
.instances = &I915_PW_INSTANCES(
I915_PW("MISC_IO", I915_PW_DOMAINS_NONE,
},
};
+static const struct i915_power_well_desc_list skl_power_wells[] = {
+ I915_PW_DESCRIPTORS(i9xx_power_wells_always_on),
+ I915_PW_DESCRIPTORS(skl_power_wells_pw_1),
+ I915_PW_DESCRIPTORS(skl_power_wells_main),
+};
+
#define BXT_PW_2_POWER_DOMAINS \
POWER_DOMAIN_PIPE_B, \
POWER_DOMAIN_PIPE_C, \
POWER_DOMAIN_AUX_C,
POWER_DOMAIN_INIT);
-static const struct i915_power_well_desc bxt_power_wells[] = {
+static const struct i915_power_well_desc bxt_power_wells_main[] = {
{
- .instances = &I915_PW_INSTANCES(
- I915_PW("always-on", &i9xx_pwdoms_always_on),
- ),
- .ops = &i9xx_always_on_power_well_ops,
- .always_on = true,
- }, {
- /* Handled by the DMC firmware */
- .instances = &I915_PW_INSTANCES(
- I915_PW("PW_1", I915_PW_DOMAINS_NONE,
- .hsw.idx = SKL_PW_CTL_IDX_PW_1,
- .id = SKL_DISP_PW_1),
- ),
- .ops = &hsw_power_well_ops,
- .always_on = true,
- .has_fuses = true,
- }, {
.instances = &I915_PW_INSTANCES(
I915_PW("DC_off", &bxt_pwdoms_dc_off,
.id = SKL_DISP_DC_OFF),
},
};
+static const struct i915_power_well_desc_list bxt_power_wells[] = {
+ I915_PW_DESCRIPTORS(i9xx_power_wells_always_on),
+ I915_PW_DESCRIPTORS(skl_power_wells_pw_1),
+ I915_PW_DESCRIPTORS(bxt_power_wells_main),
+};
+
#define GLK_PW_2_POWER_DOMAINS \
POWER_DOMAIN_PIPE_B, \
POWER_DOMAIN_PIPE_C, \
POWER_DOMAIN_AUX_C,
POWER_DOMAIN_INIT);
-static const struct i915_power_well_desc glk_power_wells[] = {
+static const struct i915_power_well_desc glk_power_wells_main[] = {
{
- .instances = &I915_PW_INSTANCES(
- I915_PW("always-on", &i9xx_pwdoms_always_on),
- ),
- .ops = &i9xx_always_on_power_well_ops,
- .always_on = true,
- }, {
- /* Handled by the DMC firmware */
- .instances = &I915_PW_INSTANCES(
- I915_PW("PW_1", I915_PW_DOMAINS_NONE,
- .hsw.idx = SKL_PW_CTL_IDX_PW_1,
- .id = SKL_DISP_PW_1),
- ),
- .ops = &hsw_power_well_ops,
- .always_on = true,
- .has_fuses = true,
- }, {
.instances = &I915_PW_INSTANCES(
I915_PW("DC_off", &glk_pwdoms_dc_off,
.id = SKL_DISP_DC_OFF),
},
};
+static const struct i915_power_well_desc_list glk_power_wells[] = {
+ I915_PW_DESCRIPTORS(i9xx_power_wells_always_on),
+ I915_PW_DESCRIPTORS(skl_power_wells_pw_1),
+ I915_PW_DESCRIPTORS(glk_power_wells_main),
+};
+
/*
* ICL PW_0/PG_0 domains (HW/DMC control):
* - PCI
I915_DECL_PW_DOMAINS(icl_pwdoms_aux_tbt3, POWER_DOMAIN_AUX_TBT_E);
I915_DECL_PW_DOMAINS(icl_pwdoms_aux_tbt4, POWER_DOMAIN_AUX_TBT_F);
-static const struct i915_power_well_desc icl_power_wells[] = {
+static const struct i915_power_well_desc icl_power_wells_pw_1[] = {
{
- .instances = &I915_PW_INSTANCES(
- I915_PW("always-on", &i9xx_pwdoms_always_on),
- ),
- .ops = &i9xx_always_on_power_well_ops,
- .always_on = true,
- }, {
/* Handled by the DMC firmware */
.instances = &I915_PW_INSTANCES(
I915_PW("PW_1", I915_PW_DOMAINS_NONE,
.ops = &hsw_power_well_ops,
.always_on = true,
.has_fuses = true,
- }, {
+ },
+};
+
+static const struct i915_power_well_desc icl_power_wells_main[] = {
+ {
.instances = &I915_PW_INSTANCES(
I915_PW("DC_off", &icl_pwdoms_dc_off,
.id = SKL_DISP_DC_OFF),
},
};
+static const struct i915_power_well_desc_list icl_power_wells[] = {
+ I915_PW_DESCRIPTORS(i9xx_power_wells_always_on),
+ I915_PW_DESCRIPTORS(icl_power_wells_pw_1),
+ I915_PW_DESCRIPTORS(icl_power_wells_main),
+};
+
#define TGL_PW_5_POWER_DOMAINS \
POWER_DOMAIN_PIPE_D, \
POWER_DOMAIN_PIPE_PANEL_FITTER_D, \
POWER_DOMAIN_AUX_TBT6,
POWER_DOMAIN_TC_COLD_OFF);
-static const struct i915_power_well_desc tgl_power_wells[] = {
+static const struct i915_power_well_desc tgl_power_wells_main[] = {
{
- .instances = &I915_PW_INSTANCES(
- I915_PW("always-on", &i9xx_pwdoms_always_on),
- ),
- .ops = &i9xx_always_on_power_well_ops,
- .always_on = true,
- }, {
- /* Handled by the DMC firmware */
- .instances = &I915_PW_INSTANCES(
- I915_PW("PW_1", I915_PW_DOMAINS_NONE,
- .hsw.idx = ICL_PW_CTL_IDX_PW_1,
- .id = SKL_DISP_PW_1),
- ),
- .ops = &hsw_power_well_ops,
- .always_on = true,
- .has_fuses = true,
- }, {
.instances = &I915_PW_INSTANCES(
I915_PW("DC_off", &tgl_pwdoms_dc_off,
.id = SKL_DISP_DC_OFF),
},
};
+static const struct i915_power_well_desc_list tgl_power_wells[] = {
+ I915_PW_DESCRIPTORS(i9xx_power_wells_always_on),
+ I915_PW_DESCRIPTORS(icl_power_wells_pw_1),
+ I915_PW_DESCRIPTORS(tgl_power_wells_main),
+};
+
#define RKL_PW_4_POWER_DOMAINS \
POWER_DOMAIN_PIPE_C, \
POWER_DOMAIN_PIPE_PANEL_FITTER_C, \
POWER_DOMAIN_MODESET,
POWER_DOMAIN_INIT);
-static const struct i915_power_well_desc rkl_power_wells[] = {
+static const struct i915_power_well_desc rkl_power_wells_main[] = {
{
- .instances = &I915_PW_INSTANCES(
- I915_PW("always-on", &i9xx_pwdoms_always_on),
- ),
- .ops = &i9xx_always_on_power_well_ops,
- .always_on = true,
- }, {
- /* Handled by the DMC firmware */
- .instances = &I915_PW_INSTANCES(
- I915_PW("PW_1", I915_PW_DOMAINS_NONE,
- .hsw.idx = ICL_PW_CTL_IDX_PW_1,
- .id = SKL_DISP_PW_1),
- ),
- .ops = &hsw_power_well_ops,
- .always_on = true,
- .has_fuses = true,
- }, {
.instances = &I915_PW_INSTANCES(
I915_PW("DC_off", &rkl_pwdoms_dc_off,
.id = SKL_DISP_DC_OFF),
},
};
+static const struct i915_power_well_desc_list rkl_power_wells[] = {
+ I915_PW_DESCRIPTORS(i9xx_power_wells_always_on),
+ I915_PW_DESCRIPTORS(icl_power_wells_pw_1),
+ I915_PW_DESCRIPTORS(rkl_power_wells_main),
+};
+
/*
* DG1 onwards Audio MMIO/VERBS lies in PG0 power well.
*/
POWER_DOMAIN_TRANSCODER_VDSC_PW2,
POWER_DOMAIN_INIT);
-static const struct i915_power_well_desc dg1_power_wells[] = {
+static const struct i915_power_well_desc dg1_power_wells_main[] = {
{
- .instances = &I915_PW_INSTANCES(
- I915_PW("always-on", &i9xx_pwdoms_always_on),
- ),
- .ops = &i9xx_always_on_power_well_ops,
- .always_on = true,
- }, {
- /* Handled by the DMC firmware */
- .instances = &I915_PW_INSTANCES(
- I915_PW("PW_1", I915_PW_DOMAINS_NONE,
- .hsw.idx = ICL_PW_CTL_IDX_PW_1,
- .id = SKL_DISP_PW_1),
- ),
- .ops = &hsw_power_well_ops,
- .always_on = true,
- .has_fuses = true,
- }, {
.instances = &I915_PW_INSTANCES(
I915_PW("DC_off", &dg1_pwdoms_dc_off,
.id = SKL_DISP_DC_OFF),
},
};
+static const struct i915_power_well_desc_list dg1_power_wells[] = {
+ I915_PW_DESCRIPTORS(i9xx_power_wells_always_on),
+ I915_PW_DESCRIPTORS(icl_power_wells_pw_1),
+ I915_PW_DESCRIPTORS(dg1_power_wells_main),
+};
+
/*
* XE_LPD Power Domains
*
I915_DECL_PW_DOMAINS(xelpd_pwdoms_ddi_io_tc3, POWER_DOMAIN_PORT_DDI_IO_TC3);
I915_DECL_PW_DOMAINS(xelpd_pwdoms_ddi_io_tc4, POWER_DOMAIN_PORT_DDI_IO_TC4);
-static const struct i915_power_well_desc xelpd_power_wells[] = {
+static const struct i915_power_well_desc xelpd_power_wells_main[] = {
{
- .instances = &I915_PW_INSTANCES(
- I915_PW("always-on", &i9xx_pwdoms_always_on),
- ),
- .ops = &i9xx_always_on_power_well_ops,
- .always_on = true,
- }, {
- /* Handled by the DMC firmware */
- .instances = &I915_PW_INSTANCES(
- I915_PW("PW_1", I915_PW_DOMAINS_NONE,
- .hsw.idx = ICL_PW_CTL_IDX_PW_1,
- .id = SKL_DISP_PW_1),
- ),
- .ops = &hsw_power_well_ops,
- .always_on = true,
- .has_fuses = true,
- }, {
.instances = &I915_PW_INSTANCES(
I915_PW("DC_off", &xelpd_pwdoms_dc_off,
.id = SKL_DISP_DC_OFF),
},
};
+static const struct i915_power_well_desc_list xelpd_power_wells[] = {
+ I915_PW_DESCRIPTORS(i9xx_power_wells_always_on),
+ I915_PW_DESCRIPTORS(icl_power_wells_pw_1),
+ I915_PW_DESCRIPTORS(xelpd_power_wells_main),
+};
+
static void init_power_well_domains(const struct i915_power_well_instance *inst,
struct i915_power_well *power_well)
{
set_bit(inst->domain_list->list[j], power_well->domains.bits);
}
-#define for_each_power_well_instance(_desc_list, _desc_count, _desc, _inst) \
+#define for_each_power_well_instance_in_desc_list(_desc_list, _desc_count, _desc, _inst) \
for ((_desc) = (_desc_list); (_desc) - (_desc_list) < (_desc_count); (_desc)++) \
for ((_inst) = (_desc)->instances->list; \
(_inst) - (_desc)->instances->list < (_desc)->instances->count; \
(_inst)++)
+#define for_each_power_well_instance(_desc_list, _desc_count, _descs, _desc, _inst) \
+ for ((_descs) = (_desc_list); \
+ (_descs) - (_desc_list) < (_desc_count); \
+ (_descs)++) \
+ for_each_power_well_instance_in_desc_list((_descs)->list, (_descs)->count, \
+ (_desc), (_inst))
+
static int
__set_power_wells(struct i915_power_domains *power_domains,
- const struct i915_power_well_desc *power_well_descs,
+ const struct i915_power_well_desc_list *power_well_descs,
int power_well_descs_sz, u64 skip_mask)
{
struct drm_i915_private *i915 = container_of(power_domains,
struct drm_i915_private,
power_domains);
u64 power_well_ids = 0;
+ const struct i915_power_well_desc_list *desc_list;
const struct i915_power_well_desc *desc;
const struct i915_power_well_instance *inst;
int power_well_count = 0;
int plt_idx = 0;
- for_each_power_well_instance(power_well_descs, power_well_descs_sz, desc, inst)
+ for_each_power_well_instance(power_well_descs, power_well_descs_sz, desc_list, desc, inst)
if (!(BIT_ULL(inst->id) & skip_mask))
power_well_count++;
if (!power_domains->power_wells)
return -ENOMEM;
- for_each_power_well_instance(power_well_descs, power_well_descs_sz, desc, inst) {
+ for_each_power_well_instance(power_well_descs, power_well_descs_sz, desc_list, desc, inst) {
struct i915_power_well *pw = &power_domains->power_wells[plt_idx];
enum i915_power_well_id id = inst->id;
else if (IS_I830(i915))
return set_power_wells(power_domains, i830_power_wells);
else
- return set_power_wells(power_domains, i9xx_always_on_power_well);
+ return set_power_wells(power_domains, i9xx_power_wells);
}
/**