diff mbox

[08/11] drm/i915: add Punit read/write routines for VLV

Message ID 1364489747-2050-8-git-send-email-jbarnes@virtuousgeek.org (mailing list archive)
State New, archived
Headers show

Commit Message

Jesse Barnes March 28, 2013, 4:55 p.m. UTC
Slightly different than other platforms.

v2 [Jani]: Fix IOSF_BYTE_ENABLES_SHIFT shift. Use common routine.

Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: Jani Nikula <jani.nikula@intel.com>
---
 drivers/gpu/drm/i915/i915_drv.h |    2 ++
 drivers/gpu/drm/i915/i915_reg.h |   22 ++++++++++++++++
 drivers/gpu/drm/i915/intel_pm.c |   53 +++++++++++++++++++++++++++++++++++++++
 3 files changed, 77 insertions(+)

Comments

Ville Syrjälä April 2, 2013, 11:37 a.m. UTC | #1
On Thu, Mar 28, 2013 at 09:55:44AM -0700, Jesse Barnes wrote:
> Slightly different than other platforms.
> 
> v2 [Jani]: Fix IOSF_BYTE_ENABLES_SHIFT shift. Use common routine.
> 
> Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
> Signed-off-by: Jani Nikula <jani.nikula@intel.com>
> ---
>  drivers/gpu/drm/i915/i915_drv.h |    2 ++
>  drivers/gpu/drm/i915/i915_reg.h |   22 ++++++++++++++++
>  drivers/gpu/drm/i915/intel_pm.c |   53 +++++++++++++++++++++++++++++++++++++++
>  3 files changed, 77 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..87a59eb 100644
> --- a/drivers/gpu/drm/i915/i915_reg.h
> +++ b/drivers/gpu/drm/i915/i915_reg.h
> @@ -4451,6 +4451,28 @@
>  #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_REG_GPU_LFM			0xd3
> +#define PUNIT_REG_GPU_FREQ_REQ			0xd4
> +#define PUNIT_REG_GPU_FREQ_STS			0xd8
> +#define PUNIT_REG_MEDIA_TURBO_FREQ_REQ		0xdc

These should be part of the turbo patch.

> +
> +#define PUNIT_OPCODE_REG_READ			6
> +#define PUNIT_OPCODE_REG_WRITE			7
> +
> +#define PUNIT_FUSE_BUS2				0xf6 /* bits 47:40 */
> +#define PUNIT_FUSE_BUS1				0xf5 /* bits 55:48 */

Ditto.

> +
>  #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..8256d0d 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 = 16;

PCI_DEVFN(2,0) maybe? I think I'm missing some doc that tells
me what kind of magic devfn and bar should contain.

Apart from those small nits:
Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com>

> +
> +	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
Jesse Barnes April 2, 2013, 6:19 p.m. UTC | #2
On Tue, 2 Apr 2013 14:37:42 +0300
Ville Syrjälä <ville.syrjala@linux.intel.com> wrote:

> On Thu, Mar 28, 2013 at 09:55:44AM -0700, Jesse Barnes wrote:
> > Slightly different than other platforms.
> > 
> > v2 [Jani]: Fix IOSF_BYTE_ENABLES_SHIFT shift. Use common routine.
> > 
> > Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
> > Signed-off-by: Jani Nikula <jani.nikula@intel.com>

Fixed these up, thanks.
diff mbox

Patch

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..87a59eb 100644
--- a/drivers/gpu/drm/i915/i915_reg.h
+++ b/drivers/gpu/drm/i915/i915_reg.h
@@ -4451,6 +4451,28 @@ 
 #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_REG_GPU_LFM			0xd3
+#define PUNIT_REG_GPU_FREQ_REQ			0xd4
+#define PUNIT_REG_GPU_FREQ_STS			0xd8
+#define PUNIT_REG_MEDIA_TURBO_FREQ_REQ		0xdc
+
+#define PUNIT_OPCODE_REG_READ			6
+#define PUNIT_OPCODE_REG_WRITE			7
+
+#define PUNIT_FUSE_BUS2				0xf6 /* bits 47:40 */
+#define PUNIT_FUSE_BUS1				0xf5 /* bits 55:48 */
+
 #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..8256d0d 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 = 16;
+
+	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);
+}