Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit a0e4e199 authored by Jesse Barnes's avatar Jesse Barnes Committed by Daniel Vetter
Browse files

drm/i915: add Punit read/write routines for VLV v2



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: default avatarVille Syrjälä <ville.syrjala@linux.intel.com>
Signed-off-by: default avatarJesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: default avatarJani Nikula <jani.nikula@intel.com>
[danvet: Add checkpatch bikeshed about missing space.]
Signed-off-by: default avatarDaniel Vetter <daniel.vetter@ffwll.ch>
parent 453c5420
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -1863,6 +1863,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);
+14 −0
Original line number Diff line number Diff line
@@ -4381,6 +4381,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
+53 −0
Original line number Diff line number Diff line
@@ -4536,3 +4536,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);
}