On Sat, 02 Feb 2013, Jesse Barnes <jbarnes at virtuousgeek.org> wrote: > Slightly different than other platforms. I'll do more review later, just pointing out an obvious bug below. BR, Jani. > > Signed-off-by: Jesse Barnes <jbarnes at virtuousgeek.org> > --- > drivers/gpu/drm/i915/i915_drv.h | 2 ++ > drivers/gpu/drm/i915/i915_reg.h | 22 ++++++++++++ > drivers/gpu/drm/i915/intel_pm.c | 74 +++++++++++++++++++++++++++++++++++++++ > 3 files changed, 98 insertions(+) > > diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h > index 34f01a9..60eee7d 100644 > --- a/drivers/gpu/drm/i915/i915_drv.h > +++ b/drivers/gpu/drm/i915/i915_drv.h > @@ -1749,6 +1749,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, bool trace); > diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h > index 7e13f34..7325b7a 100644 > --- a/drivers/gpu/drm/i915/i915_reg.h > +++ b/drivers/gpu/drm/i915/i915_reg.h > @@ -4335,6 +4335,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 7d812ba..bb97309 100644 > --- a/drivers/gpu/drm/i915/intel_pm.c > +++ b/drivers/gpu/drm/i915/intel_pm.c > @@ -4356,3 +4356,77 @@ int sandybridge_pcode_write(struct drm_i915_private *dev_priv, u8 mbox, u32 val) > > return 0; > } > + > +int valleyview_punit_read(struct drm_i915_private *dev_priv, u8 addr, u32 *val) > +{ > + u32 cmd, devfn, opcode, port, be, bar; > + > + bar = 0; > + be = 0xf; > + port = IOSF_PORT_PUNIT; > + opcode = PUNIT_OPCODE_REG_READ; > + devfn = 16; > + > + cmd = (devfn << IOSF_DEVFN_SHIFT) | (opcode << IOSF_OPCODE_SHIFT) | > + (port << IOSF_PORT_SHIFT) | (be | IOSF_BYTE_ENABLES_SHIFT) | Should be (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 (read) mailbox access failed\n"); > + return -EAGAIN; > + } > + > + I915_WRITE(VLV_IOSF_ADDR, addr); > + 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 read (%d) to finish\n", > + addr); > + return -ETIMEDOUT; > + } > + > + *val = I915_READ(VLV_IOSF_DATA); > + I915_WRITE(VLV_IOSF_DATA, 0); > + > + return 0; > +} > + > +int valleyview_punit_write(struct drm_i915_private *dev_priv, u8 addr, u32 val) > +{ > + u32 cmd, devfn, opcode, port, be, bar; > + > + bar = 0; > + be = 0xf; > + port = IOSF_PORT_PUNIT; > + opcode = PUNIT_OPCODE_REG_WRITE; > + devfn = 16; > + > + cmd = (devfn << IOSF_DEVFN_SHIFT) | (opcode << IOSF_OPCODE_SHIFT) | > + (port << IOSF_PORT_SHIFT) | (be | IOSF_BYTE_ENABLES_SHIFT) | Ditto. The obvious copy-pasting makes me note the read/write functions are roughly the same... would it make sense to have a static common routine behind the interface functions? Just add opcode parameter, and do *val = I915_READ(VLV_IOSF_DATA) and I915_WRITE(VLV_IOSF_DATA, *val) depending on that. > + (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 (write) mailbox access failed\n"); > + return -EAGAIN; > + } > + > + I915_WRITE(VLV_IOSF_ADDR, addr); > + 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 write (%d) to finish\n", > + addr); > + return -ETIMEDOUT; > + } > + > + I915_WRITE(VLV_IOSF_DATA, 0); > + > + return 0; > +} > -- > 1.7.9.5 > > _______________________________________________ > Intel-gfx mailing list > Intel-gfx at lists.freedesktop.org > http://lists.freedesktop.org/mailman/listinfo/intel-gfx