diff --git a/drivers/gpu/drm/i915/gvt/handlers.c b/drivers/gpu/drm/i915/gvt/handlers.c index d85264d48585..9220a756ecfc 100644 --- a/drivers/gpu/drm/i915/gvt/handlers.c +++ b/drivers/gpu/drm/i915/gvt/handlers.c @@ -2252,10 +2252,17 @@ static int init_generic_mmio_info(struct intel_gvt *gvt) MMIO_D(GEN6_RC6p_THRESHOLD, D_ALL); MMIO_D(GEN6_RC6pp_THRESHOLD, D_ALL); MMIO_D(GEN6_PMINTRMSK, D_ALL); - MMIO_DH(HSW_PWR_WELL_BIOS, D_BDW, NULL, power_well_ctl_mmio_write); - MMIO_DH(HSW_PWR_WELL_DRIVER, D_BDW, NULL, power_well_ctl_mmio_write); - MMIO_DH(HSW_PWR_WELL_KVMR, D_BDW, NULL, power_well_ctl_mmio_write); - MMIO_DH(HSW_PWR_WELL_DEBUG, D_BDW, NULL, power_well_ctl_mmio_write); + /* + * Use an arbitrary power well controlled by the PWR_WELL_CTL + * register. + */ + MMIO_DH(HSW_PWR_WELL_CTL_BIOS(HSW_DISP_PW_GLOBAL), D_BDW, NULL, + power_well_ctl_mmio_write); + MMIO_DH(HSW_PWR_WELL_CTL_DRIVER(HSW_DISP_PW_GLOBAL), D_BDW, NULL, + power_well_ctl_mmio_write); + MMIO_DH(HSW_PWR_WELL_CTL_KVMR, D_BDW, NULL, power_well_ctl_mmio_write); + MMIO_DH(HSW_PWR_WELL_CTL_DEBUG(HSW_DISP_PW_GLOBAL), D_BDW, NULL, + power_well_ctl_mmio_write); MMIO_DH(HSW_PWR_WELL_CTL5, D_BDW, NULL, power_well_ctl_mmio_write); MMIO_DH(HSW_PWR_WELL_CTL6, D_BDW, NULL, power_well_ctl_mmio_write); @@ -2645,9 +2652,14 @@ static int init_skl_mmio_info(struct intel_gvt *gvt) MMIO_F(_DPD_AUX_CH_CTL, 6 * 4, 0, 0, 0, D_SKL_PLUS, NULL, dp_aux_ch_ctl_mmio_write); - MMIO_D(HSW_PWR_WELL_BIOS, D_SKL_PLUS); - MMIO_DH(HSW_PWR_WELL_DRIVER, D_SKL_PLUS, NULL, - skl_power_well_ctl_write); + /* + * Use an arbitrary power well controlled by the PWR_WELL_CTL + * register. + */ + MMIO_D(HSW_PWR_WELL_CTL_BIOS(SKL_DISP_PW_MISC_IO), D_SKL_PLUS); + MMIO_DH(HSW_PWR_WELL_CTL_DRIVER(SKL_DISP_PW_MISC_IO), D_SKL_PLUS, NULL, + skl_power_well_ctl_write); + MMIO_DH(GEN6_PCODE_MAILBOX, D_SKL_PLUS, NULL, mailbox_write); MMIO_D(0xa210, D_SKL_PLUS); MMIO_D(GEN9_MEDIA_PG_IDLE_HYSTERESIS, D_SKL_PLUS); diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index 44b8da19a2a0..b2d785969d17 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -1254,13 +1254,13 @@ enum i915_power_well_id { /* * HSW/BDW - * - HSW_PWR_WELL_DRIVER (status bit: id*2, req bit: id*2+1) + * - HSW_PWR_WELL_CTL_DRIVER(0) (status bit: id*2, req bit: id*2+1) */ HSW_DISP_PW_GLOBAL = 15, /* * GEN9+ - * - HSW_PWR_WELL_DRIVER (status bit: id*2, req bit: id*2+1) + * - HSW_PWR_WELL_CTL_DRIVER(0) (status bit: id*2, req bit: id*2+1) */ SKL_DISP_PW_MISC_IO = 0, SKL_DISP_PW_DDI_A_E, @@ -8189,11 +8189,29 @@ enum { #define SKL_AUD_CODEC_WAKE_SIGNAL (1 << 15) /* HSW Power Wells */ -#define HSW_PWR_WELL_BIOS _MMIO(0x45400) /* CTL1 */ -#define HSW_PWR_WELL_DRIVER _MMIO(0x45404) /* CTL2 */ -#define HSW_PWR_WELL_KVMR _MMIO(0x45408) /* CTL3 */ -#define HSW_PWR_WELL_DEBUG _MMIO(0x4540C) /* CTL4 */ -#define _HSW_PW_SHIFT(pw) ((pw) * 2) +#define _HSW_PWR_WELL_CTL1 0x45400 +#define _HSW_PWR_WELL_CTL2 0x45404 +#define _HSW_PWR_WELL_CTL3 0x45408 +#define _HSW_PWR_WELL_CTL4 0x4540C + +/* + * Each power well control register contains up to 16 (request, status) HW + * flag tuples. The register index and HW flag shift is determined by the + * power well ID (see i915_power_well_id). There are 4 possible sources of + * power well requests each source having its own set of control registers: + * BIOS, DRIVER, KVMR, DEBUG. + */ +#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)) +#define HSW_PWR_WELL_CTL_DRIVER(pw) _MMIO(_PICK(_HSW_PW_REG_IDX(pw), \ + _HSW_PWR_WELL_CTL2)) +#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)) + #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_CTL5 _MMIO(0x45410) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index decf5da63950..29926244f4f2 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -8783,7 +8783,8 @@ static void assert_can_disable_lcpll(struct drm_i915_private *dev_priv) I915_STATE_WARN(crtc->active, "CRTC for pipe %c enabled\n", pipe_name(crtc->pipe)); - I915_STATE_WARN(I915_READ(HSW_PWR_WELL_DRIVER), "Power well on\n"); + I915_STATE_WARN(I915_READ(HSW_PWR_WELL_CTL_DRIVER(HSW_DISP_PW_GLOBAL)), + "Display power well on\n"); I915_STATE_WARN(I915_READ(SPLL_CTL) & SPLL_PLL_ENABLE, "SPLL enabled\n"); I915_STATE_WARN(I915_READ(WRPLL_CTL(0)) & WRPLL_PLL_ENABLE, "WRPLL1 enabled\n"); I915_STATE_WARN(I915_READ(WRPLL_CTL(1)) & WRPLL_PLL_ENABLE, "WRPLL2 enabled\n"); @@ -15348,7 +15349,8 @@ intel_display_capture_error_state(struct drm_i915_private *dev_priv) return NULL; if (IS_HASWELL(dev_priv) || IS_BROADWELL(dev_priv)) - error->power_well_driver = I915_READ(HSW_PWR_WELL_DRIVER); + error->power_well_driver = + I915_READ(HSW_PWR_WELL_CTL_DRIVER(HSW_DISP_PW_GLOBAL)); for_each_pipe(dev_priv, i) { error->pipe[i].power_domain_on = diff --git a/drivers/gpu/drm/i915/intel_runtime_pm.c b/drivers/gpu/drm/i915/intel_runtime_pm.c index 6e0c9d99bf0a..b66d8e136aa3 100644 --- a/drivers/gpu/drm/i915/intel_runtime_pm.c +++ b/drivers/gpu/drm/i915/intel_runtime_pm.c @@ -307,7 +307,7 @@ static void hsw_wait_for_power_well_enable(struct drm_i915_private *dev_priv, /* Timeout for PW1:10 us, AUX:not specified, other PWs:20 us. */ WARN_ON(intel_wait_for_register(dev_priv, - HSW_PWR_WELL_DRIVER, + HSW_PWR_WELL_CTL_DRIVER(id), HSW_PWR_WELL_CTL_STATE(id), HSW_PWR_WELL_CTL_STATE(id), 1)); @@ -319,10 +319,10 @@ static u32 hsw_power_well_requesters(struct drm_i915_private *dev_priv, u32 req_mask = HSW_PWR_WELL_CTL_REQ(id); u32 ret; - ret = I915_READ(HSW_PWR_WELL_BIOS) & req_mask ? 1 : 0; - ret |= I915_READ(HSW_PWR_WELL_DRIVER) & req_mask ? 2 : 0; - ret |= I915_READ(HSW_PWR_WELL_KVMR) & req_mask ? 4 : 0; - ret |= I915_READ(HSW_PWR_WELL_DEBUG) & req_mask ? 8 : 0; + ret = I915_READ(HSW_PWR_WELL_CTL_BIOS(id)) & req_mask ? 1 : 0; + ret |= I915_READ(HSW_PWR_WELL_CTL_DRIVER(id)) & req_mask ? 2 : 0; + ret |= I915_READ(HSW_PWR_WELL_CTL_KVMR) & req_mask ? 4 : 0; + ret |= I915_READ(HSW_PWR_WELL_CTL_DEBUG(id)) & req_mask ? 8 : 0; return ret; } @@ -343,7 +343,7 @@ static void hsw_wait_for_power_well_disable(struct drm_i915_private *dev_priv, * Skip the wait in case any of the request bits are set and print a * diagnostic message. */ - wait_for((disabled = !(I915_READ(HSW_PWR_WELL_DRIVER) & + wait_for((disabled = !(I915_READ(HSW_PWR_WELL_CTL_DRIVER(id)) & HSW_PWR_WELL_CTL_STATE(id))) || (reqs = hsw_power_well_requesters(dev_priv, id)), 1); if (disabled) @@ -384,8 +384,8 @@ static void hsw_power_well_enable(struct drm_i915_private *dev_priv, gen9_wait_for_power_well_fuses(dev_priv, SKL_PG0); } - val = I915_READ(HSW_PWR_WELL_DRIVER); - I915_WRITE(HSW_PWR_WELL_DRIVER, val | HSW_PWR_WELL_CTL_REQ(id)); + 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_enable(dev_priv, power_well); if (wait_fuses) @@ -403,8 +403,9 @@ static void hsw_power_well_disable(struct drm_i915_private *dev_priv, hsw_power_well_pre_disable(dev_priv, power_well->hsw.irq_pipe_mask); - val = I915_READ(HSW_PWR_WELL_DRIVER); - I915_WRITE(HSW_PWR_WELL_DRIVER, val & ~HSW_PWR_WELL_CTL_REQ(id)); + 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); } @@ -419,17 +420,19 @@ static bool hsw_power_well_enabled(struct drm_i915_private *dev_priv, enum i915_power_well_id id = power_well->id; u32 mask = HSW_PWR_WELL_CTL_REQ(id) | HSW_PWR_WELL_CTL_STATE(id); - return (I915_READ(HSW_PWR_WELL_DRIVER) & mask) == mask; + return (I915_READ(HSW_PWR_WELL_CTL_DRIVER(id)) & mask) == mask; } static void assert_can_enable_dc9(struct drm_i915_private *dev_priv) { + enum i915_power_well_id id = SKL_DISP_PW_2; + WARN_ONCE((I915_READ(DC_STATE_EN) & DC_STATE_EN_DC9), "DC9 already programmed to be enabled.\n"); WARN_ONCE(I915_READ(DC_STATE_EN) & DC_STATE_EN_UPTO_DC5, "DC5 still not disabled to enable DC9.\n"); - WARN_ONCE(I915_READ(HSW_PWR_WELL_DRIVER) & - HSW_PWR_WELL_CTL_REQ(SKL_DISP_PW_2), + WARN_ONCE(I915_READ(HSW_PWR_WELL_CTL_DRIVER(id)) & + HSW_PWR_WELL_CTL_REQ(id), "Power well 2 on.\n"); WARN_ONCE(intel_irqs_enabled(dev_priv), "Interrupts not disabled yet.\n"); @@ -630,15 +633,15 @@ static void hsw_power_well_sync_hw(struct drm_i915_private *dev_priv, { enum i915_power_well_id id = power_well->id; u32 mask = HSW_PWR_WELL_CTL_REQ(id); - u32 bios_req = I915_READ(HSW_PWR_WELL_BIOS); + u32 bios_req = I915_READ(HSW_PWR_WELL_CTL_BIOS(id)); /* Take over the request bit if set by BIOS. */ if (bios_req & mask) { - u32 drv_req = I915_READ(HSW_PWR_WELL_DRIVER); + u32 drv_req = I915_READ(HSW_PWR_WELL_CTL_DRIVER(id)); if (!(drv_req & mask)) - I915_WRITE(HSW_PWR_WELL_DRIVER, drv_req | mask); - I915_WRITE(HSW_PWR_WELL_BIOS, bios_req & ~mask); + I915_WRITE(HSW_PWR_WELL_CTL_DRIVER(id), drv_req | mask); + I915_WRITE(HSW_PWR_WELL_CTL_BIOS(id), bios_req & ~mask); } }