Although on HSW/BDW there is only a single display global power well, it's programmed the same way as other GEN9+ power wells. This also means we can get at the HSW/BDW request and status flags the same way it's done on GEN9+ by assigning the corresponding HSW/BDW power well ID. This ID was assigned in a recent patch, so we can now switch to using the same macros everywhere on HSW+. Updating the HSW power well control register with RMW is not strictly necessary, but this will allow us to use the same code for GEN9+. Signed-off-by: Imre Deak <imre.deak@xxxxxxxxx> --- drivers/gpu/drm/i915/gvt/handlers.c | 8 +++-- drivers/gpu/drm/i915/i915_reg.h | 8 ++--- drivers/gpu/drm/i915/intel_runtime_pm.c | 58 ++++++++++++++++++++------------- 3 files changed, 44 insertions(+), 30 deletions(-) diff --git a/drivers/gpu/drm/i915/gvt/handlers.c b/drivers/gpu/drm/i915/gvt/handlers.c index 17febe8..aeecf315 100644 --- a/drivers/gpu/drm/i915/gvt/handlers.c +++ b/drivers/gpu/drm/i915/gvt/handlers.c @@ -1222,10 +1222,12 @@ static int power_well_ctl_mmio_write(struct intel_vgpu *vgpu, { write_vreg(vgpu, offset, p_data, bytes); - if (vgpu_vreg(vgpu, offset) & HSW_PWR_WELL_ENABLE_REQUEST) - vgpu_vreg(vgpu, offset) |= HSW_PWR_WELL_STATE_ENABLED; + if (vgpu_vreg(vgpu, offset) & HSW_PWR_WELL_CTL_REQ(HSW_DISP_PW_GLOBAL)) + vgpu_vreg(vgpu, offset) |= + HSW_PWR_WELL_CTL_STATE(HSW_DISP_PW_GLOBAL); else - vgpu_vreg(vgpu, offset) &= ~HSW_PWR_WELL_STATE_ENABLED; + vgpu_vreg(vgpu, offset) &= + ~HSW_PWR_WELL_CTL_STATE(HSW_DISP_PW_GLOBAL); return 0; } diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index f798023..845f50c 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -1139,9 +1139,6 @@ enum i915_power_well_id { I915_DISP_PW_ALWAYS_ON = 20, }; -#define SKL_POWER_WELL_STATE(pw) (1 << ((pw) * 2)) -#define SKL_POWER_WELL_REQ(pw) (1 << (((pw) * 2) + 1)) - #define PUNIT_REG_PWRGT_CTRL 0x60 #define PUNIT_REG_PWRGT_STATUS 0x61 #define PUNIT_PWRGT_MASK(power_well) (3 << ((power_well) * 2)) @@ -8015,8 +8012,9 @@ enum { #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_PWR_WELL_ENABLE_REQUEST (1<<31) -#define HSW_PWR_WELL_STATE_ENABLED (1<<30) +#define _HSW_PW_SHIFT(pw) ((pw) * 2) +#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) #define HSW_PWR_WELL_ENABLE_SINGLE_STEP (1<<31) #define HSW_PWR_WELL_PWR_GATE_OVERRIDE (1<<20) diff --git a/drivers/gpu/drm/i915/intel_runtime_pm.c b/drivers/gpu/drm/i915/intel_runtime_pm.c index d0934bd..e18c38e6 100644 --- a/drivers/gpu/drm/i915/intel_runtime_pm.c +++ b/drivers/gpu/drm/i915/intel_runtime_pm.c @@ -177,8 +177,10 @@ static void intel_power_well_put(struct drm_i915_private *dev_priv, static bool hsw_power_well_enabled(struct drm_i915_private *dev_priv, struct i915_power_well *power_well) { - return I915_READ(HSW_PWR_WELL_DRIVER) == - (HSW_PWR_WELL_ENABLE_REQUEST | HSW_PWR_WELL_STATE_ENABLED); + 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; } /** @@ -350,15 +352,15 @@ static void gen9_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, - SKL_POWER_WELL_STATE(id), - SKL_POWER_WELL_STATE(id), + HSW_PWR_WELL_CTL_STATE(id), + HSW_PWR_WELL_CTL_STATE(id), 1)); } static u32 gen9_power_well_requesters(struct drm_i915_private *dev_priv, enum i915_power_well_id id) { - u32 req_mask = SKL_POWER_WELL_REQ(id); + u32 req_mask = HSW_PWR_WELL_CTL_REQ(id); u32 ret; ret = I915_READ(HSW_PWR_WELL_BIOS) & req_mask ? 1 : 0; @@ -386,7 +388,7 @@ static void gen9_wait_for_power_well_disable(struct drm_i915_private *dev_priv, * diagnostic message. */ wait_for((disabled = !(I915_READ(HSW_PWR_WELL_DRIVER) & - SKL_POWER_WELL_STATE(id))) || + HSW_PWR_WELL_CTL_STATE(id))) || (reqs = gen9_power_well_requesters(dev_priv, id)), 1); if (disabled) return; @@ -399,12 +401,16 @@ static void gen9_wait_for_power_well_disable(struct drm_i915_private *dev_priv, static void hsw_power_well_enable(struct drm_i915_private *dev_priv, struct i915_power_well *power_well) { - I915_WRITE(HSW_PWR_WELL_DRIVER, HSW_PWR_WELL_ENABLE_REQUEST); + enum i915_power_well_id id = power_well->id; + u32 val; + + val = I915_READ(HSW_PWR_WELL_DRIVER); + I915_WRITE(HSW_PWR_WELL_DRIVER, val | HSW_PWR_WELL_CTL_REQ(id)); if (intel_wait_for_register(dev_priv, HSW_PWR_WELL_DRIVER, - HSW_PWR_WELL_STATE_ENABLED, - HSW_PWR_WELL_STATE_ENABLED, + HSW_PWR_WELL_CTL_STATE(id), + HSW_PWR_WELL_CTL_STATE(id), 20)) DRM_ERROR("Timeout enabling power well\n"); hsw_power_well_post_enable(dev_priv); @@ -413,8 +419,12 @@ static void hsw_power_well_enable(struct drm_i915_private *dev_priv, static void hsw_power_well_disable(struct drm_i915_private *dev_priv, struct i915_power_well *power_well) { + enum i915_power_well_id id = power_well->id; + u32 val; + hsw_power_well_pre_disable(dev_priv); - I915_WRITE(HSW_PWR_WELL_DRIVER, 0); + val = I915_READ(HSW_PWR_WELL_DRIVER); + I915_WRITE(HSW_PWR_WELL_DRIVER, val & ~HSW_PWR_WELL_CTL_REQ(id)); POSTING_READ(HSW_PWR_WELL_DRIVER); } @@ -591,7 +601,7 @@ static void assert_can_enable_dc9(struct drm_i915_private *dev_priv) 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) & - SKL_POWER_WELL_REQ(SKL_DISP_PW_2), + HSW_PWR_WELL_CTL_REQ(SKL_DISP_PW_2), "Power well 2 on.\n"); WARN_ONCE(intel_irqs_enabled(dev_priv), "Interrupts not disabled yet.\n"); @@ -829,8 +839,8 @@ static void skl_set_power_well(struct drm_i915_private *dev_priv, return; } - req_mask = SKL_POWER_WELL_REQ(power_well->id); - state_mask = SKL_POWER_WELL_STATE(power_well->id); + req_mask = HSW_PWR_WELL_CTL_REQ(power_well->id); + state_mask = HSW_PWR_WELL_CTL_STATE(power_well->id); if (!enable) skl_power_well_pre_disable(dev_priv, power_well); @@ -875,21 +885,25 @@ static void skl_set_power_well(struct drm_i915_private *dev_priv, static void hsw_power_well_sync_hw(struct drm_i915_private *dev_priv, struct i915_power_well *power_well) { + 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); + /* Take over the request bit if set by BIOS. */ - if (I915_READ(HSW_PWR_WELL_BIOS) & HSW_PWR_WELL_ENABLE_REQUEST) { - if (!(I915_READ(HSW_PWR_WELL_DRIVER) & - HSW_PWR_WELL_ENABLE_REQUEST)) - I915_WRITE(HSW_PWR_WELL_DRIVER, - HSW_PWR_WELL_ENABLE_REQUEST); - I915_WRITE(HSW_PWR_WELL_BIOS, 0); + if (bios_req & mask) { + u32 drv_req = I915_READ(HSW_PWR_WELL_DRIVER); + + if (!(drv_req & mask)) + I915_WRITE(HSW_PWR_WELL_DRIVER, drv_req | mask); + I915_WRITE(HSW_PWR_WELL_BIOS, bios_req & ~mask); } } static bool skl_power_well_enabled(struct drm_i915_private *dev_priv, struct i915_power_well *power_well) { - uint32_t mask = SKL_POWER_WELL_REQ(power_well->id) | - SKL_POWER_WELL_STATE(power_well->id); + uint32_t mask = HSW_PWR_WELL_CTL_REQ(power_well->id) | + HSW_PWR_WELL_CTL_STATE(power_well->id); return (I915_READ(HSW_PWR_WELL_DRIVER) & mask) == mask; } @@ -897,7 +911,7 @@ static bool skl_power_well_enabled(struct drm_i915_private *dev_priv, static void skl_power_well_sync_hw(struct drm_i915_private *dev_priv, struct i915_power_well *power_well) { - uint32_t mask = SKL_POWER_WELL_REQ(power_well->id); + uint32_t mask = HSW_PWR_WELL_CTL_REQ(power_well->id); uint32_t bios_req = I915_READ(HSW_PWR_WELL_BIOS); /* Take over the request bit if set by BIOS. */ -- 2.7.4 _______________________________________________ Intel-gfx mailing list Intel-gfx@xxxxxxxxxxxxxxxxxxxxx https://lists.freedesktop.org/mailman/listinfo/intel-gfx