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.d...@intel.com>
---
 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@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

Reply via email to