Slightly different than other platforms.

v2 [Jani]: Fix IOSF_BYTE_ENABLES_SHIFT shift. Use common routine.
v3: drop turbo defines from this patch (Ville)
    use PCI_DEVFN(2,0) instead of open coding (Ville)

Reviewed-by: Ville Syrjälä <ville.syrj...@linux.intel.com>
Signed-off-by: Jesse Barnes <jbar...@virtuousgeek.org>
Signed-off-by: Jani Nikula <jani.nik...@intel.com>
---
 drivers/gpu/drm/i915/i915_drv.h |    2 ++
 drivers/gpu/drm/i915/i915_reg.h |   14 +++++++++++
 drivers/gpu/drm/i915/intel_pm.c |   53 +++++++++++++++++++++++++++++++++++++++
 3 files changed, 69 insertions(+)

diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 182c494..642cb1f 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -1845,6 +1845,8 @@ int __gen6_gt_wait_for_fifo(struct drm_i915_private 
*dev_priv);
 
 int sandybridge_pcode_read(struct drm_i915_private *dev_priv, u8 mbox, u32 
*val);
 int sandybridge_pcode_write(struct drm_i915_private *dev_priv, u8 mbox, u32 
val);
+int valleyview_punit_read(struct drm_i915_private *dev_priv, u8 addr, u32 
*val);
+int valleyview_punit_write(struct drm_i915_private *dev_priv, u8 addr, u32 
val);
 
 #define __i915_read(x, y) \
        u##x i915_read##x(struct drm_i915_private *dev_priv, u32 reg);
diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
index 68051d6..85f8b0b 100644
--- a/drivers/gpu/drm/i915/i915_reg.h
+++ b/drivers/gpu/drm/i915/i915_reg.h
@@ -4451,6 +4451,20 @@
 #define GEN6_PCODE_DATA                                0x138128
 #define   GEN6_PCODE_FREQ_IA_RATIO_SHIFT       8
 
+#define VLV_IOSF_DOORBELL_REQ                  0x182100
+#define   IOSF_DEVFN_SHIFT                     24
+#define   IOSF_OPCODE_SHIFT                    16
+#define   IOSF_PORT_SHIFT                      8
+#define   IOSF_BYTE_ENABLES_SHIFT              4
+#define   IOSF_BAR_SHIFT                       1
+#define   IOSF_SB_BUSY                         (1<<0)
+#define   IOSF_PORT_PUNIT                      0x4
+#define VLV_IOSF_DATA                          0x182104
+#define VLV_IOSF_ADDR                          0x182108
+
+#define PUNIT_OPCODE_REG_READ                  6
+#define PUNIT_OPCODE_REG_WRITE                 7
+
 #define GEN6_GT_CORE_STATUS            0x138060
 #define   GEN6_CORE_CPD_STATE_MASK     (7<<4)
 #define   GEN6_RCn_MASK                        7
diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
index 6fa9b79..9776281 100644
--- a/drivers/gpu/drm/i915/intel_pm.c
+++ b/drivers/gpu/drm/i915/intel_pm.c
@@ -4525,3 +4525,56 @@ int sandybridge_pcode_write(struct drm_i915_private 
*dev_priv, u8 mbox, u32 val)
 
        return 0;
 }
+
+static int vlv_punit_rw(struct drm_i915_private *dev_priv, u8 opcode,
+                       u8 addr, u32 *val)
+{
+       u32 cmd, devfn, port, be, bar;
+
+       bar = 0;
+       be = 0xf;
+       port = IOSF_PORT_PUNIT;
+       devfn = PCI_DEVFN(2,0);
+
+       cmd = (devfn << IOSF_DEVFN_SHIFT) | (opcode << IOSF_OPCODE_SHIFT) |
+               (port << IOSF_PORT_SHIFT) | (be << IOSF_BYTE_ENABLES_SHIFT) |
+               (bar << IOSF_BAR_SHIFT);
+
+       WARN_ON(!mutex_is_locked(&dev_priv->rps.hw_lock));
+
+       if (I915_READ(VLV_IOSF_DOORBELL_REQ) & IOSF_SB_BUSY) {
+               DRM_DEBUG_DRIVER("warning: pcode (%s) mailbox access failed\n",
+                                opcode == PUNIT_OPCODE_REG_READ ?
+                                "read" : "write");
+               return -EAGAIN;
+       }
+
+       I915_WRITE(VLV_IOSF_ADDR, addr);
+       if (opcode == PUNIT_OPCODE_REG_WRITE)
+               I915_WRITE(VLV_IOSF_DATA, *val);
+       I915_WRITE(VLV_IOSF_DOORBELL_REQ, cmd);
+
+       if (wait_for((I915_READ(VLV_IOSF_DOORBELL_REQ) & IOSF_SB_BUSY) == 0,
+                    500)) {
+               DRM_ERROR("timeout waiting for pcode %s (%d) to finish\n",
+                         opcode == PUNIT_OPCODE_REG_READ ? "read" : "write",
+                         addr);
+               return -ETIMEDOUT;
+       }
+
+       if (opcode == PUNIT_OPCODE_REG_READ)
+               *val = I915_READ(VLV_IOSF_DATA);
+       I915_WRITE(VLV_IOSF_DATA, 0);
+
+       return 0;
+}
+
+int valleyview_punit_read(struct drm_i915_private *dev_priv, u8 addr, u32 *val)
+{
+       return vlv_punit_rw(dev_priv, PUNIT_OPCODE_REG_READ, addr, val);
+}
+
+int valleyview_punit_write(struct drm_i915_private *dev_priv, u8 addr, u32 val)
+{
+       return vlv_punit_rw(dev_priv, PUNIT_OPCODE_REG_WRITE, addr, &val);
+}
-- 
1.7.10.4

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

Reply via email to