* [PATCH] drm/i915/icl: Add power well support
@ 2018-06-26 14:22 Imre Deak
2018-06-26 14:47 ` ✗ Fi.CI.CHECKPATCH: warning for " Patchwork
` (3 more replies)
0 siblings, 4 replies; 9+ messages in thread
From: Imre Deak @ 2018-06-26 14:22 UTC (permalink / raw)
To: intel-gfx; +Cc: Paulo Zanoni
Add the definition for ICL power wells and their mapping to power
domains. On ICL there are 3 power well control registers, we'll select
the correct one based on higher bits of the power well ID. The offset
for the control and status flags within this register is based on the
lower bits of the ID as on older platforms.
As the DC state programming is also the same as on old platforms we can
reuse the corresponding helpers. For this we mark here the DC-off power
well as shared among multiple platforms.
Other than the above the delta between old platforms and ICL:
- Pipe C has its own power well, so we can save some additional power in the
pipe A+B and (non-eDP) pipe A configurations.
- Power wells for port E/F DDI/AUX IO and Thunderbolt 1-4 AUX IO
v2:
- Rebase on drm-tip after prep patch for this was merged there as
requested by Paulo.
- Actually add the new AUX and DDI power well control regs (Rakshmi)
v3:
- Fix power well register names in code comments
- Add TBT AUX->power well 3 dependency
v4:
- Rebase
v5:
- Detach AUX power wells from the INIT power domain. These power wells
can only be enabled in a TC/TBT connected state and otherwise not
needed during driver initialization.
Cc: Animesh Manna <animesh.manna@intel.com>
Cc: Rakshmi Bhatia <rakshmi.bhatia@intel.com>
Cc: Paulo Zanoni <paulo.r.zanoni@intel.com>
Signed-off-by: Imre Deak <imre.deak@intel.com>
Reviewed-by: Animesh Manna <animesh.manna@intel.com> (v1)
---
drivers/gpu/drm/i915/i915_reg.h | 78 +++++++-
drivers/gpu/drm/i915/intel_display.h | 4 +
drivers/gpu/drm/i915/intel_runtime_pm.c | 329 +++++++++++++++++++++++++++++++-
3 files changed, 395 insertions(+), 16 deletions(-)
diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
index caad19f5f557..865b05ce8d76 100644
--- a/drivers/gpu/drm/i915/i915_reg.h
+++ b/drivers/gpu/drm/i915/i915_reg.h
@@ -1045,13 +1045,13 @@ enum i915_power_well_id {
/*
* HSW/BDW
- * - HSW_PWR_WELL_CTL_DRIVER(0) (status bit: id*2, req bit: id*2+1)
+ * - _HSW_PWR_WELL_CTL1-4 (status bit: id*2, req bit: id*2+1)
*/
HSW_DISP_PW_GLOBAL = 15,
/*
* GEN9+
- * - HSW_PWR_WELL_CTL_DRIVER(0) (status bit: id*2, req bit: id*2+1)
+ * - _HSW_PWR_WELL_CTL1-4 (status bit: id*2, req bit: id*2+1)
*/
SKL_DISP_PW_MISC_IO = 0,
SKL_DISP_PW_DDI_A_E,
@@ -1075,17 +1075,54 @@ enum i915_power_well_id {
SKL_DISP_PW_2,
/* - custom power wells */
- SKL_DISP_PW_DC_OFF,
BXT_DPIO_CMN_A,
BXT_DPIO_CMN_BC,
- GLK_DPIO_CMN_C, /* 19 */
+ GLK_DPIO_CMN_C, /* 18 */
+
+ /*
+ * GEN11+
+ * - _HSW_PWR_WELL_CTL1-4
+ * (status bit: (id&15)*2, req bit:(id&15)*2+1)
+ */
+ ICL_DISP_PW_1 = 0,
+ ICL_DISP_PW_2,
+ ICL_DISP_PW_3,
+ ICL_DISP_PW_4,
+
+ /*
+ * - _HSW_PWR_WELL_CTL_AUX1/2/4
+ * (status bit: (id&15)*2, req bit:(id&15)*2+1)
+ */
+ ICL_DISP_PW_AUX_A = 16,
+ ICL_DISP_PW_AUX_B,
+ ICL_DISP_PW_AUX_C,
+ ICL_DISP_PW_AUX_D,
+ ICL_DISP_PW_AUX_E,
+ ICL_DISP_PW_AUX_F,
+
+ ICL_DISP_PW_AUX_TBT1 = 24,
+ ICL_DISP_PW_AUX_TBT2,
+ ICL_DISP_PW_AUX_TBT3,
+ ICL_DISP_PW_AUX_TBT4,
+
+ /*
+ * - _HSW_PWR_WELL_CTL_DDI1/2/4
+ * (status bit: (id&15)*2, req bit:(id&15)*2+1)
+ */
+ ICL_DISP_PW_DDI_A = 32,
+ ICL_DISP_PW_DDI_B,
+ ICL_DISP_PW_DDI_C,
+ ICL_DISP_PW_DDI_D,
+ ICL_DISP_PW_DDI_E,
+ ICL_DISP_PW_DDI_F, /* 37 */
/*
* Multiple platforms.
* Must start following the highest ID of any platform.
* - custom power wells
*/
- I915_DISP_PW_ALWAYS_ON = 20,
+ SKL_DISP_PW_DC_OFF = 38,
+ I915_DISP_PW_ALWAYS_ON,
};
#define PUNIT_REG_PWRGT_CTRL 0x60
@@ -1679,6 +1716,13 @@ enum i915_power_well_id {
#define IREF1RC_OFFSET_MASK (0xFF << IREF1RC_OFFSET_SHIFT)
#define BXT_PORT_CL1CM_DW10(phy) _BXT_PHY((phy), _PORT_CL1CM_DW10_BC)
+#define _ICL_PORT_CL_DW12_A 0x162030
+#define _ICL_PORT_CL_DW12_B 0x6C030
+#define ICL_LANE_ENABLE_AUX (1 << 0)
+#define ICL_PORT_CL_DW12(port) _MMIO(_PICK((port), \
+ _ICL_PORT_CL_DW12_A, \
+ _ICL_PORT_CL_DW12_B))
+
#define _PORT_CL1CM_DW28_A 0x162070
#define _PORT_CL1CM_DW28_BC 0x6C070
#define OCL1_POWER_DOWN_EN (1 << 23)
@@ -8563,6 +8607,14 @@ enum {
#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
@@ -8572,14 +8624,20 @@ enum {
*/
#define _HSW_PW_REG_IDX(pw) ((pw) >> 4)
#define _HSW_PW_SHIFT(pw) (((pw) & 0xf) * 2)
-/* TODO: Add all PWR_WELL_CTL registers below for new platforms */
#define HSW_PWR_WELL_CTL_BIOS(pw) _MMIO(_PICK(_HSW_PW_REG_IDX(pw), \
- _HSW_PWR_WELL_CTL1))
+ _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))
+ _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))
+ _HSW_PWR_WELL_CTL4, \
+ _ICL_PWR_WELL_CTL_AUX4, \
+ _ICL_PWR_WELL_CTL_DDI4))
#define HSW_PWR_WELL_CTL_REQ(pw) (1 << (_HSW_PW_SHIFT(pw) + 1))
#define HSW_PWR_WELL_CTL_STATE(pw) (1 << _HSW_PW_SHIFT(pw))
@@ -8600,6 +8658,8 @@ enum skl_power_gate {
#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)
#define SKL_FUSE_PG_DIST_STATUS(pg) (1 << (27 - (pg)))
#define _CNL_AUX_REG_IDX(pw) ((pw) - 9)
diff --git a/drivers/gpu/drm/i915/intel_display.h b/drivers/gpu/drm/i915/intel_display.h
index dfb02da73ac8..a77dd29db2ec 100644
--- a/drivers/gpu/drm/i915/intel_display.h
+++ b/drivers/gpu/drm/i915/intel_display.h
@@ -199,6 +199,10 @@ enum intel_display_power_domain {
POWER_DOMAIN_AUX_E,
POWER_DOMAIN_AUX_F,
POWER_DOMAIN_AUX_IO_A,
+ POWER_DOMAIN_AUX_TBT1,
+ POWER_DOMAIN_AUX_TBT2,
+ POWER_DOMAIN_AUX_TBT3,
+ POWER_DOMAIN_AUX_TBT4,
POWER_DOMAIN_GMBUS,
POWER_DOMAIN_MODESET,
POWER_DOMAIN_GT_IRQ,
diff --git a/drivers/gpu/drm/i915/intel_runtime_pm.c b/drivers/gpu/drm/i915/intel_runtime_pm.c
index 2969787201ef..790670f5fb98 100644
--- a/drivers/gpu/drm/i915/intel_runtime_pm.c
+++ b/drivers/gpu/drm/i915/intel_runtime_pm.c
@@ -134,6 +134,14 @@ intel_display_power_domain_str(enum intel_display_power_domain domain)
return "AUX_F";
case POWER_DOMAIN_AUX_IO_A:
return "AUX_IO_A";
+ case POWER_DOMAIN_AUX_TBT1:
+ return "AUX_TBT1";
+ case POWER_DOMAIN_AUX_TBT2:
+ return "AUX_TBT2";
+ case POWER_DOMAIN_AUX_TBT3:
+ return "AUX_TBT3";
+ case POWER_DOMAIN_AUX_TBT4:
+ return "AUX_TBT4";
case POWER_DOMAIN_GMBUS:
return "GMBUS";
case POWER_DOMAIN_INIT:
@@ -384,7 +392,8 @@ static void hsw_power_well_enable(struct drm_i915_private *dev_priv,
u32 val;
if (wait_fuses) {
- pg = SKL_PW_TO_PG(id);
+ pg = INTEL_GEN(dev_priv) >= 11 ? ICL_PW_TO_PG(id) :
+ SKL_PW_TO_PG(id);
/*
* For PW1 we have to wait both for the PW0/PG0 fuse state
* before enabling the power well and PW1/PG1's own fuse
@@ -430,6 +439,43 @@ static void hsw_power_well_disable(struct drm_i915_private *dev_priv,
hsw_wait_for_power_well_disable(dev_priv, power_well);
}
+#define ICL_AUX_PW_TO_PORT(pw) ((pw) - ICL_DISP_PW_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->id;
+ enum port port = ICL_AUX_PW_TO_PORT(id);
+ 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(ICL_PORT_CL_DW12(port));
+ I915_WRITE(ICL_PORT_CL_DW12(port), val | ICL_LANE_ENABLE_AUX);
+
+ hsw_wait_for_power_well_enable(dev_priv, power_well);
+}
+
+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->id;
+ enum port port = ICL_AUX_PW_TO_PORT(id);
+ 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));
+
+ hsw_wait_for_power_well_disable(dev_priv, power_well);
+}
+
/*
* We should only use the power well if we explicitly asked the hardware to
* enable it, so check if it's enabled and also check if we've requested it to
@@ -1897,6 +1943,105 @@ void intel_display_power_put(struct drm_i915_private *dev_priv,
BIT_ULL(POWER_DOMAIN_AUX_A) | \
BIT_ULL(POWER_DOMAIN_INIT))
+/*
+ * ICL PW_0/PG_0 domains (HW/DMC control):
+ * - PCI
+ * - clocks except port PLL
+ * - central power except FBC
+ * - shared functions except pipe interrupts, pipe MBUS, DBUF registers
+ * ICL PW_1/PG_1 domains (HW/DMC control):
+ * - DBUF function
+ * - PIPE_A and its planes, except VGA
+ * - transcoder EDP + PSR
+ * - transcoder DSI
+ * - DDI_A
+ * - FBC
+ */
+#define ICL_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 ICL_PW_3_POWER_DOMAINS ( \
+ ICL_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_PORT_DDI_E_LANES) | \
+ BIT_ULL(POWER_DOMAIN_PORT_DDI_E_IO) | \
+ BIT_ULL(POWER_DOMAIN_PORT_DDI_F_LANES) | \
+ BIT_ULL(POWER_DOMAIN_PORT_DDI_F_IO) | \
+ BIT_ULL(POWER_DOMAIN_AUX_B) | \
+ BIT_ULL(POWER_DOMAIN_AUX_C) | \
+ BIT_ULL(POWER_DOMAIN_AUX_D) | \
+ BIT_ULL(POWER_DOMAIN_AUX_E) | \
+ BIT_ULL(POWER_DOMAIN_AUX_F) | \
+ BIT_ULL(POWER_DOMAIN_AUX_TBT1) | \
+ BIT_ULL(POWER_DOMAIN_AUX_TBT2) | \
+ BIT_ULL(POWER_DOMAIN_AUX_TBT3) | \
+ BIT_ULL(POWER_DOMAIN_AUX_TBT4) | \
+ BIT_ULL(POWER_DOMAIN_VGA) | \
+ BIT_ULL(POWER_DOMAIN_AUDIO) | \
+ BIT_ULL(POWER_DOMAIN_INIT))
+ /*
+ * - transcoder WD
+ * - KVMR (HW control)
+ */
+#define ICL_PW_2_POWER_DOMAINS ( \
+ ICL_PW_3_POWER_DOMAINS | \
+ BIT_ULL(POWER_DOMAIN_INIT))
+ /*
+ * - eDP/DSI VDSC
+ * - KVMR (HW control)
+ */
+#define ICL_DISPLAY_DC_OFF_POWER_DOMAINS ( \
+ ICL_PW_2_POWER_DOMAINS | \
+ BIT_ULL(POWER_DOMAIN_MODESET) | \
+ BIT_ULL(POWER_DOMAIN_AUX_A) | \
+ BIT_ULL(POWER_DOMAIN_INIT))
+
+#define ICL_DDI_IO_A_POWER_DOMAINS ( \
+ BIT_ULL(POWER_DOMAIN_PORT_DDI_A_IO))
+#define ICL_DDI_IO_B_POWER_DOMAINS ( \
+ BIT_ULL(POWER_DOMAIN_PORT_DDI_B_IO))
+#define ICL_DDI_IO_C_POWER_DOMAINS ( \
+ BIT_ULL(POWER_DOMAIN_PORT_DDI_C_IO))
+#define ICL_DDI_IO_D_POWER_DOMAINS ( \
+ BIT_ULL(POWER_DOMAIN_PORT_DDI_D_IO))
+#define ICL_DDI_IO_E_POWER_DOMAINS ( \
+ BIT_ULL(POWER_DOMAIN_PORT_DDI_E_IO))
+#define ICL_DDI_IO_F_POWER_DOMAINS ( \
+ BIT_ULL(POWER_DOMAIN_PORT_DDI_F_IO))
+
+#define ICL_AUX_A_IO_POWER_DOMAINS ( \
+ BIT_ULL(POWER_DOMAIN_AUX_A))
+#define ICL_AUX_B_IO_POWER_DOMAINS ( \
+ BIT_ULL(POWER_DOMAIN_AUX_B))
+#define ICL_AUX_C_IO_POWER_DOMAINS ( \
+ BIT_ULL(POWER_DOMAIN_AUX_C))
+#define ICL_AUX_D_IO_POWER_DOMAINS ( \
+ BIT_ULL(POWER_DOMAIN_AUX_D))
+#define ICL_AUX_E_IO_POWER_DOMAINS ( \
+ BIT_ULL(POWER_DOMAIN_AUX_E))
+#define ICL_AUX_F_IO_POWER_DOMAINS ( \
+ BIT_ULL(POWER_DOMAIN_AUX_F))
+#define ICL_AUX_TBT1_IO_POWER_DOMAINS ( \
+ BIT_ULL(POWER_DOMAIN_AUX_TBT1))
+#define ICL_AUX_TBT2_IO_POWER_DOMAINS ( \
+ BIT_ULL(POWER_DOMAIN_AUX_TBT2))
+#define ICL_AUX_TBT3_IO_POWER_DOMAINS ( \
+ BIT_ULL(POWER_DOMAIN_AUX_TBT3))
+#define ICL_AUX_TBT4_IO_POWER_DOMAINS ( \
+ BIT_ULL(POWER_DOMAIN_AUX_TBT4))
+
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,
@@ -2454,6 +2599,157 @@ static struct i915_power_well cnl_power_wells[] = {
},
};
+static const struct i915_power_well_ops icl_combo_phy_aux_power_well_ops = {
+ .sync_hw = hsw_power_well_sync_hw,
+ .enable = icl_combo_phy_aux_power_well_enable,
+ .disable = icl_combo_phy_aux_power_well_disable,
+ .is_enabled = hsw_power_well_enabled,
+};
+
+static struct i915_power_well icl_power_wells[] = {
+ {
+ .name = "always-on",
+ .always_on = 1,
+ .domains = POWER_DOMAIN_MASK,
+ .ops = &i9xx_always_on_power_well_ops,
+ .id = I915_DISP_PW_ALWAYS_ON,
+ },
+ {
+ .name = "power well 1",
+ /* Handled by the DMC firmware */
+ .domains = 0,
+ .ops = &hsw_power_well_ops,
+ .id = ICL_DISP_PW_1,
+ .hsw.has_fuses = true,
+ },
+ {
+ .name = "power well 2",
+ .domains = ICL_PW_2_POWER_DOMAINS,
+ .ops = &hsw_power_well_ops,
+ .id = ICL_DISP_PW_2,
+ .hsw.has_fuses = true,
+ },
+ {
+ .name = "DC off",
+ .domains = ICL_DISPLAY_DC_OFF_POWER_DOMAINS,
+ .ops = &gen9_dc_off_power_well_ops,
+ .id = SKL_DISP_PW_DC_OFF,
+ },
+ {
+ .name = "power well 3",
+ .domains = ICL_PW_3_POWER_DOMAINS,
+ .ops = &hsw_power_well_ops,
+ .id = ICL_DISP_PW_3,
+ .hsw.irq_pipe_mask = BIT(PIPE_B),
+ .hsw.has_vga = true,
+ .hsw.has_fuses = true,
+ },
+ {
+ .name = "DDI A IO",
+ .domains = ICL_DDI_IO_A_POWER_DOMAINS,
+ .ops = &hsw_power_well_ops,
+ .id = ICL_DISP_PW_DDI_A,
+ },
+ {
+ .name = "DDI B IO",
+ .domains = ICL_DDI_IO_B_POWER_DOMAINS,
+ .ops = &hsw_power_well_ops,
+ .id = ICL_DISP_PW_DDI_B,
+ },
+ {
+ .name = "DDI C IO",
+ .domains = ICL_DDI_IO_C_POWER_DOMAINS,
+ .ops = &hsw_power_well_ops,
+ .id = ICL_DISP_PW_DDI_C,
+ },
+ {
+ .name = "DDI D IO",
+ .domains = ICL_DDI_IO_D_POWER_DOMAINS,
+ .ops = &hsw_power_well_ops,
+ .id = ICL_DISP_PW_DDI_D,
+ },
+ {
+ .name = "DDI E IO",
+ .domains = ICL_DDI_IO_E_POWER_DOMAINS,
+ .ops = &hsw_power_well_ops,
+ .id = ICL_DISP_PW_DDI_E,
+ },
+ {
+ .name = "DDI F IO",
+ .domains = ICL_DDI_IO_F_POWER_DOMAINS,
+ .ops = &hsw_power_well_ops,
+ .id = ICL_DISP_PW_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,
+ },
+ {
+ .name = "AUX B",
+ .domains = ICL_AUX_B_IO_POWER_DOMAINS,
+ .ops = &icl_combo_phy_aux_power_well_ops,
+ .id = ICL_DISP_PW_AUX_B,
+ },
+ {
+ .name = "AUX C",
+ .domains = ICL_AUX_C_IO_POWER_DOMAINS,
+ .ops = &hsw_power_well_ops,
+ .id = ICL_DISP_PW_AUX_C,
+ },
+ {
+ .name = "AUX D",
+ .domains = ICL_AUX_D_IO_POWER_DOMAINS,
+ .ops = &hsw_power_well_ops,
+ .id = ICL_DISP_PW_AUX_D,
+ },
+ {
+ .name = "AUX E",
+ .domains = ICL_AUX_E_IO_POWER_DOMAINS,
+ .ops = &hsw_power_well_ops,
+ .id = ICL_DISP_PW_AUX_E,
+ },
+ {
+ .name = "AUX F",
+ .domains = ICL_AUX_F_IO_POWER_DOMAINS,
+ .ops = &hsw_power_well_ops,
+ .id = ICL_DISP_PW_AUX_F,
+ },
+ {
+ .name = "AUX TBT1",
+ .domains = ICL_AUX_TBT1_IO_POWER_DOMAINS,
+ .ops = &hsw_power_well_ops,
+ .id = ICL_DISP_PW_AUX_TBT1,
+ },
+ {
+ .name = "AUX TBT2",
+ .domains = ICL_AUX_TBT2_IO_POWER_DOMAINS,
+ .ops = &hsw_power_well_ops,
+ .id = ICL_DISP_PW_AUX_TBT2,
+ },
+ {
+ .name = "AUX TBT3",
+ .domains = ICL_AUX_TBT3_IO_POWER_DOMAINS,
+ .ops = &hsw_power_well_ops,
+ .id = ICL_DISP_PW_AUX_TBT3,
+ },
+ {
+ .name = "AUX TBT4",
+ .domains = ICL_AUX_TBT4_IO_POWER_DOMAINS,
+ .ops = &hsw_power_well_ops,
+ .id = ICL_DISP_PW_AUX_TBT4,
+ },
+ {
+ .name = "power well 4",
+ .domains = ICL_PW_4_POWER_DOMAINS,
+ .ops = &hsw_power_well_ops,
+ .id = ICL_DISP_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)
@@ -2471,7 +2767,7 @@ static uint32_t get_allowed_dc_mask(const struct drm_i915_private *dev_priv,
int requested_dc;
int max_dc;
- if (IS_GEN9_BC(dev_priv) || IS_CANNONLAKE(dev_priv)) {
+ if (IS_GEN9_BC(dev_priv) || INTEL_INFO(dev_priv)->gen >= 10) {
max_dc = 2;
mask = 0;
} else if (IS_GEN9_LP(dev_priv)) {
@@ -2559,7 +2855,9 @@ 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_HASWELL(dev_priv)) {
+ if (IS_ICELAKE(dev_priv)) {
+ set_power_wells(power_domains, icl_power_wells);
+ } else if (IS_HASWELL(dev_priv)) {
set_power_wells(power_domains, hsw_power_wells);
} else if (IS_BROADWELL(dev_priv)) {
set_power_wells(power_domains, bdw_power_wells);
@@ -3026,6 +3324,8 @@ static void cnl_display_core_uninit(struct drm_i915_private *dev_priv)
static void icl_display_core_init(struct drm_i915_private *dev_priv,
bool resume)
{
+ struct i915_power_domains *power_domains = &dev_priv->power_domains;
+ struct i915_power_well *well;
enum port port;
u32 val;
@@ -3054,8 +3354,14 @@ static void icl_display_core_init(struct drm_i915_private *dev_priv,
I915_WRITE(ICL_PORT_CL_DW5(port), val);
}
- /* 4. Enable power well 1 (PG1) and aux IO power. */
- /* FIXME: ICL power wells code not here yet. */
+ /*
+ * 4. Enable Power Well 1 (PG1).
+ * The AUX IO power wells will be enabled on demand.
+ */
+ mutex_lock(&power_domains->lock);
+ well = lookup_power_well(dev_priv, ICL_DISP_PW_1);
+ intel_power_well_enable(dev_priv, well);
+ mutex_unlock(&power_domains->lock);
/* 5. Enable CDCLK. */
icl_init_cdclk(dev_priv);
@@ -3073,6 +3379,8 @@ static void icl_display_core_init(struct drm_i915_private *dev_priv,
static void icl_display_core_uninit(struct drm_i915_private *dev_priv)
{
+ struct i915_power_domains *power_domains = &dev_priv->power_domains;
+ struct i915_power_well *well;
enum port port;
u32 val;
@@ -3086,8 +3394,15 @@ static void icl_display_core_uninit(struct drm_i915_private *dev_priv)
/* 3. Disable CD clock */
icl_uninit_cdclk(dev_priv);
- /* 4. Disable Power Well 1 (PG1) and Aux IO Power */
- /* FIXME: ICL power wells code not here yet. */
+ /*
+ * 4. Disable Power Well 1 (PG1).
+ * The AUX IO power wells are toggled on demand, so they are already
+ * disabled at this point.
+ */
+ mutex_lock(&power_domains->lock);
+ well = lookup_power_well(dev_priv, ICL_DISP_PW_1);
+ intel_power_well_disable(dev_priv, well);
+ mutex_unlock(&power_domains->lock);
/* 5. Disable Comp */
for (port = PORT_A; port <= PORT_B; port++) {
--
2.13.2
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx
^ permalink raw reply related [flat|nested] 9+ messages in thread* ✗ Fi.CI.CHECKPATCH: warning for drm/i915/icl: Add power well support 2018-06-26 14:22 [PATCH] drm/i915/icl: Add power well support Imre Deak @ 2018-06-26 14:47 ` Patchwork 2018-06-26 15:05 ` ✓ Fi.CI.BAT: success " Patchwork ` (2 subsequent siblings) 3 siblings, 0 replies; 9+ messages in thread From: Patchwork @ 2018-06-26 14:47 UTC (permalink / raw) To: Imre Deak; +Cc: intel-gfx == Series Details == Series: drm/i915/icl: Add power well support URL : https://patchwork.freedesktop.org/series/45409/ State : warning == Summary == $ dim checkpatch origin/drm-tip 409dfff082a1 drm/i915/icl: Add power well support -:17: WARNING:COMMIT_LOG_LONG_LINE: Possible unwrapped commit description (prefer a maximum 75 chars per line) #17: - Pipe C has its own power well, so we can save some additional power in the -:326: WARNING:BLOCK_COMMENT_STYLE: Block comments should align the * on each line #326: FILE: drivers/gpu/drm/i915/intel_runtime_pm.c:1995: + /* + * - transcoder WD -:333: WARNING:BLOCK_COMMENT_STYLE: Block comments should align the * on each line #333: FILE: drivers/gpu/drm/i915/intel_runtime_pm.c:2002: + /* + * - eDP/DSI VDSC total: 0 errors, 3 warnings, 0 checks, 536 lines checked _______________________________________________ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/intel-gfx ^ permalink raw reply [flat|nested] 9+ messages in thread
* ✓ Fi.CI.BAT: success for drm/i915/icl: Add power well support 2018-06-26 14:22 [PATCH] drm/i915/icl: Add power well support Imre Deak 2018-06-26 14:47 ` ✗ Fi.CI.CHECKPATCH: warning for " Patchwork @ 2018-06-26 15:05 ` Patchwork 2018-06-26 16:12 ` ✓ Fi.CI.IGT: " Patchwork 2018-06-27 0:28 ` [PATCH] " Paulo Zanoni 3 siblings, 0 replies; 9+ messages in thread From: Patchwork @ 2018-06-26 15:05 UTC (permalink / raw) To: Imre Deak; +Cc: intel-gfx == Series Details == Series: drm/i915/icl: Add power well support URL : https://patchwork.freedesktop.org/series/45409/ State : success == Summary == = CI Bug Log - changes from CI_DRM_4380 -> Patchwork_9424 = == Summary - SUCCESS == No regressions found. External URL: https://patchwork.freedesktop.org/api/1.0/series/45409/revisions/1/mbox/ == Known issues == Here are the changes found in Patchwork_9424 that come from known issues: === IGT changes === ==== Possible fixes ==== igt@gem_basic@bad-close: fi-skl-6770hq: DMESG-WARN (fdo#105541) -> PASS fdo#105541 https://bugs.freedesktop.org/show_bug.cgi?id=105541 == Participating hosts (44 -> 39) == Missing (5): fi-ctg-p8600 fi-ilk-m540 fi-byt-squawks fi-bsw-cyan fi-hsw-4200u == Build changes == * Linux: CI_DRM_4380 -> Patchwork_9424 CI_DRM_4380: e69a5560b14d9c7377744267ffd9963f06734f38 @ git://anongit.freedesktop.org/gfx-ci/linux IGT_4530: 0e98bf69f146eb72fe3a7c3b19a049b5786f0ca3 @ git://anongit.freedesktop.org/xorg/app/intel-gpu-tools Patchwork_9424: 409dfff082a1aca653c41e87af092e1e12e2673d @ git://anongit.freedesktop.org/gfx-ci/linux == Linux commits == 409dfff082a1 drm/i915/icl: Add power well support == Logs == For more details see: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_9424/issues.html _______________________________________________ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/intel-gfx ^ permalink raw reply [flat|nested] 9+ messages in thread
* ✓ Fi.CI.IGT: success for drm/i915/icl: Add power well support 2018-06-26 14:22 [PATCH] drm/i915/icl: Add power well support Imre Deak 2018-06-26 14:47 ` ✗ Fi.CI.CHECKPATCH: warning for " Patchwork 2018-06-26 15:05 ` ✓ Fi.CI.BAT: success " Patchwork @ 2018-06-26 16:12 ` Patchwork 2018-06-27 13:09 ` Imre Deak 2018-06-27 0:28 ` [PATCH] " Paulo Zanoni 3 siblings, 1 reply; 9+ messages in thread From: Patchwork @ 2018-06-26 16:12 UTC (permalink / raw) To: Imre Deak; +Cc: intel-gfx == Series Details == Series: drm/i915/icl: Add power well support URL : https://patchwork.freedesktop.org/series/45409/ State : success == Summary == = CI Bug Log - changes from CI_DRM_4380_full -> Patchwork_9424_full = == Summary - WARNING == Minor unknown changes coming with Patchwork_9424_full need to be verified manually. If you think the reported changes have nothing to do with the changes introduced in Patchwork_9424_full, please notify your bug team to allow them to document this new failure mode, which will reduce false positives in CI. == Possible new issues == Here are the unknown changes that may have been introduced in Patchwork_9424_full: === IGT changes === ==== Warnings ==== igt@gem_exec_schedule@deep-bsd2: shard-kbl: SKIP -> PASS igt@gem_exec_schedule@deep-vebox: shard-kbl: PASS -> SKIP == Known issues == Here are the changes found in Patchwork_9424_full that come from known issues: === IGT changes === ==== Issues hit ==== igt@drv_selftest@live_hangcheck: shard-apl: PASS -> DMESG-FAIL (fdo#106947, fdo#106560) igt@kms_atomic_transition@1x-modeset-transitions-nonblocking: shard-glk: PASS -> FAIL (fdo#105703) igt@kms_flip@2x-flip-vs-expired-vblank: shard-glk: PASS -> FAIL (fdo#105363) igt@kms_flip_tiling@flip-x-tiled: shard-glk: PASS -> FAIL (fdo#103822, fdo#104724) ==== Possible fixes ==== igt@drv_selftest@live_hangcheck: shard-kbl: DMESG-FAIL (fdo#106947, fdo#106560) -> PASS igt@gem_ctx_isolation@rcs0-s3: shard-kbl: INCOMPLETE (fdo#103665) -> PASS igt@kms_flip@plain-flip-ts-check-interruptible: shard-glk: FAIL (fdo#100368) -> PASS +1 igt@kms_flip_tiling@flip-y-tiled: shard-glk: FAIL (fdo#104724) -> PASS ==== Warnings ==== igt@drv_selftest@live_gtt: shard-glk: FAIL (fdo#105347) -> INCOMPLETE (k.org#198133, fdo#103359) fdo#100368 https://bugs.freedesktop.org/show_bug.cgi?id=100368 fdo#103359 https://bugs.freedesktop.org/show_bug.cgi?id=103359 fdo#103665 https://bugs.freedesktop.org/show_bug.cgi?id=103665 fdo#103822 https://bugs.freedesktop.org/show_bug.cgi?id=103822 fdo#104724 https://bugs.freedesktop.org/show_bug.cgi?id=104724 fdo#105347 https://bugs.freedesktop.org/show_bug.cgi?id=105347 fdo#105363 https://bugs.freedesktop.org/show_bug.cgi?id=105363 fdo#105703 https://bugs.freedesktop.org/show_bug.cgi?id=105703 fdo#106560 https://bugs.freedesktop.org/show_bug.cgi?id=106560 fdo#106947 https://bugs.freedesktop.org/show_bug.cgi?id=106947 k.org#198133 https://bugzilla.kernel.org/show_bug.cgi?id=198133 == Participating hosts (5 -> 5) == No changes in participating hosts == Build changes == * Linux: CI_DRM_4380 -> Patchwork_9424 CI_DRM_4380: e69a5560b14d9c7377744267ffd9963f06734f38 @ git://anongit.freedesktop.org/gfx-ci/linux IGT_4530: 0e98bf69f146eb72fe3a7c3b19a049b5786f0ca3 @ git://anongit.freedesktop.org/xorg/app/intel-gpu-tools Patchwork_9424: 409dfff082a1aca653c41e87af092e1e12e2673d @ git://anongit.freedesktop.org/gfx-ci/linux piglit_4509: fdc5a4ca11124ab8413c7988896eec4c97336694 @ git://anongit.freedesktop.org/piglit == Logs == For more details see: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_9424/shards.html _______________________________________________ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/intel-gfx ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: ✓ Fi.CI.IGT: success for drm/i915/icl: Add power well support 2018-06-26 16:12 ` ✓ Fi.CI.IGT: " Patchwork @ 2018-06-27 13:09 ` Imre Deak 2018-06-27 13:52 ` Jani Nikula 0 siblings, 1 reply; 9+ messages in thread From: Imre Deak @ 2018-06-27 13:09 UTC (permalink / raw) To: intel-gfx, Animesh Manna, Paulo Zanoni, Rakshmi Bhatia On Tue, Jun 26, 2018 at 04:12:24PM +0000, Patchwork wrote: > == Series Details == > > Series: drm/i915/icl: Add power well support > URL : https://patchwork.freedesktop.org/series/45409/ > State : success Pushed it to -dinq with the s/_PICK(_MMIO())/_MMIO_PORT()/ change and the checkpatch warnings fixed. Thanks for the reviews. > > == Summary == > > = CI Bug Log - changes from CI_DRM_4380_full -> Patchwork_9424_full = > > == Summary - WARNING == > > Minor unknown changes coming with Patchwork_9424_full need to be verified > manually. > > If you think the reported changes have nothing to do with the changes > introduced in Patchwork_9424_full, please notify your bug team to allow them > to document this new failure mode, which will reduce false positives in CI. > > > > == Possible new issues == > > Here are the unknown changes that may have been introduced in Patchwork_9424_full: > > === IGT changes === > > ==== Warnings ==== > > igt@gem_exec_schedule@deep-bsd2: > shard-kbl: SKIP -> PASS > > igt@gem_exec_schedule@deep-vebox: > shard-kbl: PASS -> SKIP > > > == Known issues == > > Here are the changes found in Patchwork_9424_full that come from known issues: > > === IGT changes === > > ==== Issues hit ==== > > igt@drv_selftest@live_hangcheck: > shard-apl: PASS -> DMESG-FAIL (fdo#106947, fdo#106560) > > igt@kms_atomic_transition@1x-modeset-transitions-nonblocking: > shard-glk: PASS -> FAIL (fdo#105703) > > igt@kms_flip@2x-flip-vs-expired-vblank: > shard-glk: PASS -> FAIL (fdo#105363) > > igt@kms_flip_tiling@flip-x-tiled: > shard-glk: PASS -> FAIL (fdo#103822, fdo#104724) > > > ==== Possible fixes ==== > > igt@drv_selftest@live_hangcheck: > shard-kbl: DMESG-FAIL (fdo#106947, fdo#106560) -> PASS > > igt@gem_ctx_isolation@rcs0-s3: > shard-kbl: INCOMPLETE (fdo#103665) -> PASS > > igt@kms_flip@plain-flip-ts-check-interruptible: > shard-glk: FAIL (fdo#100368) -> PASS +1 > > igt@kms_flip_tiling@flip-y-tiled: > shard-glk: FAIL (fdo#104724) -> PASS > > > ==== Warnings ==== > > igt@drv_selftest@live_gtt: > shard-glk: FAIL (fdo#105347) -> INCOMPLETE (k.org#198133, fdo#103359) > > > fdo#100368 https://bugs.freedesktop.org/show_bug.cgi?id=100368 > fdo#103359 https://bugs.freedesktop.org/show_bug.cgi?id=103359 > fdo#103665 https://bugs.freedesktop.org/show_bug.cgi?id=103665 > fdo#103822 https://bugs.freedesktop.org/show_bug.cgi?id=103822 > fdo#104724 https://bugs.freedesktop.org/show_bug.cgi?id=104724 > fdo#105347 https://bugs.freedesktop.org/show_bug.cgi?id=105347 > fdo#105363 https://bugs.freedesktop.org/show_bug.cgi?id=105363 > fdo#105703 https://bugs.freedesktop.org/show_bug.cgi?id=105703 > fdo#106560 https://bugs.freedesktop.org/show_bug.cgi?id=106560 > fdo#106947 https://bugs.freedesktop.org/show_bug.cgi?id=106947 > k.org#198133 https://bugzilla.kernel.org/show_bug.cgi?id=198133 > > > == Participating hosts (5 -> 5) == > > No changes in participating hosts > > > == Build changes == > > * Linux: CI_DRM_4380 -> Patchwork_9424 > > CI_DRM_4380: e69a5560b14d9c7377744267ffd9963f06734f38 @ git://anongit.freedesktop.org/gfx-ci/linux > IGT_4530: 0e98bf69f146eb72fe3a7c3b19a049b5786f0ca3 @ git://anongit.freedesktop.org/xorg/app/intel-gpu-tools > Patchwork_9424: 409dfff082a1aca653c41e87af092e1e12e2673d @ git://anongit.freedesktop.org/gfx-ci/linux > piglit_4509: fdc5a4ca11124ab8413c7988896eec4c97336694 @ git://anongit.freedesktop.org/piglit > > == Logs == > > For more details see: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_9424/shards.html _______________________________________________ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/intel-gfx ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: ✓ Fi.CI.IGT: success for drm/i915/icl: Add power well support 2018-06-27 13:09 ` Imre Deak @ 2018-06-27 13:52 ` Jani Nikula 2018-06-27 14:11 ` Imre Deak 0 siblings, 1 reply; 9+ messages in thread From: Jani Nikula @ 2018-06-27 13:52 UTC (permalink / raw) To: imre.deak, intel-gfx, Animesh Manna, Paulo Zanoni, Rakshmi Bhatia Cc: Rodrigo Vivi On Wed, 27 Jun 2018, Imre Deak <imre.deak@intel.com> wrote: > Pushed it to -dinq with the s/_PICK(_MMIO())/_MMIO_PORT()/ change and the > checkpatch warnings fixed. Thanks for the reviews. I'd prefer it if actual functional changes were resent to the list for CI instead of fixed in place. BR, Jani. -- Jani Nikula, Intel Open Source Graphics Center _______________________________________________ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/intel-gfx ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: ✓ Fi.CI.IGT: success for drm/i915/icl: Add power well support 2018-06-27 13:52 ` Jani Nikula @ 2018-06-27 14:11 ` Imre Deak 0 siblings, 0 replies; 9+ messages in thread From: Imre Deak @ 2018-06-27 14:11 UTC (permalink / raw) To: Jani Nikula; +Cc: Rodrigo Vivi, intel-gfx, Paulo Zanoni On Wed, Jun 27, 2018 at 04:52:27PM +0300, Jani Nikula wrote: > On Wed, 27 Jun 2018, Imre Deak <imre.deak@intel.com> wrote: > > Pushed it to -dinq with the s/_PICK(_MMIO())/_MMIO_PORT()/ change and the > > checkpatch warnings fixed. Thanks for the reviews. > > I'd prefer it if actual functional changes were resent to the list for > CI instead of fixed in place. Hm, I considered this a trivial change. Is there a rule that prevents any code changes while merging, or something saying what's considered trivial? > > BR, > Jani. > > -- > Jani Nikula, Intel Open Source Graphics Center _______________________________________________ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/intel-gfx ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH] drm/i915/icl: Add power well support 2018-06-26 14:22 [PATCH] drm/i915/icl: Add power well support Imre Deak ` (2 preceding siblings ...) 2018-06-26 16:12 ` ✓ Fi.CI.IGT: " Patchwork @ 2018-06-27 0:28 ` Paulo Zanoni 2018-06-27 11:59 ` Imre Deak 3 siblings, 1 reply; 9+ messages in thread From: Paulo Zanoni @ 2018-06-27 0:28 UTC (permalink / raw) To: Imre Deak, intel-gfx Em Ter, 2018-06-26 às 17:22 +0300, Imre Deak escreveu: > Add the definition for ICL power wells and their mapping to power > domains. On ICL there are 3 power well control registers, we'll > select > the correct one based on higher bits of the power well ID. The offset > for the control and status flags within this register is based on the > lower bits of the ID as on older platforms. > > As the DC state programming is also the same as on old platforms we > can > reuse the corresponding helpers. For this we mark here the DC-off > power > well as shared among multiple platforms. > > Other than the above the delta between old platforms and ICL: > - Pipe C has its own power well, so we can save some additional power > in the > pipe A+B and (non-eDP) pipe A configurations. > - Power wells for port E/F DDI/AUX IO and Thunderbolt 1-4 AUX IO > > v2: > - Rebase on drm-tip after prep patch for this was merged there as > requested by Paulo. > - Actually add the new AUX and DDI power well control regs (Rakshmi) > > v3: > - Fix power well register names in code comments > - Add TBT AUX->power well 3 dependency > > v4: > - Rebase > > v5: > - Detach AUX power wells from the INIT power domain. These power > wells > can only be enabled in a TC/TBT connected state and otherwise not > needed during driver initialization. > > Cc: Animesh Manna <animesh.manna@intel.com> > Cc: Rakshmi Bhatia <rakshmi.bhatia@intel.com> > Cc: Paulo Zanoni <paulo.r.zanoni@intel.com> > Signed-off-by: Imre Deak <imre.deak@intel.com> > Reviewed-by: Animesh Manna <animesh.manna@intel.com> (v1) > --- > drivers/gpu/drm/i915/i915_reg.h | 78 +++++++- > drivers/gpu/drm/i915/intel_display.h | 4 + > drivers/gpu/drm/i915/intel_runtime_pm.c | 329 > +++++++++++++++++++++++++++++++- > 3 files changed, 395 insertions(+), 16 deletions(-) > > diff --git a/drivers/gpu/drm/i915/i915_reg.h > b/drivers/gpu/drm/i915/i915_reg.h > index caad19f5f557..865b05ce8d76 100644 > --- a/drivers/gpu/drm/i915/i915_reg.h > +++ b/drivers/gpu/drm/i915/i915_reg.h > @@ -1045,13 +1045,13 @@ enum i915_power_well_id { > > /* > * HSW/BDW > - * - HSW_PWR_WELL_CTL_DRIVER(0) (status bit: id*2, req bit: > id*2+1) > + * - _HSW_PWR_WELL_CTL1-4 (status bit: id*2, req bit: > id*2+1) > */ > HSW_DISP_PW_GLOBAL = 15, > > /* > * GEN9+ > - * - HSW_PWR_WELL_CTL_DRIVER(0) (status bit: id*2, req bit: > id*2+1) > + * - _HSW_PWR_WELL_CTL1-4 (status bit: id*2, req bit: > id*2+1) > */ > SKL_DISP_PW_MISC_IO = 0, > SKL_DISP_PW_DDI_A_E, > @@ -1075,17 +1075,54 @@ enum i915_power_well_id { > SKL_DISP_PW_2, > > /* - custom power wells */ > - SKL_DISP_PW_DC_OFF, > BXT_DPIO_CMN_A, > BXT_DPIO_CMN_BC, > - GLK_DPIO_CMN_C, /* 19 */ > + GLK_DPIO_CMN_C, /* 18 */ > + > + /* > + * GEN11+ > + * - _HSW_PWR_WELL_CTL1-4 > + * (status bit: (id&15)*2, req bit:(id&15)*2+1) > + */ > + ICL_DISP_PW_1 = 0, > + ICL_DISP_PW_2, > + ICL_DISP_PW_3, > + ICL_DISP_PW_4, > + > + /* > + * - _HSW_PWR_WELL_CTL_AUX1/2/4 > + * (status bit: (id&15)*2, req bit:(id&15)*2+1) > + */ > + ICL_DISP_PW_AUX_A = 16, > + ICL_DISP_PW_AUX_B, > + ICL_DISP_PW_AUX_C, > + ICL_DISP_PW_AUX_D, > + ICL_DISP_PW_AUX_E, > + ICL_DISP_PW_AUX_F, > + > + ICL_DISP_PW_AUX_TBT1 = 24, > + ICL_DISP_PW_AUX_TBT2, > + ICL_DISP_PW_AUX_TBT3, > + ICL_DISP_PW_AUX_TBT4, > + > + /* > + * - _HSW_PWR_WELL_CTL_DDI1/2/4 > + * (status bit: (id&15)*2, req bit:(id&15)*2+1) > + */ > + ICL_DISP_PW_DDI_A = 32, > + ICL_DISP_PW_DDI_B, > + ICL_DISP_PW_DDI_C, > + ICL_DISP_PW_DDI_D, > + ICL_DISP_PW_DDI_E, > + ICL_DISP_PW_DDI_F, /* 37 */ > > /* > * Multiple platforms. > * Must start following the highest ID of any platform. > * - custom power wells > */ > - I915_DISP_PW_ALWAYS_ON = 20, > + SKL_DISP_PW_DC_OFF = 38, > + I915_DISP_PW_ALWAYS_ON, > }; > > #define PUNIT_REG_PWRGT_CTRL 0x60 > @@ -1679,6 +1716,13 @@ enum i915_power_well_id { > #define IREF1RC_OFFSET_MASK (0xFF << > IREF1RC_OFFSET_SHIFT) > #define BXT_PORT_CL1CM_DW10(phy) _BXT_PHY((phy), > _PORT_CL1CM_DW10_BC) > > +#define _ICL_PORT_CL_DW12_A 0x162030 > +#define _ICL_PORT_CL_DW12_B 0x6C030 > +#define ICL_LANE_ENABLE_AUX (1 << 0) > +#define ICL_PORT_CL_DW12(port) _MMIO(_PICK((port), You can get away with _PIPE instead of _PICK here, which is supposed to be a little more efficient. Otherwise, looks correct (minus checkpatch problems). Reviewed-by: Paulo Zanoni <paulo.r.zanoni@intel.com> But I would say the PW code is getting very hard to read. The whole magic behind the i915_power_well_id enum values is hard to read, and a lot of other magic macros build on top of that. I would really love if our code were a little more straightforward, less reliant on the magic, even if it were a little bigger. Stuff like _HSW_PW_REG_IDX() and others are crazy. Ideally the code would not have to rely on the value of the actual enum for anything. But all of that is content for a new series. > \ > + _ICL_PORT_CL_DW1 > 2_A, \ > + _ICL_PORT_CL_DW1 > 2_B)) > + > #define _PORT_CL1CM_DW28_A 0x162070 > #define _PORT_CL1CM_DW28_BC 0x6C070 > #define OCL1_POWER_DOWN_EN (1 << 23) > @@ -8563,6 +8607,14 @@ enum { > #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 > @@ -8572,14 +8624,20 @@ enum { > */ > #define _HSW_PW_REG_IDX(pw) ((pw) >> 4) > #define _HSW_PW_SHIFT(pw) (((pw) & 0xf) * 2) > -/* TODO: Add all PWR_WELL_CTL registers below for new platforms */ > #define HSW_PWR_WELL_CTL_BIOS(pw) _MMIO(_PICK(_HSW_PW_REG_IDX > (pw), \ > - _HSW_PWR_WELL_CT > L1)) > + _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)) > + _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)) > + _HSW_PWR_WELL_CT > L4, \ > + _ICL_PWR_WELL_CT > L_AUX4, \ > + _ICL_PWR_WELL_CT > L_DDI4)) > > #define HSW_PWR_WELL_CTL_REQ(pw) (1 << > (_HSW_PW_SHIFT(pw) + 1)) > #define HSW_PWR_WELL_CTL_STATE(pw) (1 << > _HSW_PW_SHIFT(pw)) > @@ -8600,6 +8658,8 @@ enum skl_power_gate { > #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) > #define SKL_FUSE_PG_DIST_STATUS(pg) (1 << (27 - > (pg))) > > #define _CNL_AUX_REG_IDX(pw) ((pw) - 9) > diff --git a/drivers/gpu/drm/i915/intel_display.h > b/drivers/gpu/drm/i915/intel_display.h > index dfb02da73ac8..a77dd29db2ec 100644 > --- a/drivers/gpu/drm/i915/intel_display.h > +++ b/drivers/gpu/drm/i915/intel_display.h > @@ -199,6 +199,10 @@ enum intel_display_power_domain { > POWER_DOMAIN_AUX_E, > POWER_DOMAIN_AUX_F, > POWER_DOMAIN_AUX_IO_A, > + POWER_DOMAIN_AUX_TBT1, > + POWER_DOMAIN_AUX_TBT2, > + POWER_DOMAIN_AUX_TBT3, > + POWER_DOMAIN_AUX_TBT4, > POWER_DOMAIN_GMBUS, > POWER_DOMAIN_MODESET, > POWER_DOMAIN_GT_IRQ, > diff --git a/drivers/gpu/drm/i915/intel_runtime_pm.c > b/drivers/gpu/drm/i915/intel_runtime_pm.c > index 2969787201ef..790670f5fb98 100644 > --- a/drivers/gpu/drm/i915/intel_runtime_pm.c > +++ b/drivers/gpu/drm/i915/intel_runtime_pm.c > @@ -134,6 +134,14 @@ intel_display_power_domain_str(enum > intel_display_power_domain domain) > return "AUX_F"; > case POWER_DOMAIN_AUX_IO_A: > return "AUX_IO_A"; > + case POWER_DOMAIN_AUX_TBT1: > + return "AUX_TBT1"; > + case POWER_DOMAIN_AUX_TBT2: > + return "AUX_TBT2"; > + case POWER_DOMAIN_AUX_TBT3: > + return "AUX_TBT3"; > + case POWER_DOMAIN_AUX_TBT4: > + return "AUX_TBT4"; > case POWER_DOMAIN_GMBUS: > return "GMBUS"; > case POWER_DOMAIN_INIT: > @@ -384,7 +392,8 @@ static void hsw_power_well_enable(struct > drm_i915_private *dev_priv, > u32 val; > > if (wait_fuses) { > - pg = SKL_PW_TO_PG(id); > + pg = INTEL_GEN(dev_priv) >= 11 ? ICL_PW_TO_PG(id) : > + SKL_PW_TO_PG(id); > /* > * For PW1 we have to wait both for the PW0/PG0 fuse > state > * before enabling the power well and PW1/PG1's own > fuse > @@ -430,6 +439,43 @@ static void hsw_power_well_disable(struct > drm_i915_private *dev_priv, > hsw_wait_for_power_well_disable(dev_priv, power_well); > } > > +#define ICL_AUX_PW_TO_PORT(pw) ((pw) - ICL_DISP_PW_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->id; > + enum port port = ICL_AUX_PW_TO_PORT(id); > + 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(ICL_PORT_CL_DW12(port)); > + I915_WRITE(ICL_PORT_CL_DW12(port), val | > ICL_LANE_ENABLE_AUX); > + > + hsw_wait_for_power_well_enable(dev_priv, power_well); > +} > + > +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->id; > + enum port port = ICL_AUX_PW_TO_PORT(id); > + 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)); > + > + hsw_wait_for_power_well_disable(dev_priv, power_well); > +} > + > /* > * We should only use the power well if we explicitly asked the > hardware to > * enable it, so check if it's enabled and also check if we've > requested it to > @@ -1897,6 +1943,105 @@ void intel_display_power_put(struct > drm_i915_private *dev_priv, > BIT_ULL(POWER_DOMAIN_AUX_A) | \ > BIT_ULL(POWER_DOMAIN_INIT)) > > +/* > + * ICL PW_0/PG_0 domains (HW/DMC control): > + * - PCI > + * - clocks except port PLL > + * - central power except FBC > + * - shared functions except pipe interrupts, pipe MBUS, DBUF > registers > + * ICL PW_1/PG_1 domains (HW/DMC control): > + * - DBUF function > + * - PIPE_A and its planes, except VGA > + * - transcoder EDP + PSR > + * - transcoder DSI > + * - DDI_A > + * - FBC > + */ > +#define ICL_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 ICL_PW_3_POWER_DOMAINS ( \ > + ICL_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_PORT_DDI_E_LANES) | \ > + BIT_ULL(POWER_DOMAIN_PORT_DDI_E_IO) | \ > + BIT_ULL(POWER_DOMAIN_PORT_DDI_F_LANES) | \ > + BIT_ULL(POWER_DOMAIN_PORT_DDI_F_IO) | \ > + BIT_ULL(POWER_DOMAIN_AUX_B) | \ > + BIT_ULL(POWER_DOMAIN_AUX_C) | \ > + BIT_ULL(POWER_DOMAIN_AUX_D) | \ > + BIT_ULL(POWER_DOMAIN_AUX_E) | \ > + BIT_ULL(POWER_DOMAIN_AUX_F) | \ > + BIT_ULL(POWER_DOMAIN_AUX_TBT1) | \ > + BIT_ULL(POWER_DOMAIN_AUX_TBT2) | \ > + BIT_ULL(POWER_DOMAIN_AUX_TBT3) | \ > + BIT_ULL(POWER_DOMAIN_AUX_TBT4) | \ > + BIT_ULL(POWER_DOMAIN_VGA) | \ > + BIT_ULL(POWER_DOMAIN_AUDIO) | \ > + BIT_ULL(POWER_DOMAIN_INIT)) > + /* > + * - transcoder WD > + * - KVMR (HW control) > + */ > +#define ICL_PW_2_POWER_DOMAINS ( \ > + ICL_PW_3_POWER_DOMAINS | \ > + BIT_ULL(POWER_DOMAIN_INIT)) > + /* > + * - eDP/DSI VDSC > + * - KVMR (HW control) > + */ > +#define ICL_DISPLAY_DC_OFF_POWER_DOMAINS ( \ > + ICL_PW_2_POWER_DOMAINS | \ > + BIT_ULL(POWER_DOMAIN_MODESET) | \ > + BIT_ULL(POWER_DOMAIN_AUX_A) | \ > + BIT_ULL(POWER_DOMAIN_INIT)) > + > +#define ICL_DDI_IO_A_POWER_DOMAINS ( \ > + BIT_ULL(POWER_DOMAIN_PORT_DDI_A_IO)) > +#define ICL_DDI_IO_B_POWER_DOMAINS ( \ > + BIT_ULL(POWER_DOMAIN_PORT_DDI_B_IO)) > +#define ICL_DDI_IO_C_POWER_DOMAINS ( \ > + BIT_ULL(POWER_DOMAIN_PORT_DDI_C_IO)) > +#define ICL_DDI_IO_D_POWER_DOMAINS ( \ > + BIT_ULL(POWER_DOMAIN_PORT_DDI_D_IO)) > +#define ICL_DDI_IO_E_POWER_DOMAINS ( \ > + BIT_ULL(POWER_DOMAIN_PORT_DDI_E_IO)) > +#define ICL_DDI_IO_F_POWER_DOMAINS ( \ > + BIT_ULL(POWER_DOMAIN_PORT_DDI_F_IO)) > + > +#define ICL_AUX_A_IO_POWER_DOMAINS ( \ > + BIT_ULL(POWER_DOMAIN_AUX_A)) > +#define ICL_AUX_B_IO_POWER_DOMAINS ( \ > + BIT_ULL(POWER_DOMAIN_AUX_B)) > +#define ICL_AUX_C_IO_POWER_DOMAINS ( \ > + BIT_ULL(POWER_DOMAIN_AUX_C)) > +#define ICL_AUX_D_IO_POWER_DOMAINS ( \ > + BIT_ULL(POWER_DOMAIN_AUX_D)) > +#define ICL_AUX_E_IO_POWER_DOMAINS ( \ > + BIT_ULL(POWER_DOMAIN_AUX_E)) > +#define ICL_AUX_F_IO_POWER_DOMAINS ( \ > + BIT_ULL(POWER_DOMAIN_AUX_F)) > +#define ICL_AUX_TBT1_IO_POWER_DOMAINS ( \ > + BIT_ULL(POWER_DOMAIN_AUX_TBT1)) > +#define ICL_AUX_TBT2_IO_POWER_DOMAINS ( \ > + BIT_ULL(POWER_DOMAIN_AUX_TBT2)) > +#define ICL_AUX_TBT3_IO_POWER_DOMAINS ( \ > + BIT_ULL(POWER_DOMAIN_AUX_TBT3)) > +#define ICL_AUX_TBT4_IO_POWER_DOMAINS ( \ > + BIT_ULL(POWER_DOMAIN_AUX_TBT4)) > + > 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, > @@ -2454,6 +2599,157 @@ static struct i915_power_well > cnl_power_wells[] = { > }, > }; > > +static const struct i915_power_well_ops > icl_combo_phy_aux_power_well_ops = { > + .sync_hw = hsw_power_well_sync_hw, > + .enable = icl_combo_phy_aux_power_well_enable, > + .disable = icl_combo_phy_aux_power_well_disable, > + .is_enabled = hsw_power_well_enabled, > +}; > + > +static struct i915_power_well icl_power_wells[] = { > + { > + .name = "always-on", > + .always_on = 1, > + .domains = POWER_DOMAIN_MASK, > + .ops = &i9xx_always_on_power_well_ops, > + .id = I915_DISP_PW_ALWAYS_ON, > + }, > + { > + .name = "power well 1", > + /* Handled by the DMC firmware */ > + .domains = 0, > + .ops = &hsw_power_well_ops, > + .id = ICL_DISP_PW_1, > + .hsw.has_fuses = true, > + }, > + { > + .name = "power well 2", > + .domains = ICL_PW_2_POWER_DOMAINS, > + .ops = &hsw_power_well_ops, > + .id = ICL_DISP_PW_2, > + .hsw.has_fuses = true, > + }, > + { > + .name = "DC off", > + .domains = ICL_DISPLAY_DC_OFF_POWER_DOMAINS, > + .ops = &gen9_dc_off_power_well_ops, > + .id = SKL_DISP_PW_DC_OFF, > + }, > + { > + .name = "power well 3", > + .domains = ICL_PW_3_POWER_DOMAINS, > + .ops = &hsw_power_well_ops, > + .id = ICL_DISP_PW_3, > + .hsw.irq_pipe_mask = BIT(PIPE_B), > + .hsw.has_vga = true, > + .hsw.has_fuses = true, > + }, > + { > + .name = "DDI A IO", > + .domains = ICL_DDI_IO_A_POWER_DOMAINS, > + .ops = &hsw_power_well_ops, > + .id = ICL_DISP_PW_DDI_A, > + }, > + { > + .name = "DDI B IO", > + .domains = ICL_DDI_IO_B_POWER_DOMAINS, > + .ops = &hsw_power_well_ops, > + .id = ICL_DISP_PW_DDI_B, > + }, > + { > + .name = "DDI C IO", > + .domains = ICL_DDI_IO_C_POWER_DOMAINS, > + .ops = &hsw_power_well_ops, > + .id = ICL_DISP_PW_DDI_C, > + }, > + { > + .name = "DDI D IO", > + .domains = ICL_DDI_IO_D_POWER_DOMAINS, > + .ops = &hsw_power_well_ops, > + .id = ICL_DISP_PW_DDI_D, > + }, > + { > + .name = "DDI E IO", > + .domains = ICL_DDI_IO_E_POWER_DOMAINS, > + .ops = &hsw_power_well_ops, > + .id = ICL_DISP_PW_DDI_E, > + }, > + { > + .name = "DDI F IO", > + .domains = ICL_DDI_IO_F_POWER_DOMAINS, > + .ops = &hsw_power_well_ops, > + .id = ICL_DISP_PW_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, > + }, > + { > + .name = "AUX B", > + .domains = ICL_AUX_B_IO_POWER_DOMAINS, > + .ops = &icl_combo_phy_aux_power_well_ops, > + .id = ICL_DISP_PW_AUX_B, > + }, > + { > + .name = "AUX C", > + .domains = ICL_AUX_C_IO_POWER_DOMAINS, > + .ops = &hsw_power_well_ops, > + .id = ICL_DISP_PW_AUX_C, > + }, > + { > + .name = "AUX D", > + .domains = ICL_AUX_D_IO_POWER_DOMAINS, > + .ops = &hsw_power_well_ops, > + .id = ICL_DISP_PW_AUX_D, > + }, > + { > + .name = "AUX E", > + .domains = ICL_AUX_E_IO_POWER_DOMAINS, > + .ops = &hsw_power_well_ops, > + .id = ICL_DISP_PW_AUX_E, > + }, > + { > + .name = "AUX F", > + .domains = ICL_AUX_F_IO_POWER_DOMAINS, > + .ops = &hsw_power_well_ops, > + .id = ICL_DISP_PW_AUX_F, > + }, > + { > + .name = "AUX TBT1", > + .domains = ICL_AUX_TBT1_IO_POWER_DOMAINS, > + .ops = &hsw_power_well_ops, > + .id = ICL_DISP_PW_AUX_TBT1, > + }, > + { > + .name = "AUX TBT2", > + .domains = ICL_AUX_TBT2_IO_POWER_DOMAINS, > + .ops = &hsw_power_well_ops, > + .id = ICL_DISP_PW_AUX_TBT2, > + }, > + { > + .name = "AUX TBT3", > + .domains = ICL_AUX_TBT3_IO_POWER_DOMAINS, > + .ops = &hsw_power_well_ops, > + .id = ICL_DISP_PW_AUX_TBT3, > + }, > + { > + .name = "AUX TBT4", > + .domains = ICL_AUX_TBT4_IO_POWER_DOMAINS, > + .ops = &hsw_power_well_ops, > + .id = ICL_DISP_PW_AUX_TBT4, > + }, > + { > + .name = "power well 4", > + .domains = ICL_PW_4_POWER_DOMAINS, > + .ops = &hsw_power_well_ops, > + .id = ICL_DISP_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) > @@ -2471,7 +2767,7 @@ static uint32_t get_allowed_dc_mask(const > struct drm_i915_private *dev_priv, > int requested_dc; > int max_dc; > > - if (IS_GEN9_BC(dev_priv) || IS_CANNONLAKE(dev_priv)) { > + if (IS_GEN9_BC(dev_priv) || INTEL_INFO(dev_priv)->gen >= 10) > { > max_dc = 2; > mask = 0; > } else if (IS_GEN9_LP(dev_priv)) { > @@ -2559,7 +2855,9 @@ 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_HASWELL(dev_priv)) { > + if (IS_ICELAKE(dev_priv)) { > + set_power_wells(power_domains, icl_power_wells); > + } else if (IS_HASWELL(dev_priv)) { > set_power_wells(power_domains, hsw_power_wells); > } else if (IS_BROADWELL(dev_priv)) { > set_power_wells(power_domains, bdw_power_wells); > @@ -3026,6 +3324,8 @@ static void cnl_display_core_uninit(struct > drm_i915_private *dev_priv) > static void icl_display_core_init(struct drm_i915_private *dev_priv, > bool resume) > { > + struct i915_power_domains *power_domains = &dev_priv- > >power_domains; > + struct i915_power_well *well; > enum port port; > u32 val; > > @@ -3054,8 +3354,14 @@ static void icl_display_core_init(struct > drm_i915_private *dev_priv, > I915_WRITE(ICL_PORT_CL_DW5(port), val); > } > > - /* 4. Enable power well 1 (PG1) and aux IO power. */ > - /* FIXME: ICL power wells code not here yet. */ > + /* > + * 4. Enable Power Well 1 (PG1). > + * The AUX IO power wells will be enabled on demand. > + */ > + mutex_lock(&power_domains->lock); > + well = lookup_power_well(dev_priv, ICL_DISP_PW_1); > + intel_power_well_enable(dev_priv, well); > + mutex_unlock(&power_domains->lock); > > /* 5. Enable CDCLK. */ > icl_init_cdclk(dev_priv); > @@ -3073,6 +3379,8 @@ static void icl_display_core_init(struct > drm_i915_private *dev_priv, > > static void icl_display_core_uninit(struct drm_i915_private > *dev_priv) > { > + struct i915_power_domains *power_domains = &dev_priv- > >power_domains; > + struct i915_power_well *well; > enum port port; > u32 val; > > @@ -3086,8 +3394,15 @@ static void icl_display_core_uninit(struct > drm_i915_private *dev_priv) > /* 3. Disable CD clock */ > icl_uninit_cdclk(dev_priv); > > - /* 4. Disable Power Well 1 (PG1) and Aux IO Power */ > - /* FIXME: ICL power wells code not here yet. */ > + /* > + * 4. Disable Power Well 1 (PG1). > + * The AUX IO power wells are toggled on demand, so they > are already > + * disabled at this point. > + */ > + mutex_lock(&power_domains->lock); > + well = lookup_power_well(dev_priv, ICL_DISP_PW_1); > + intel_power_well_disable(dev_priv, well); > + mutex_unlock(&power_domains->lock); > > /* 5. Disable Comp */ > for (port = PORT_A; port <= PORT_B; port++) { _______________________________________________ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/intel-gfx ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH] drm/i915/icl: Add power well support 2018-06-27 0:28 ` [PATCH] " Paulo Zanoni @ 2018-06-27 11:59 ` Imre Deak 0 siblings, 0 replies; 9+ messages in thread From: Imre Deak @ 2018-06-27 11:59 UTC (permalink / raw) To: Paulo Zanoni; +Cc: intel-gfx On Tue, Jun 26, 2018 at 05:28:06PM -0700, Paulo Zanoni wrote: > Em Ter, 2018-06-26 às 17:22 +0300, Imre Deak escreveu: > > Add the definition for ICL power wells and their mapping to power > > domains. On ICL there are 3 power well control registers, we'll > > select > > the correct one based on higher bits of the power well ID. The offset > > for the control and status flags within this register is based on the > > lower bits of the ID as on older platforms. > > > > As the DC state programming is also the same as on old platforms we > > can > > reuse the corresponding helpers. For this we mark here the DC-off > > power > > well as shared among multiple platforms. > > > > Other than the above the delta between old platforms and ICL: > > - Pipe C has its own power well, so we can save some additional power > > in the > > pipe A+B and (non-eDP) pipe A configurations. > > - Power wells for port E/F DDI/AUX IO and Thunderbolt 1-4 AUX IO > > > > v2: > > - Rebase on drm-tip after prep patch for this was merged there as > > requested by Paulo. > > - Actually add the new AUX and DDI power well control regs (Rakshmi) > > > > v3: > > - Fix power well register names in code comments > > - Add TBT AUX->power well 3 dependency > > > > v4: > > - Rebase > > > > v5: > > - Detach AUX power wells from the INIT power domain. These power > > wells > > can only be enabled in a TC/TBT connected state and otherwise not > > needed during driver initialization. > > > > Cc: Animesh Manna <animesh.manna@intel.com> > > Cc: Rakshmi Bhatia <rakshmi.bhatia@intel.com> > > Cc: Paulo Zanoni <paulo.r.zanoni@intel.com> > > Signed-off-by: Imre Deak <imre.deak@intel.com> > > Reviewed-by: Animesh Manna <animesh.manna@intel.com> (v1) > > --- > > drivers/gpu/drm/i915/i915_reg.h | 78 +++++++- > > drivers/gpu/drm/i915/intel_display.h | 4 + > > drivers/gpu/drm/i915/intel_runtime_pm.c | 329 > > +++++++++++++++++++++++++++++++- > > 3 files changed, 395 insertions(+), 16 deletions(-) > > > > diff --git a/drivers/gpu/drm/i915/i915_reg.h > > b/drivers/gpu/drm/i915/i915_reg.h > > index caad19f5f557..865b05ce8d76 100644 > > --- a/drivers/gpu/drm/i915/i915_reg.h > > +++ b/drivers/gpu/drm/i915/i915_reg.h > > @@ -1045,13 +1045,13 @@ enum i915_power_well_id { > > > > /* > > * HSW/BDW > > - * - HSW_PWR_WELL_CTL_DRIVER(0) (status bit: id*2, req bit: > > id*2+1) > > + * - _HSW_PWR_WELL_CTL1-4 (status bit: id*2, req bit: > > id*2+1) > > */ > > HSW_DISP_PW_GLOBAL = 15, > > > > /* > > * GEN9+ > > - * - HSW_PWR_WELL_CTL_DRIVER(0) (status bit: id*2, req bit: > > id*2+1) > > + * - _HSW_PWR_WELL_CTL1-4 (status bit: id*2, req bit: > > id*2+1) > > */ > > SKL_DISP_PW_MISC_IO = 0, > > SKL_DISP_PW_DDI_A_E, > > @@ -1075,17 +1075,54 @@ enum i915_power_well_id { > > SKL_DISP_PW_2, > > > > /* - custom power wells */ > > - SKL_DISP_PW_DC_OFF, > > BXT_DPIO_CMN_A, > > BXT_DPIO_CMN_BC, > > - GLK_DPIO_CMN_C, /* 19 */ > > + GLK_DPIO_CMN_C, /* 18 */ > > + > > + /* > > + * GEN11+ > > + * - _HSW_PWR_WELL_CTL1-4 > > + * (status bit: (id&15)*2, req bit:(id&15)*2+1) > > + */ > > + ICL_DISP_PW_1 = 0, > > + ICL_DISP_PW_2, > > + ICL_DISP_PW_3, > > + ICL_DISP_PW_4, > > + > > + /* > > + * - _HSW_PWR_WELL_CTL_AUX1/2/4 > > + * (status bit: (id&15)*2, req bit:(id&15)*2+1) > > + */ > > + ICL_DISP_PW_AUX_A = 16, > > + ICL_DISP_PW_AUX_B, > > + ICL_DISP_PW_AUX_C, > > + ICL_DISP_PW_AUX_D, > > + ICL_DISP_PW_AUX_E, > > + ICL_DISP_PW_AUX_F, > > + > > + ICL_DISP_PW_AUX_TBT1 = 24, > > + ICL_DISP_PW_AUX_TBT2, > > + ICL_DISP_PW_AUX_TBT3, > > + ICL_DISP_PW_AUX_TBT4, > > + > > + /* > > + * - _HSW_PWR_WELL_CTL_DDI1/2/4 > > + * (status bit: (id&15)*2, req bit:(id&15)*2+1) > > + */ > > + ICL_DISP_PW_DDI_A = 32, > > + ICL_DISP_PW_DDI_B, > > + ICL_DISP_PW_DDI_C, > > + ICL_DISP_PW_DDI_D, > > + ICL_DISP_PW_DDI_E, > > + ICL_DISP_PW_DDI_F, /* 37 */ > > > > /* > > * Multiple platforms. > > * Must start following the highest ID of any platform. > > * - custom power wells > > */ > > - I915_DISP_PW_ALWAYS_ON = 20, > > + SKL_DISP_PW_DC_OFF = 38, > > + I915_DISP_PW_ALWAYS_ON, > > }; > > > > #define PUNIT_REG_PWRGT_CTRL 0x60 > > @@ -1679,6 +1716,13 @@ enum i915_power_well_id { > > #define IREF1RC_OFFSET_MASK (0xFF << > > IREF1RC_OFFSET_SHIFT) > > #define BXT_PORT_CL1CM_DW10(phy) _BXT_PHY((phy), > > _PORT_CL1CM_DW10_BC) > > > > +#define _ICL_PORT_CL_DW12_A 0x162030 > > +#define _ICL_PORT_CL_DW12_B 0x6C030 > > +#define ICL_LANE_ENABLE_AUX (1 << 0) > > +#define ICL_PORT_CL_DW12(port) _MMIO(_PICK((port), > > You can get away with _PIPE instead of _PICK here, which is supposed to > be a little more efficient. There's a third instance of the register with a different offset, but yes we can use _PIPE until that is taken into use. Will change that along with the checkpatch issues. > > Otherwise, looks correct (minus checkpatch problems). > Reviewed-by: Paulo Zanoni <paulo.r.zanoni@intel.com> > > But I would say the PW code is getting very hard to read. The whole > magic behind the i915_power_well_id enum values is hard to read, and a > lot of other magic macros build on top of that. Not having the usual register definition followed by the definition of the flags withing the register is not so nice. I considered adding the register address and request/status flag positions to the power well descriptors somehow, will look into that. > I would really love if our code were a little more straightforward, > less reliant on the magic, even if it were a little bigger. Stuff like > _HSW_PW_REG_IDX() and others are crazy. Ideally the code would not > have to rely on the value of the actual enum for anything. But all of > that is content for a new series. > > > > \ > > + _ICL_PORT_CL_DW1 > > 2_A, \ > > + _ICL_PORT_CL_DW1 > > 2_B)) > > + > > #define _PORT_CL1CM_DW28_A 0x162070 > > #define _PORT_CL1CM_DW28_BC 0x6C070 > > #define OCL1_POWER_DOWN_EN (1 << 23) > > @@ -8563,6 +8607,14 @@ enum { > > #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 > > @@ -8572,14 +8624,20 @@ enum { > > */ > > #define _HSW_PW_REG_IDX(pw) ((pw) >> 4) > > #define _HSW_PW_SHIFT(pw) (((pw) & 0xf) * 2) > > -/* TODO: Add all PWR_WELL_CTL registers below for new platforms */ > > #define HSW_PWR_WELL_CTL_BIOS(pw) _MMIO(_PICK(_HSW_PW_REG_IDX > > (pw), \ > > - _HSW_PWR_WELL_CT > > L1)) > > + _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)) > > + _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)) > > + _HSW_PWR_WELL_CT > > L4, \ > > + _ICL_PWR_WELL_CT > > L_AUX4, \ > > + _ICL_PWR_WELL_CT > > L_DDI4)) > > > > #define HSW_PWR_WELL_CTL_REQ(pw) (1 << > > (_HSW_PW_SHIFT(pw) + 1)) > > #define HSW_PWR_WELL_CTL_STATE(pw) (1 << > > _HSW_PW_SHIFT(pw)) > > @@ -8600,6 +8658,8 @@ enum skl_power_gate { > > #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) > > #define SKL_FUSE_PG_DIST_STATUS(pg) (1 << (27 - > > (pg))) > > > > #define _CNL_AUX_REG_IDX(pw) ((pw) - 9) > > diff --git a/drivers/gpu/drm/i915/intel_display.h > > b/drivers/gpu/drm/i915/intel_display.h > > index dfb02da73ac8..a77dd29db2ec 100644 > > --- a/drivers/gpu/drm/i915/intel_display.h > > +++ b/drivers/gpu/drm/i915/intel_display.h > > @@ -199,6 +199,10 @@ enum intel_display_power_domain { > > POWER_DOMAIN_AUX_E, > > POWER_DOMAIN_AUX_F, > > POWER_DOMAIN_AUX_IO_A, > > + POWER_DOMAIN_AUX_TBT1, > > + POWER_DOMAIN_AUX_TBT2, > > + POWER_DOMAIN_AUX_TBT3, > > + POWER_DOMAIN_AUX_TBT4, > > POWER_DOMAIN_GMBUS, > > POWER_DOMAIN_MODESET, > > POWER_DOMAIN_GT_IRQ, > > diff --git a/drivers/gpu/drm/i915/intel_runtime_pm.c > > b/drivers/gpu/drm/i915/intel_runtime_pm.c > > index 2969787201ef..790670f5fb98 100644 > > --- a/drivers/gpu/drm/i915/intel_runtime_pm.c > > +++ b/drivers/gpu/drm/i915/intel_runtime_pm.c > > @@ -134,6 +134,14 @@ intel_display_power_domain_str(enum > > intel_display_power_domain domain) > > return "AUX_F"; > > case POWER_DOMAIN_AUX_IO_A: > > return "AUX_IO_A"; > > + case POWER_DOMAIN_AUX_TBT1: > > + return "AUX_TBT1"; > > + case POWER_DOMAIN_AUX_TBT2: > > + return "AUX_TBT2"; > > + case POWER_DOMAIN_AUX_TBT3: > > + return "AUX_TBT3"; > > + case POWER_DOMAIN_AUX_TBT4: > > + return "AUX_TBT4"; > > case POWER_DOMAIN_GMBUS: > > return "GMBUS"; > > case POWER_DOMAIN_INIT: > > @@ -384,7 +392,8 @@ static void hsw_power_well_enable(struct > > drm_i915_private *dev_priv, > > u32 val; > > > > if (wait_fuses) { > > - pg = SKL_PW_TO_PG(id); > > + pg = INTEL_GEN(dev_priv) >= 11 ? ICL_PW_TO_PG(id) : > > + SKL_PW_TO_PG(id); > > /* > > * For PW1 we have to wait both for the PW0/PG0 fuse > > state > > * before enabling the power well and PW1/PG1's own > > fuse > > @@ -430,6 +439,43 @@ static void hsw_power_well_disable(struct > > drm_i915_private *dev_priv, > > hsw_wait_for_power_well_disable(dev_priv, power_well); > > } > > > > +#define ICL_AUX_PW_TO_PORT(pw) ((pw) - ICL_DISP_PW_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->id; > > + enum port port = ICL_AUX_PW_TO_PORT(id); > > + 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(ICL_PORT_CL_DW12(port)); > > + I915_WRITE(ICL_PORT_CL_DW12(port), val | > > ICL_LANE_ENABLE_AUX); > > + > > + hsw_wait_for_power_well_enable(dev_priv, power_well); > > +} > > + > > +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->id; > > + enum port port = ICL_AUX_PW_TO_PORT(id); > > + 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)); > > + > > + hsw_wait_for_power_well_disable(dev_priv, power_well); > > +} > > + > > /* > > * We should only use the power well if we explicitly asked the > > hardware to > > * enable it, so check if it's enabled and also check if we've > > requested it to > > @@ -1897,6 +1943,105 @@ void intel_display_power_put(struct > > drm_i915_private *dev_priv, > > BIT_ULL(POWER_DOMAIN_AUX_A) | \ > > BIT_ULL(POWER_DOMAIN_INIT)) > > > > +/* > > + * ICL PW_0/PG_0 domains (HW/DMC control): > > + * - PCI > > + * - clocks except port PLL > > + * - central power except FBC > > + * - shared functions except pipe interrupts, pipe MBUS, DBUF > > registers > > + * ICL PW_1/PG_1 domains (HW/DMC control): > > + * - DBUF function > > + * - PIPE_A and its planes, except VGA > > + * - transcoder EDP + PSR > > + * - transcoder DSI > > + * - DDI_A > > + * - FBC > > + */ > > +#define ICL_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 ICL_PW_3_POWER_DOMAINS ( \ > > + ICL_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_PORT_DDI_E_LANES) | \ > > + BIT_ULL(POWER_DOMAIN_PORT_DDI_E_IO) | \ > > + BIT_ULL(POWER_DOMAIN_PORT_DDI_F_LANES) | \ > > + BIT_ULL(POWER_DOMAIN_PORT_DDI_F_IO) | \ > > + BIT_ULL(POWER_DOMAIN_AUX_B) | \ > > + BIT_ULL(POWER_DOMAIN_AUX_C) | \ > > + BIT_ULL(POWER_DOMAIN_AUX_D) | \ > > + BIT_ULL(POWER_DOMAIN_AUX_E) | \ > > + BIT_ULL(POWER_DOMAIN_AUX_F) | \ > > + BIT_ULL(POWER_DOMAIN_AUX_TBT1) | \ > > + BIT_ULL(POWER_DOMAIN_AUX_TBT2) | \ > > + BIT_ULL(POWER_DOMAIN_AUX_TBT3) | \ > > + BIT_ULL(POWER_DOMAIN_AUX_TBT4) | \ > > + BIT_ULL(POWER_DOMAIN_VGA) | \ > > + BIT_ULL(POWER_DOMAIN_AUDIO) | \ > > + BIT_ULL(POWER_DOMAIN_INIT)) > > + /* > > + * - transcoder WD > > + * - KVMR (HW control) > > + */ > > +#define ICL_PW_2_POWER_DOMAINS ( \ > > + ICL_PW_3_POWER_DOMAINS | \ > > + BIT_ULL(POWER_DOMAIN_INIT)) > > + /* > > + * - eDP/DSI VDSC > > + * - KVMR (HW control) > > + */ > > +#define ICL_DISPLAY_DC_OFF_POWER_DOMAINS ( \ > > + ICL_PW_2_POWER_DOMAINS | \ > > + BIT_ULL(POWER_DOMAIN_MODESET) | \ > > + BIT_ULL(POWER_DOMAIN_AUX_A) | \ > > + BIT_ULL(POWER_DOMAIN_INIT)) > > + > > +#define ICL_DDI_IO_A_POWER_DOMAINS ( \ > > + BIT_ULL(POWER_DOMAIN_PORT_DDI_A_IO)) > > +#define ICL_DDI_IO_B_POWER_DOMAINS ( \ > > + BIT_ULL(POWER_DOMAIN_PORT_DDI_B_IO)) > > +#define ICL_DDI_IO_C_POWER_DOMAINS ( \ > > + BIT_ULL(POWER_DOMAIN_PORT_DDI_C_IO)) > > +#define ICL_DDI_IO_D_POWER_DOMAINS ( \ > > + BIT_ULL(POWER_DOMAIN_PORT_DDI_D_IO)) > > +#define ICL_DDI_IO_E_POWER_DOMAINS ( \ > > + BIT_ULL(POWER_DOMAIN_PORT_DDI_E_IO)) > > +#define ICL_DDI_IO_F_POWER_DOMAINS ( \ > > + BIT_ULL(POWER_DOMAIN_PORT_DDI_F_IO)) > > + > > +#define ICL_AUX_A_IO_POWER_DOMAINS ( \ > > + BIT_ULL(POWER_DOMAIN_AUX_A)) > > +#define ICL_AUX_B_IO_POWER_DOMAINS ( \ > > + BIT_ULL(POWER_DOMAIN_AUX_B)) > > +#define ICL_AUX_C_IO_POWER_DOMAINS ( \ > > + BIT_ULL(POWER_DOMAIN_AUX_C)) > > +#define ICL_AUX_D_IO_POWER_DOMAINS ( \ > > + BIT_ULL(POWER_DOMAIN_AUX_D)) > > +#define ICL_AUX_E_IO_POWER_DOMAINS ( \ > > + BIT_ULL(POWER_DOMAIN_AUX_E)) > > +#define ICL_AUX_F_IO_POWER_DOMAINS ( \ > > + BIT_ULL(POWER_DOMAIN_AUX_F)) > > +#define ICL_AUX_TBT1_IO_POWER_DOMAINS ( \ > > + BIT_ULL(POWER_DOMAIN_AUX_TBT1)) > > +#define ICL_AUX_TBT2_IO_POWER_DOMAINS ( \ > > + BIT_ULL(POWER_DOMAIN_AUX_TBT2)) > > +#define ICL_AUX_TBT3_IO_POWER_DOMAINS ( \ > > + BIT_ULL(POWER_DOMAIN_AUX_TBT3)) > > +#define ICL_AUX_TBT4_IO_POWER_DOMAINS ( \ > > + BIT_ULL(POWER_DOMAIN_AUX_TBT4)) > > + > > 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, > > @@ -2454,6 +2599,157 @@ static struct i915_power_well > > cnl_power_wells[] = { > > }, > > }; > > > > +static const struct i915_power_well_ops > > icl_combo_phy_aux_power_well_ops = { > > + .sync_hw = hsw_power_well_sync_hw, > > + .enable = icl_combo_phy_aux_power_well_enable, > > + .disable = icl_combo_phy_aux_power_well_disable, > > + .is_enabled = hsw_power_well_enabled, > > +}; > > + > > +static struct i915_power_well icl_power_wells[] = { > > + { > > + .name = "always-on", > > + .always_on = 1, > > + .domains = POWER_DOMAIN_MASK, > > + .ops = &i9xx_always_on_power_well_ops, > > + .id = I915_DISP_PW_ALWAYS_ON, > > + }, > > + { > > + .name = "power well 1", > > + /* Handled by the DMC firmware */ > > + .domains = 0, > > + .ops = &hsw_power_well_ops, > > + .id = ICL_DISP_PW_1, > > + .hsw.has_fuses = true, > > + }, > > + { > > + .name = "power well 2", > > + .domains = ICL_PW_2_POWER_DOMAINS, > > + .ops = &hsw_power_well_ops, > > + .id = ICL_DISP_PW_2, > > + .hsw.has_fuses = true, > > + }, > > + { > > + .name = "DC off", > > + .domains = ICL_DISPLAY_DC_OFF_POWER_DOMAINS, > > + .ops = &gen9_dc_off_power_well_ops, > > + .id = SKL_DISP_PW_DC_OFF, > > + }, > > + { > > + .name = "power well 3", > > + .domains = ICL_PW_3_POWER_DOMAINS, > > + .ops = &hsw_power_well_ops, > > + .id = ICL_DISP_PW_3, > > + .hsw.irq_pipe_mask = BIT(PIPE_B), > > + .hsw.has_vga = true, > > + .hsw.has_fuses = true, > > + }, > > + { > > + .name = "DDI A IO", > > + .domains = ICL_DDI_IO_A_POWER_DOMAINS, > > + .ops = &hsw_power_well_ops, > > + .id = ICL_DISP_PW_DDI_A, > > + }, > > + { > > + .name = "DDI B IO", > > + .domains = ICL_DDI_IO_B_POWER_DOMAINS, > > + .ops = &hsw_power_well_ops, > > + .id = ICL_DISP_PW_DDI_B, > > + }, > > + { > > + .name = "DDI C IO", > > + .domains = ICL_DDI_IO_C_POWER_DOMAINS, > > + .ops = &hsw_power_well_ops, > > + .id = ICL_DISP_PW_DDI_C, > > + }, > > + { > > + .name = "DDI D IO", > > + .domains = ICL_DDI_IO_D_POWER_DOMAINS, > > + .ops = &hsw_power_well_ops, > > + .id = ICL_DISP_PW_DDI_D, > > + }, > > + { > > + .name = "DDI E IO", > > + .domains = ICL_DDI_IO_E_POWER_DOMAINS, > > + .ops = &hsw_power_well_ops, > > + .id = ICL_DISP_PW_DDI_E, > > + }, > > + { > > + .name = "DDI F IO", > > + .domains = ICL_DDI_IO_F_POWER_DOMAINS, > > + .ops = &hsw_power_well_ops, > > + .id = ICL_DISP_PW_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, > > + }, > > + { > > + .name = "AUX B", > > + .domains = ICL_AUX_B_IO_POWER_DOMAINS, > > + .ops = &icl_combo_phy_aux_power_well_ops, > > + .id = ICL_DISP_PW_AUX_B, > > + }, > > + { > > + .name = "AUX C", > > + .domains = ICL_AUX_C_IO_POWER_DOMAINS, > > + .ops = &hsw_power_well_ops, > > + .id = ICL_DISP_PW_AUX_C, > > + }, > > + { > > + .name = "AUX D", > > + .domains = ICL_AUX_D_IO_POWER_DOMAINS, > > + .ops = &hsw_power_well_ops, > > + .id = ICL_DISP_PW_AUX_D, > > + }, > > + { > > + .name = "AUX E", > > + .domains = ICL_AUX_E_IO_POWER_DOMAINS, > > + .ops = &hsw_power_well_ops, > > + .id = ICL_DISP_PW_AUX_E, > > + }, > > + { > > + .name = "AUX F", > > + .domains = ICL_AUX_F_IO_POWER_DOMAINS, > > + .ops = &hsw_power_well_ops, > > + .id = ICL_DISP_PW_AUX_F, > > + }, > > + { > > + .name = "AUX TBT1", > > + .domains = ICL_AUX_TBT1_IO_POWER_DOMAINS, > > + .ops = &hsw_power_well_ops, > > + .id = ICL_DISP_PW_AUX_TBT1, > > + }, > > + { > > + .name = "AUX TBT2", > > + .domains = ICL_AUX_TBT2_IO_POWER_DOMAINS, > > + .ops = &hsw_power_well_ops, > > + .id = ICL_DISP_PW_AUX_TBT2, > > + }, > > + { > > + .name = "AUX TBT3", > > + .domains = ICL_AUX_TBT3_IO_POWER_DOMAINS, > > + .ops = &hsw_power_well_ops, > > + .id = ICL_DISP_PW_AUX_TBT3, > > + }, > > + { > > + .name = "AUX TBT4", > > + .domains = ICL_AUX_TBT4_IO_POWER_DOMAINS, > > + .ops = &hsw_power_well_ops, > > + .id = ICL_DISP_PW_AUX_TBT4, > > + }, > > + { > > + .name = "power well 4", > > + .domains = ICL_PW_4_POWER_DOMAINS, > > + .ops = &hsw_power_well_ops, > > + .id = ICL_DISP_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) > > @@ -2471,7 +2767,7 @@ static uint32_t get_allowed_dc_mask(const > > struct drm_i915_private *dev_priv, > > int requested_dc; > > int max_dc; > > > > - if (IS_GEN9_BC(dev_priv) || IS_CANNONLAKE(dev_priv)) { > > + if (IS_GEN9_BC(dev_priv) || INTEL_INFO(dev_priv)->gen >= 10) > > { > > max_dc = 2; > > mask = 0; > > } else if (IS_GEN9_LP(dev_priv)) { > > @@ -2559,7 +2855,9 @@ 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_HASWELL(dev_priv)) { > > + if (IS_ICELAKE(dev_priv)) { > > + set_power_wells(power_domains, icl_power_wells); > > + } else if (IS_HASWELL(dev_priv)) { > > set_power_wells(power_domains, hsw_power_wells); > > } else if (IS_BROADWELL(dev_priv)) { > > set_power_wells(power_domains, bdw_power_wells); > > @@ -3026,6 +3324,8 @@ static void cnl_display_core_uninit(struct > > drm_i915_private *dev_priv) > > static void icl_display_core_init(struct drm_i915_private *dev_priv, > > bool resume) > > { > > + struct i915_power_domains *power_domains = &dev_priv- > > >power_domains; > > + struct i915_power_well *well; > > enum port port; > > u32 val; > > > > @@ -3054,8 +3354,14 @@ static void icl_display_core_init(struct > > drm_i915_private *dev_priv, > > I915_WRITE(ICL_PORT_CL_DW5(port), val); > > } > > > > - /* 4. Enable power well 1 (PG1) and aux IO power. */ > > - /* FIXME: ICL power wells code not here yet. */ > > + /* > > + * 4. Enable Power Well 1 (PG1). > > + * The AUX IO power wells will be enabled on demand. > > + */ > > + mutex_lock(&power_domains->lock); > > + well = lookup_power_well(dev_priv, ICL_DISP_PW_1); > > + intel_power_well_enable(dev_priv, well); > > + mutex_unlock(&power_domains->lock); > > > > /* 5. Enable CDCLK. */ > > icl_init_cdclk(dev_priv); > > @@ -3073,6 +3379,8 @@ static void icl_display_core_init(struct > > drm_i915_private *dev_priv, > > > > static void icl_display_core_uninit(struct drm_i915_private > > *dev_priv) > > { > > + struct i915_power_domains *power_domains = &dev_priv- > > >power_domains; > > + struct i915_power_well *well; > > enum port port; > > u32 val; > > > > @@ -3086,8 +3394,15 @@ static void icl_display_core_uninit(struct > > drm_i915_private *dev_priv) > > /* 3. Disable CD clock */ > > icl_uninit_cdclk(dev_priv); > > > > - /* 4. Disable Power Well 1 (PG1) and Aux IO Power */ > > - /* FIXME: ICL power wells code not here yet. */ > > + /* > > + * 4. Disable Power Well 1 (PG1). > > + * The AUX IO power wells are toggled on demand, so they > > are already > > + * disabled at this point. > > + */ > > + mutex_lock(&power_domains->lock); > > + well = lookup_power_well(dev_priv, ICL_DISP_PW_1); > > + intel_power_well_disable(dev_priv, well); > > + mutex_unlock(&power_domains->lock); > > > > /* 5. Disable Comp */ > > for (port = PORT_A; port <= PORT_B; port++) { _______________________________________________ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/intel-gfx ^ permalink raw reply [flat|nested] 9+ messages in thread
end of thread, other threads:[~2018-06-27 14:12 UTC | newest] Thread overview: 9+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2018-06-26 14:22 [PATCH] drm/i915/icl: Add power well support Imre Deak 2018-06-26 14:47 ` ✗ Fi.CI.CHECKPATCH: warning for " Patchwork 2018-06-26 15:05 ` ✓ Fi.CI.BAT: success " Patchwork 2018-06-26 16:12 ` ✓ Fi.CI.IGT: " Patchwork 2018-06-27 13:09 ` Imre Deak 2018-06-27 13:52 ` Jani Nikula 2018-06-27 14:11 ` Imre Deak 2018-06-27 0:28 ` [PATCH] " Paulo Zanoni 2018-06-27 11:59 ` Imre Deak
This is an external index of several public inboxes, see mirroring instructions on how to clone and mirror all data and code used by this external index.