Commit 1af474fe authored by Imre Deak's avatar Imre Deak Committed by Daniel Vetter

drm/i915/hsw+: Unify the hsw/bdw and gen9+ power well req/state macros

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: default avatarImre Deak <imre.deak@intel.com>
Reviewed-by: default avatarArkadiusz Hiler <arkadiusz.hiler@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/1499352040-8819-13-git-send-email-imre.deak@intel.comSigned-off-by: default avatarDaniel Vetter <daniel.vetter@ffwll.ch>
parent ec46d483
...@@ -1222,10 +1222,12 @@ static int power_well_ctl_mmio_write(struct intel_vgpu *vgpu, ...@@ -1222,10 +1222,12 @@ static int power_well_ctl_mmio_write(struct intel_vgpu *vgpu,
{ {
write_vreg(vgpu, offset, p_data, bytes); write_vreg(vgpu, offset, p_data, bytes);
if (vgpu_vreg(vgpu, offset) & HSW_PWR_WELL_ENABLE_REQUEST) if (vgpu_vreg(vgpu, offset) & HSW_PWR_WELL_CTL_REQ(HSW_DISP_PW_GLOBAL))
vgpu_vreg(vgpu, offset) |= HSW_PWR_WELL_STATE_ENABLED; vgpu_vreg(vgpu, offset) |=
HSW_PWR_WELL_CTL_STATE(HSW_DISP_PW_GLOBAL);
else 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; return 0;
} }
......
...@@ -1140,9 +1140,6 @@ enum i915_power_well_id { ...@@ -1140,9 +1140,6 @@ enum i915_power_well_id {
I915_DISP_PW_ALWAYS_ON = 20, 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_CTRL 0x60
#define PUNIT_REG_PWRGT_STATUS 0x61 #define PUNIT_REG_PWRGT_STATUS 0x61
#define PUNIT_PWRGT_MASK(power_well) (3 << ((power_well) * 2)) #define PUNIT_PWRGT_MASK(power_well) (3 << ((power_well) * 2))
...@@ -8016,8 +8013,9 @@ enum { ...@@ -8016,8 +8013,9 @@ enum {
#define HSW_PWR_WELL_DRIVER _MMIO(0x45404) /* CTL2 */ #define HSW_PWR_WELL_DRIVER _MMIO(0x45404) /* CTL2 */
#define HSW_PWR_WELL_KVMR _MMIO(0x45408) /* CTL3 */ #define HSW_PWR_WELL_KVMR _MMIO(0x45408) /* CTL3 */
#define HSW_PWR_WELL_DEBUG _MMIO(0x4540C) /* CTL4 */ #define HSW_PWR_WELL_DEBUG _MMIO(0x4540C) /* CTL4 */
#define HSW_PWR_WELL_ENABLE_REQUEST (1<<31) #define _HSW_PW_SHIFT(pw) ((pw) * 2)
#define HSW_PWR_WELL_STATE_ENABLED (1<<30) #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_CTL5 _MMIO(0x45410)
#define HSW_PWR_WELL_ENABLE_SINGLE_STEP (1<<31) #define HSW_PWR_WELL_ENABLE_SINGLE_STEP (1<<31)
#define HSW_PWR_WELL_PWR_GATE_OVERRIDE (1<<20) #define HSW_PWR_WELL_PWR_GATE_OVERRIDE (1<<20)
......
...@@ -177,8 +177,10 @@ static void intel_power_well_put(struct drm_i915_private *dev_priv, ...@@ -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, static bool hsw_power_well_enabled(struct drm_i915_private *dev_priv,
struct i915_power_well *power_well) struct i915_power_well *power_well)
{ {
return I915_READ(HSW_PWR_WELL_DRIVER) == enum i915_power_well_id id = power_well->id;
(HSW_PWR_WELL_ENABLE_REQUEST | HSW_PWR_WELL_STATE_ENABLED); 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, ...@@ -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. */ /* Timeout for PW1:10 us, AUX:not specified, other PWs:20 us. */
WARN_ON(intel_wait_for_register(dev_priv, WARN_ON(intel_wait_for_register(dev_priv,
HSW_PWR_WELL_DRIVER, HSW_PWR_WELL_DRIVER,
SKL_POWER_WELL_STATE(id), HSW_PWR_WELL_CTL_STATE(id),
SKL_POWER_WELL_STATE(id), HSW_PWR_WELL_CTL_STATE(id),
1)); 1));
} }
static u32 gen9_power_well_requesters(struct drm_i915_private *dev_priv, static u32 gen9_power_well_requesters(struct drm_i915_private *dev_priv,
enum i915_power_well_id id) 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; u32 ret;
ret = I915_READ(HSW_PWR_WELL_BIOS) & req_mask ? 1 : 0; 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, ...@@ -386,7 +388,7 @@ static void gen9_wait_for_power_well_disable(struct drm_i915_private *dev_priv,
* diagnostic message. * diagnostic message.
*/ */
wait_for((disabled = !(I915_READ(HSW_PWR_WELL_DRIVER) & 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); (reqs = gen9_power_well_requesters(dev_priv, id)), 1);
if (disabled) if (disabled)
return; return;
...@@ -399,12 +401,16 @@ static void gen9_wait_for_power_well_disable(struct drm_i915_private *dev_priv, ...@@ -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, static void hsw_power_well_enable(struct drm_i915_private *dev_priv,
struct i915_power_well *power_well) 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, if (intel_wait_for_register(dev_priv,
HSW_PWR_WELL_DRIVER, HSW_PWR_WELL_DRIVER,
HSW_PWR_WELL_STATE_ENABLED, HSW_PWR_WELL_CTL_STATE(id),
HSW_PWR_WELL_STATE_ENABLED, HSW_PWR_WELL_CTL_STATE(id),
20)) 20))
DRM_ERROR("Timeout enabling power well\n"); DRM_ERROR("Timeout enabling power well\n");
hsw_power_well_post_enable(dev_priv); hsw_power_well_post_enable(dev_priv);
...@@ -413,8 +419,12 @@ static void hsw_power_well_enable(struct drm_i915_private *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, static void hsw_power_well_disable(struct drm_i915_private *dev_priv,
struct i915_power_well *power_well) struct i915_power_well *power_well)
{ {
enum i915_power_well_id id = power_well->id;
u32 val;
hsw_power_well_pre_disable(dev_priv); 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); POSTING_READ(HSW_PWR_WELL_DRIVER);
} }
...@@ -591,7 +601,7 @@ static void assert_can_enable_dc9(struct drm_i915_private *dev_priv) ...@@ -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, WARN_ONCE(I915_READ(DC_STATE_EN) & DC_STATE_EN_UPTO_DC5,
"DC5 still not disabled to enable DC9.\n"); "DC5 still not disabled to enable DC9.\n");
WARN_ONCE(I915_READ(HSW_PWR_WELL_DRIVER) & 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"); "Power well 2 on.\n");
WARN_ONCE(intel_irqs_enabled(dev_priv), WARN_ONCE(intel_irqs_enabled(dev_priv),
"Interrupts not disabled yet.\n"); "Interrupts not disabled yet.\n");
...@@ -829,8 +839,8 @@ static void skl_set_power_well(struct drm_i915_private *dev_priv, ...@@ -829,8 +839,8 @@ static void skl_set_power_well(struct drm_i915_private *dev_priv,
return; return;
} }
req_mask = SKL_POWER_WELL_REQ(power_well->id); req_mask = HSW_PWR_WELL_CTL_REQ(power_well->id);
state_mask = SKL_POWER_WELL_STATE(power_well->id); state_mask = HSW_PWR_WELL_CTL_STATE(power_well->id);
if (!enable) if (!enable)
skl_power_well_pre_disable(dev_priv, power_well); 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, ...@@ -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, static void hsw_power_well_sync_hw(struct drm_i915_private *dev_priv,
struct i915_power_well *power_well) 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. */ /* Take over the request bit if set by BIOS. */
if (I915_READ(HSW_PWR_WELL_BIOS) & HSW_PWR_WELL_ENABLE_REQUEST) { if (bios_req & mask) {
if (!(I915_READ(HSW_PWR_WELL_DRIVER) & u32 drv_req = I915_READ(HSW_PWR_WELL_DRIVER);
HSW_PWR_WELL_ENABLE_REQUEST))
I915_WRITE(HSW_PWR_WELL_DRIVER, if (!(drv_req & mask))
HSW_PWR_WELL_ENABLE_REQUEST); I915_WRITE(HSW_PWR_WELL_DRIVER, drv_req | mask);
I915_WRITE(HSW_PWR_WELL_BIOS, 0); I915_WRITE(HSW_PWR_WELL_BIOS, bios_req & ~mask);
} }
} }
static bool skl_power_well_enabled(struct drm_i915_private *dev_priv, static bool skl_power_well_enabled(struct drm_i915_private *dev_priv,
struct i915_power_well *power_well) 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) |
SKL_POWER_WELL_STATE(power_well->id); HSW_PWR_WELL_CTL_STATE(power_well->id);
return (I915_READ(HSW_PWR_WELL_DRIVER) & mask) == mask; 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, ...@@ -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, static void skl_power_well_sync_hw(struct drm_i915_private *dev_priv,
struct i915_power_well *power_well) 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); uint32_t bios_req = I915_READ(HSW_PWR_WELL_BIOS);
/* Take over the request bit if set by BIOS. */ /* Take over the request bit if set by BIOS. */
......
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