diff options
author | Jesse Barnes <jbarnes@virtuousgeek.org> | 2013-04-02 14:23:05 -0400 |
---|---|---|
committer | Daniel Vetter <daniel.vetter@ffwll.ch> | 2013-04-02 15:00:06 -0400 |
commit | a0e4e199ad18070e17d15b920a39c6ec9d95b793 (patch) | |
tree | 269f1c328d220ee13596f509d6191762f709cde9 /drivers/gpu | |
parent | 453c542059cfa1988cabcf84f715307cd9789163 (diff) |
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: Ville Syrjälä <ville.syrjala@linux.intel.com>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: Jani Nikula <jani.nikula@intel.com>
[danvet: Add checkpatch bikeshed about missing space.]
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Diffstat (limited to 'drivers/gpu')
-rw-r--r-- | drivers/gpu/drm/i915/i915_drv.h | 2 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/i915_reg.h | 14 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/intel_pm.c | 53 |
3 files changed, 69 insertions, 0 deletions
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index c895a8465611..2338c73ec217 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h | |||
@@ -1863,6 +1863,8 @@ int __gen6_gt_wait_for_fifo(struct drm_i915_private *dev_priv); | |||
1863 | 1863 | ||
1864 | int sandybridge_pcode_read(struct drm_i915_private *dev_priv, u8 mbox, u32 *val); | 1864 | int sandybridge_pcode_read(struct drm_i915_private *dev_priv, u8 mbox, u32 *val); |
1865 | int sandybridge_pcode_write(struct drm_i915_private *dev_priv, u8 mbox, u32 val); | 1865 | int sandybridge_pcode_write(struct drm_i915_private *dev_priv, u8 mbox, u32 val); |
1866 | int valleyview_punit_read(struct drm_i915_private *dev_priv, u8 addr, u32 *val); | ||
1867 | int valleyview_punit_write(struct drm_i915_private *dev_priv, u8 addr, u32 val); | ||
1866 | 1868 | ||
1867 | #define __i915_read(x, y) \ | 1869 | #define __i915_read(x, y) \ |
1868 | u##x i915_read##x(struct drm_i915_private *dev_priv, u32 reg); | 1870 | 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 37663696a56b..058686c0dbbf 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h | |||
@@ -4381,6 +4381,20 @@ | |||
4381 | #define GEN6_PCODE_DATA 0x138128 | 4381 | #define GEN6_PCODE_DATA 0x138128 |
4382 | #define GEN6_PCODE_FREQ_IA_RATIO_SHIFT 8 | 4382 | #define GEN6_PCODE_FREQ_IA_RATIO_SHIFT 8 |
4383 | 4383 | ||
4384 | #define VLV_IOSF_DOORBELL_REQ 0x182100 | ||
4385 | #define IOSF_DEVFN_SHIFT 24 | ||
4386 | #define IOSF_OPCODE_SHIFT 16 | ||
4387 | #define IOSF_PORT_SHIFT 8 | ||
4388 | #define IOSF_BYTE_ENABLES_SHIFT 4 | ||
4389 | #define IOSF_BAR_SHIFT 1 | ||
4390 | #define IOSF_SB_BUSY (1<<0) | ||
4391 | #define IOSF_PORT_PUNIT 0x4 | ||
4392 | #define VLV_IOSF_DATA 0x182104 | ||
4393 | #define VLV_IOSF_ADDR 0x182108 | ||
4394 | |||
4395 | #define PUNIT_OPCODE_REG_READ 6 | ||
4396 | #define PUNIT_OPCODE_REG_WRITE 7 | ||
4397 | |||
4384 | #define GEN6_GT_CORE_STATUS 0x138060 | 4398 | #define GEN6_GT_CORE_STATUS 0x138060 |
4385 | #define GEN6_CORE_CPD_STATE_MASK (7<<4) | 4399 | #define GEN6_CORE_CPD_STATE_MASK (7<<4) |
4386 | #define GEN6_RCn_MASK 7 | 4400 | #define GEN6_RCn_MASK 7 |
diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index 27f94cd19ee2..f48227ad5d33 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c | |||
@@ -4536,3 +4536,56 @@ int sandybridge_pcode_write(struct drm_i915_private *dev_priv, u8 mbox, u32 val) | |||
4536 | 4536 | ||
4537 | return 0; | 4537 | return 0; |
4538 | } | 4538 | } |
4539 | |||
4540 | static int vlv_punit_rw(struct drm_i915_private *dev_priv, u8 opcode, | ||
4541 | u8 addr, u32 *val) | ||
4542 | { | ||
4543 | u32 cmd, devfn, port, be, bar; | ||
4544 | |||
4545 | bar = 0; | ||
4546 | be = 0xf; | ||
4547 | port = IOSF_PORT_PUNIT; | ||
4548 | devfn = PCI_DEVFN(2, 0); | ||
4549 | |||
4550 | cmd = (devfn << IOSF_DEVFN_SHIFT) | (opcode << IOSF_OPCODE_SHIFT) | | ||
4551 | (port << IOSF_PORT_SHIFT) | (be << IOSF_BYTE_ENABLES_SHIFT) | | ||
4552 | (bar << IOSF_BAR_SHIFT); | ||
4553 | |||
4554 | WARN_ON(!mutex_is_locked(&dev_priv->rps.hw_lock)); | ||
4555 | |||
4556 | if (I915_READ(VLV_IOSF_DOORBELL_REQ) & IOSF_SB_BUSY) { | ||
4557 | DRM_DEBUG_DRIVER("warning: pcode (%s) mailbox access failed\n", | ||
4558 | opcode == PUNIT_OPCODE_REG_READ ? | ||
4559 | "read" : "write"); | ||
4560 | return -EAGAIN; | ||
4561 | } | ||
4562 | |||
4563 | I915_WRITE(VLV_IOSF_ADDR, addr); | ||
4564 | if (opcode == PUNIT_OPCODE_REG_WRITE) | ||
4565 | I915_WRITE(VLV_IOSF_DATA, *val); | ||
4566 | I915_WRITE(VLV_IOSF_DOORBELL_REQ, cmd); | ||
4567 | |||
4568 | if (wait_for((I915_READ(VLV_IOSF_DOORBELL_REQ) & IOSF_SB_BUSY) == 0, | ||
4569 | 500)) { | ||
4570 | DRM_ERROR("timeout waiting for pcode %s (%d) to finish\n", | ||
4571 | opcode == PUNIT_OPCODE_REG_READ ? "read" : "write", | ||
4572 | addr); | ||
4573 | return -ETIMEDOUT; | ||
4574 | } | ||
4575 | |||
4576 | if (opcode == PUNIT_OPCODE_REG_READ) | ||
4577 | *val = I915_READ(VLV_IOSF_DATA); | ||
4578 | I915_WRITE(VLV_IOSF_DATA, 0); | ||
4579 | |||
4580 | return 0; | ||
4581 | } | ||
4582 | |||
4583 | int valleyview_punit_read(struct drm_i915_private *dev_priv, u8 addr, u32 *val) | ||
4584 | { | ||
4585 | return vlv_punit_rw(dev_priv, PUNIT_OPCODE_REG_READ, addr, val); | ||
4586 | } | ||
4587 | |||
4588 | int valleyview_punit_write(struct drm_i915_private *dev_priv, u8 addr, u32 val) | ||
4589 | { | ||
4590 | return vlv_punit_rw(dev_priv, PUNIT_OPCODE_REG_WRITE, addr, &val); | ||
4591 | } | ||