Commit 67ca07e7 authored by Imre Deak's avatar Imre Deak

drm/i915/icl: Add power well support

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.

v6:
- Use _MMIO_PORT(...) instead _MMIO(_PICK(...)) (Paulo)
  Fix checkpatch warnings.

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: default avatarImre Deak <imre.deak@intel.com>
Reviewed-by: Animesh Manna <animesh.manna@intel.com> (v1)
Reviewed-by: default avatarPaulo Zanoni <paulo.r.zanoni@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20180626142232.22361-1-imre.deak@intel.com
parent 00c8f194
...@@ -1045,13 +1045,13 @@ enum i915_power_well_id { ...@@ -1045,13 +1045,13 @@ enum i915_power_well_id {
/* /*
* HSW/BDW * 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, HSW_DISP_PW_GLOBAL = 15,
/* /*
* GEN9+ * 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_MISC_IO = 0,
SKL_DISP_PW_DDI_A_E, SKL_DISP_PW_DDI_A_E,
...@@ -1075,17 +1075,54 @@ enum i915_power_well_id { ...@@ -1075,17 +1075,54 @@ enum i915_power_well_id {
SKL_DISP_PW_2, SKL_DISP_PW_2,
/* - custom power wells */ /* - custom power wells */
SKL_DISP_PW_DC_OFF,
BXT_DPIO_CMN_A, BXT_DPIO_CMN_A,
BXT_DPIO_CMN_BC, 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. * Multiple platforms.
* Must start following the highest ID of any platform. * Must start following the highest ID of any platform.
* - custom power wells * - 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 #define PUNIT_REG_PWRGT_CTRL 0x60
...@@ -1679,6 +1716,13 @@ enum i915_power_well_id { ...@@ -1679,6 +1716,13 @@ enum i915_power_well_id {
#define IREF1RC_OFFSET_MASK (0xFF << IREF1RC_OFFSET_SHIFT) #define IREF1RC_OFFSET_MASK (0xFF << IREF1RC_OFFSET_SHIFT)
#define BXT_PORT_CL1CM_DW10(phy) _BXT_PHY((phy), _PORT_CL1CM_DW10_BC) #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_PORT((port), \
_ICL_PORT_CL_DW12_A, \
_ICL_PORT_CL_DW12_B)
#define _PORT_CL1CM_DW28_A 0x162070 #define _PORT_CL1CM_DW28_A 0x162070
#define _PORT_CL1CM_DW28_BC 0x6C070 #define _PORT_CL1CM_DW28_BC 0x6C070
#define OCL1_POWER_DOWN_EN (1 << 23) #define OCL1_POWER_DOWN_EN (1 << 23)
...@@ -8564,6 +8608,14 @@ enum { ...@@ -8564,6 +8608,14 @@ enum {
#define _HSW_PWR_WELL_CTL3 0x45408 #define _HSW_PWR_WELL_CTL3 0x45408
#define _HSW_PWR_WELL_CTL4 0x4540C #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 * 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 * flag tuples. The register index and HW flag shift is determined by the
...@@ -8573,14 +8625,20 @@ enum { ...@@ -8573,14 +8625,20 @@ enum {
*/ */
#define _HSW_PW_REG_IDX(pw) ((pw) >> 4) #define _HSW_PW_REG_IDX(pw) ((pw) >> 4)
#define _HSW_PW_SHIFT(pw) (((pw) & 0xf) * 2) #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), \ #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), \ #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_KVMR _MMIO(_HSW_PWR_WELL_CTL3)
#define HSW_PWR_WELL_CTL_DEBUG(pw) _MMIO(_PICK(_HSW_PW_REG_IDX(pw), \ #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_REQ(pw) (1 << (_HSW_PW_SHIFT(pw) + 1))
#define HSW_PWR_WELL_CTL_STATE(pw) (1 << _HSW_PW_SHIFT(pw)) #define HSW_PWR_WELL_CTL_STATE(pw) (1 << _HSW_PW_SHIFT(pw))
...@@ -8601,6 +8659,8 @@ enum skl_power_gate { ...@@ -8601,6 +8659,8 @@ enum skl_power_gate {
#define SKL_FUSE_DOWNLOAD_STATUS (1 << 31) #define SKL_FUSE_DOWNLOAD_STATUS (1 << 31)
/* PG0 (HW control->no power well ID), PG1..PG2 (SKL_DISP_PW1..SKL_DISP_PW2) */ /* 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) #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 SKL_FUSE_PG_DIST_STATUS(pg) (1 << (27 - (pg)))
#define _CNL_AUX_REG_IDX(pw) ((pw) - 9) #define _CNL_AUX_REG_IDX(pw) ((pw) - 9)
......
...@@ -199,6 +199,10 @@ enum intel_display_power_domain { ...@@ -199,6 +199,10 @@ enum intel_display_power_domain {
POWER_DOMAIN_AUX_E, POWER_DOMAIN_AUX_E,
POWER_DOMAIN_AUX_F, POWER_DOMAIN_AUX_F,
POWER_DOMAIN_AUX_IO_A, 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_GMBUS,
POWER_DOMAIN_MODESET, POWER_DOMAIN_MODESET,
POWER_DOMAIN_GT_IRQ, POWER_DOMAIN_GT_IRQ,
......
...@@ -134,6 +134,14 @@ intel_display_power_domain_str(enum intel_display_power_domain domain) ...@@ -134,6 +134,14 @@ intel_display_power_domain_str(enum intel_display_power_domain domain)
return "AUX_F"; return "AUX_F";
case POWER_DOMAIN_AUX_IO_A: case POWER_DOMAIN_AUX_IO_A:
return "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: case POWER_DOMAIN_GMBUS:
return "GMBUS"; return "GMBUS";
case POWER_DOMAIN_INIT: case POWER_DOMAIN_INIT:
...@@ -384,7 +392,8 @@ static void hsw_power_well_enable(struct drm_i915_private *dev_priv, ...@@ -384,7 +392,8 @@ static void hsw_power_well_enable(struct drm_i915_private *dev_priv,
u32 val; u32 val;
if (wait_fuses) { 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 * For PW1 we have to wait both for the PW0/PG0 fuse state
* before enabling the power well and PW1/PG1's own fuse * 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, ...@@ -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); 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 * 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 * 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, ...@@ -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_AUX_A) | \
BIT_ULL(POWER_DOMAIN_INIT)) 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 = { static const struct i915_power_well_ops i9xx_always_on_power_well_ops = {
.sync_hw = i9xx_power_well_sync_hw_noop, .sync_hw = i9xx_power_well_sync_hw_noop,
.enable = i9xx_always_on_power_well_noop, .enable = i9xx_always_on_power_well_noop,
...@@ -2454,6 +2599,157 @@ static struct i915_power_well cnl_power_wells[] = { ...@@ -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 static int
sanitize_disable_power_well_option(const struct drm_i915_private *dev_priv, sanitize_disable_power_well_option(const struct drm_i915_private *dev_priv,
int disable_power_well) int disable_power_well)
...@@ -2471,7 +2767,7 @@ static uint32_t get_allowed_dc_mask(const struct drm_i915_private *dev_priv, ...@@ -2471,7 +2767,7 @@ static uint32_t get_allowed_dc_mask(const struct drm_i915_private *dev_priv,
int requested_dc; int requested_dc;
int max_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; max_dc = 2;
mask = 0; mask = 0;
} else if (IS_GEN9_LP(dev_priv)) { } else if (IS_GEN9_LP(dev_priv)) {
...@@ -2559,7 +2855,9 @@ int intel_power_domains_init(struct drm_i915_private *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 enabling order will be from lower to higher indexed wells,
* the disabling order is reversed. * 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); set_power_wells(power_domains, hsw_power_wells);
} else if (IS_BROADWELL(dev_priv)) { } else if (IS_BROADWELL(dev_priv)) {
set_power_wells(power_domains, bdw_power_wells); set_power_wells(power_domains, bdw_power_wells);
...@@ -3026,6 +3324,8 @@ static void cnl_display_core_uninit(struct drm_i915_private *dev_priv) ...@@ -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, static void icl_display_core_init(struct drm_i915_private *dev_priv,
bool resume) bool resume)
{ {
struct i915_power_domains *power_domains = &dev_priv->power_domains;
struct i915_power_well *well;
enum port port; enum port port;
u32 val; u32 val;
...@@ -3054,8 +3354,14 @@ static void icl_display_core_init(struct drm_i915_private *dev_priv, ...@@ -3054,8 +3354,14 @@ static void icl_display_core_init(struct drm_i915_private *dev_priv,
I915_WRITE(ICL_PORT_CL_DW5(port), val); 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. */ /* 5. Enable CDCLK. */
icl_init_cdclk(dev_priv); icl_init_cdclk(dev_priv);
...@@ -3073,6 +3379,8 @@ static void icl_display_core_init(struct drm_i915_private *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) 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; enum port port;
u32 val; u32 val;
...@@ -3086,8 +3394,15 @@ static void icl_display_core_uninit(struct drm_i915_private *dev_priv) ...@@ -3086,8 +3394,15 @@ static void icl_display_core_uninit(struct drm_i915_private *dev_priv)
/* 3. Disable CD clock */ /* 3. Disable CD clock */
icl_uninit_cdclk(dev_priv); 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 */ /* 5. Disable Comp */
for (port = PORT_A; port <= PORT_B; port++) { for (port = PORT_A; port <= PORT_B; port++) {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment