[Intel-gfx] [PATCH] drm/i915: Hold forcewake for whole of punit communication
Chris Wilson
chris at chris-wilson.co.uk
Wed Feb 15 10:41:29 UTC 2017
Take the forcewake for punit access and hold it across our waits to
ensure that the powerwell is not dropped by a spurious sleep.
Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>
Cc: Mika Kuoppala <mika.kuoppala at intel.com>
---
drivers/gpu/drm/i915/intel_sideband.c | 55 ++++++++++++++++++++++-------------
1 file changed, 34 insertions(+), 21 deletions(-)
diff --git a/drivers/gpu/drm/i915/intel_sideband.c b/drivers/gpu/drm/i915/intel_sideband.c
index 9f782b5eb6e6..ce6d166d67ea 100644
--- a/drivers/gpu/drm/i915/intel_sideband.c
+++ b/drivers/gpu/drm/i915/intel_sideband.c
@@ -39,42 +39,55 @@
/* Private register write, double-word addressing, non-posted */
#define SB_CRWRDA_NP 0x07
-static int vlv_sideband_rw(struct drm_i915_private *dev_priv, u32 devfn,
- u32 port, u32 opcode, u32 addr, u32 *val)
+static int vlv_sideband_rw(struct drm_i915_private *dev_priv,
+ u32 devfn, u32 port, u32 opcode, u32 addr,
+ u32 *val)
{
- u32 cmd, be = 0xf, bar = 0;
- bool is_read = (opcode == SB_MRD_NP || opcode == SB_CRRDDA_NP);
+ const bool is_read = (opcode == SB_MRD_NP || opcode == SB_CRRDDA_NP);
+ enum forcewake_domains fw_domains;
+ int err = 0;
- cmd = (devfn << IOSF_DEVFN_SHIFT) | (opcode << IOSF_OPCODE_SHIFT) |
- (port << IOSF_PORT_SHIFT) | (be << IOSF_BYTE_ENABLES_SHIFT) |
- (bar << IOSF_BAR_SHIFT);
+ lockdep_assert_held(&dev_priv->sb_lock);
- WARN_ON(!mutex_is_locked(&dev_priv->sb_lock));
+ fw_domains = intel_uncore_forcewake_for_reg(dev_priv,
+ VLV_IOSF_DOORBELL_REQ,
+ FW_REG_READ | FW_REG_WRITE);
+ intel_uncore_forcewake_get(dev_priv, fw_domains);
- if (intel_wait_for_register(dev_priv,
- VLV_IOSF_DOORBELL_REQ, IOSF_SB_BUSY, 0,
- 5)) {
+ if (intel_wait_for_register_fw(dev_priv,
+ VLV_IOSF_DOORBELL_REQ, IOSF_SB_BUSY, 0,
+ 5)) {
DRM_DEBUG_DRIVER("IOSF sideband idle wait (%s) timed out\n",
is_read ? "read" : "write");
- return -EAGAIN;
+ err = -EAGAIN;
+ goto out;
}
- I915_WRITE(VLV_IOSF_ADDR, addr);
- I915_WRITE(VLV_IOSF_DATA, is_read ? 0 : *val);
- I915_WRITE(VLV_IOSF_DOORBELL_REQ, cmd);
+ I915_WRITE_FW(VLV_IOSF_ADDR, addr);
+ I915_WRITE_FW(VLV_IOSF_DATA, is_read ? 0 : *val);
+ I915_WRITE_FW(VLV_IOSF_DOORBELL_REQ,
+ (devfn << IOSF_DEVFN_SHIFT) |
+ (opcode << IOSF_OPCODE_SHIFT) |
+ (port << IOSF_PORT_SHIFT) |
+ (0xf << IOSF_BYTE_ENABLES_SHIFT) |
+ (0 << IOSF_BAR_SHIFT));
- if (intel_wait_for_register(dev_priv,
- VLV_IOSF_DOORBELL_REQ, IOSF_SB_BUSY, 0,
- 5)) {
+
+ if (intel_wait_for_register_fw(dev_priv,
+ VLV_IOSF_DOORBELL_REQ, IOSF_SB_BUSY, 0,
+ 5)) {
DRM_DEBUG_DRIVER("IOSF sideband finish wait (%s) timed out\n",
is_read ? "read" : "write");
- return -ETIMEDOUT;
+ err = -ETIMEDOUT;
+ goto out;
}
if (is_read)
- *val = I915_READ(VLV_IOSF_DATA);
+ *val = I915_READ_FW(VLV_IOSF_DATA);
- return 0;
+out:
+ intel_uncore_forcewake_put(dev_priv, fw_domains);
+ return err;
}
u32 vlv_punit_read(struct drm_i915_private *dev_priv, u32 addr)
--
2.11.0
More information about the Intel-gfx
mailing list