drm/i915: add support for SBI ops
authorEugeni Dodonov <eugeni.dodonov@intel.com>
Wed, 9 May 2012 18:37:10 +0000 (15:37 -0300)
committerDaniel Vetter <daniel.vetter@ffwll.ch>
Sat, 19 May 2012 20:39:43 +0000 (22:39 +0200)
With Lynx Point, we need to use SBI to communicate with the display clock
control. This commit adds helper functions to access the registers via
SBI.

v2: de-inline the function and address changes in bits names

v3: protect operations with dpio_lock, increase timeout to 100 for
paranoia sake.

v4: decrease paranoia a bit, as noticed by Chris Wilson

Reviewed-by: Rodrigo Vivi <rodrigo.vivi@gmail.com>
Reviewed-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: Eugeni Dodonov <eugeni.dodonov@intel.com>
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
drivers/gpu/drm/i915/intel_display.c

index 42b9e20..45b93a0 100644 (file)
@@ -1299,6 +1299,69 @@ static void intel_disable_pll(struct drm_i915_private *dev_priv, enum pipe pipe)
        POSTING_READ(reg);
 }
 
+/* SBI access */
+static void
+intel_sbi_write(struct drm_i915_private *dev_priv, u16 reg, u32 value)
+{
+       unsigned long flags;
+
+       spin_lock_irqsave(&dev_priv->dpio_lock, flags);
+       if (wait_for((I915_READ(SBI_CTL_STAT) & SBI_READY) == 0,
+                               100)) {
+               DRM_ERROR("timeout waiting for SBI to become ready\n");
+               goto out_unlock;
+       }
+
+       I915_WRITE(SBI_ADDR,
+                       (reg << 16));
+       I915_WRITE(SBI_DATA,
+                       value);
+       I915_WRITE(SBI_CTL_STAT,
+                       SBI_BUSY |
+                       SBI_CTL_OP_CRWR);
+
+       if (wait_for((I915_READ(SBI_CTL_STAT) & (SBI_READY | SBI_RESPONSE_SUCCESS)) == 0,
+                               100)) {
+               DRM_ERROR("timeout waiting for SBI to complete write transaction\n");
+               goto out_unlock;
+       }
+
+out_unlock:
+       spin_unlock_irqrestore(&dev_priv->dpio_lock, flags);
+}
+
+static u32
+intel_sbi_read(struct drm_i915_private *dev_priv, u16 reg)
+{
+       unsigned long flags;
+       u32 value;
+
+       spin_lock_irqsave(&dev_priv->dpio_lock, flags);
+       if (wait_for((I915_READ(SBI_CTL_STAT) & SBI_READY) == 0,
+                               100)) {
+               DRM_ERROR("timeout waiting for SBI to become ready\n");
+               goto out_unlock;
+       }
+
+       I915_WRITE(SBI_ADDR,
+                       (reg << 16));
+       I915_WRITE(SBI_CTL_STAT,
+                       SBI_BUSY |
+                       SBI_CTL_OP_CRRD);
+
+       if (wait_for((I915_READ(SBI_CTL_STAT) & (SBI_READY | SBI_RESPONSE_SUCCESS)) == 0,
+                               100)) {
+               DRM_ERROR("timeout waiting for SBI to complete read transaction\n");
+               goto out_unlock;
+       }
+
+       value = I915_READ(SBI_DATA);
+
+out_unlock:
+       spin_unlock_irqrestore(&dev_priv->dpio_lock, flags);
+       return value;
+}
+
 /**
  * intel_enable_pch_pll - enable PCH PLL
  * @dev_priv: i915 private structure