aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm
diff options
context:
space:
mode:
authorPaulo Zanoni <paulo.r.zanoni@intel.com>2012-12-01 09:04:24 -0500
committerDaniel Vetter <daniel.vetter@ffwll.ch>2012-12-10 04:24:16 -0500
commit988d6ee8b2e8694830036821933372b22f3d1935 (patch)
tree05f6a291af464d673c23726ace4bd9ba3353d279 /drivers/gpu/drm
parentd4b1931c149e1cf78a930d7abde00bd378272e6e (diff)
drm/i915: add support for mPHY destination on intel_sbi_{read, write}
This way we should be able to write mPHY registers using the Sideband Interface in the next commit. Also fixed some syntax oddities in the related code. Signed-off-by: Paulo Zanoni <paulo.r.zanoni@intel.com> Reviewed-by: Damien Lespiau <damien.lespiau@intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Diffstat (limited to 'drivers/gpu/drm')
-rw-r--r--drivers/gpu/drm/i915/i915_drv.h5
-rw-r--r--drivers/gpu/drm/i915/i915_reg.h4
-rw-r--r--drivers/gpu/drm/i915/intel_display.c65
3 files changed, 40 insertions, 34 deletions
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 79589bbff3d..8513e1cd221 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -382,6 +382,11 @@ enum intel_pch {
382 PCH_LPT, /* Lynxpoint PCH */ 382 PCH_LPT, /* Lynxpoint PCH */
383}; 383};
384 384
385enum intel_sbi_destination {
386 SBI_ICLK,
387 SBI_MPHY,
388};
389
385#define QUIRK_PIPEA_FORCE (1<<0) 390#define QUIRK_PIPEA_FORCE (1<<0)
386#define QUIRK_LVDS_SSC_DISABLE (1<<1) 391#define QUIRK_LVDS_SSC_DISABLE (1<<1)
387#define QUIRK_INVERT_BRIGHTNESS (1<<2) 392#define QUIRK_INVERT_BRIGHTNESS (1<<2)
diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
index 97fbd9d1823..0760425c892 100644
--- a/drivers/gpu/drm/i915/i915_reg.h
+++ b/drivers/gpu/drm/i915/i915_reg.h
@@ -4534,6 +4534,10 @@
4534#define SBI_ADDR 0xC6000 4534#define SBI_ADDR 0xC6000
4535#define SBI_DATA 0xC6004 4535#define SBI_DATA 0xC6004
4536#define SBI_CTL_STAT 0xC6008 4536#define SBI_CTL_STAT 0xC6008
4537#define SBI_CTL_DEST_ICLK (0x0<<16)
4538#define SBI_CTL_DEST_MPHY (0x1<<16)
4539#define SBI_CTL_OP_IORD (0x2<<8)
4540#define SBI_CTL_OP_IOWR (0x3<<8)
4537#define SBI_CTL_OP_CRRD (0x6<<8) 4541#define SBI_CTL_OP_CRRD (0x6<<8)
4538#define SBI_CTL_OP_CRWR (0x7<<8) 4542#define SBI_CTL_OP_CRWR (0x7<<8)
4539#define SBI_RESPONSE_FAIL (0x1<<1) 4543#define SBI_RESPONSE_FAIL (0x1<<1)
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 41e2d9508ef..64993ecacf9 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -1506,24 +1506,26 @@ static void intel_disable_pll(struct drm_i915_private *dev_priv, enum pipe pipe)
1506 1506
1507/* SBI access */ 1507/* SBI access */
1508static void 1508static void
1509intel_sbi_write(struct drm_i915_private *dev_priv, u16 reg, u32 value) 1509intel_sbi_write(struct drm_i915_private *dev_priv, u16 reg, u32 value,
1510 enum intel_sbi_destination destination)
1510{ 1511{
1511 unsigned long flags; 1512 unsigned long flags;
1513 u32 tmp;
1512 1514
1513 spin_lock_irqsave(&dev_priv->dpio_lock, flags); 1515 spin_lock_irqsave(&dev_priv->dpio_lock, flags);
1514 if (wait_for((I915_READ(SBI_CTL_STAT) & SBI_BUSY) == 0, 1516 if (wait_for((I915_READ(SBI_CTL_STAT) & SBI_BUSY) == 0, 100)) {
1515 100)) {
1516 DRM_ERROR("timeout waiting for SBI to become ready\n"); 1517 DRM_ERROR("timeout waiting for SBI to become ready\n");
1517 goto out_unlock; 1518 goto out_unlock;
1518 } 1519 }
1519 1520
1520 I915_WRITE(SBI_ADDR, 1521 I915_WRITE(SBI_ADDR, (reg << 16));
1521 (reg << 16)); 1522 I915_WRITE(SBI_DATA, value);
1522 I915_WRITE(SBI_DATA, 1523
1523 value); 1524 if (destination == SBI_ICLK)
1524 I915_WRITE(SBI_CTL_STAT, 1525 tmp = SBI_CTL_DEST_ICLK | SBI_CTL_OP_CRWR;
1525 SBI_BUSY | 1526 else
1526 SBI_CTL_OP_CRWR); 1527 tmp = SBI_CTL_DEST_MPHY | SBI_CTL_OP_IOWR;
1528 I915_WRITE(SBI_CTL_STAT, SBI_BUSY | tmp);
1527 1529
1528 if (wait_for((I915_READ(SBI_CTL_STAT) & (SBI_BUSY | SBI_RESPONSE_FAIL)) == 0, 1530 if (wait_for((I915_READ(SBI_CTL_STAT) & (SBI_BUSY | SBI_RESPONSE_FAIL)) == 0,
1529 100)) { 1531 100)) {
@@ -1536,23 +1538,25 @@ out_unlock:
1536} 1538}
1537 1539
1538static u32 1540static u32
1539intel_sbi_read(struct drm_i915_private *dev_priv, u16 reg) 1541intel_sbi_read(struct drm_i915_private *dev_priv, u16 reg,
1542 enum intel_sbi_destination destination)
1540{ 1543{
1541 unsigned long flags; 1544 unsigned long flags;
1542 u32 value = 0; 1545 u32 value = 0;
1543 1546
1544 spin_lock_irqsave(&dev_priv->dpio_lock, flags); 1547 spin_lock_irqsave(&dev_priv->dpio_lock, flags);
1545 if (wait_for((I915_READ(SBI_CTL_STAT) & SBI_BUSY) == 0, 1548 if (wait_for((I915_READ(SBI_CTL_STAT) & SBI_BUSY) == 0, 100)) {
1546 100)) {
1547 DRM_ERROR("timeout waiting for SBI to become ready\n"); 1549 DRM_ERROR("timeout waiting for SBI to become ready\n");
1548 goto out_unlock; 1550 goto out_unlock;
1549 } 1551 }
1550 1552
1551 I915_WRITE(SBI_ADDR, 1553 I915_WRITE(SBI_ADDR, (reg << 16));
1552 (reg << 16)); 1554
1553 I915_WRITE(SBI_CTL_STAT, 1555 if (destination == SBI_ICLK)
1554 SBI_BUSY | 1556 value = SBI_CTL_DEST_ICLK | SBI_CTL_OP_CRRD;
1555 SBI_CTL_OP_CRRD); 1557 else
1558 value = SBI_CTL_DEST_MPHY | SBI_CTL_OP_IORD;
1559 I915_WRITE(SBI_CTL_STAT, value | SBI_BUSY);
1556 1560
1557 if (wait_for((I915_READ(SBI_CTL_STAT) & (SBI_BUSY | SBI_RESPONSE_FAIL)) == 0, 1561 if (wait_for((I915_READ(SBI_CTL_STAT) & (SBI_BUSY | SBI_RESPONSE_FAIL)) == 0,
1558 100)) { 1562 100)) {
@@ -3024,8 +3028,9 @@ static void lpt_program_iclkip(struct drm_crtc *crtc)
3024 3028
3025 /* Disable SSCCTL */ 3029 /* Disable SSCCTL */
3026 intel_sbi_write(dev_priv, SBI_SSCCTL6, 3030 intel_sbi_write(dev_priv, SBI_SSCCTL6,
3027 intel_sbi_read(dev_priv, SBI_SSCCTL6) | 3031 intel_sbi_read(dev_priv, SBI_SSCCTL6, SBI_ICLK) |
3028 SBI_SSCCTL_DISABLE); 3032 SBI_SSCCTL_DISABLE,
3033 SBI_ICLK);
3029 3034
3030 /* 20MHz is a corner case which is out of range for the 7-bit divisor */ 3035 /* 20MHz is a corner case which is out of range for the 7-bit divisor */
3031 if (crtc->mode.clock == 20000) { 3036 if (crtc->mode.clock == 20000) {
@@ -3066,33 +3071,25 @@ static void lpt_program_iclkip(struct drm_crtc *crtc)
3066 phaseinc); 3071 phaseinc);
3067 3072
3068 /* Program SSCDIVINTPHASE6 */ 3073 /* Program SSCDIVINTPHASE6 */
3069 temp = intel_sbi_read(dev_priv, SBI_SSCDIVINTPHASE6); 3074 temp = intel_sbi_read(dev_priv, SBI_SSCDIVINTPHASE6, SBI_ICLK);
3070 temp &= ~SBI_SSCDIVINTPHASE_DIVSEL_MASK; 3075 temp &= ~SBI_SSCDIVINTPHASE_DIVSEL_MASK;
3071 temp |= SBI_SSCDIVINTPHASE_DIVSEL(divsel); 3076 temp |= SBI_SSCDIVINTPHASE_DIVSEL(divsel);
3072 temp &= ~SBI_SSCDIVINTPHASE_INCVAL_MASK; 3077 temp &= ~SBI_SSCDIVINTPHASE_INCVAL_MASK;
3073 temp |= SBI_SSCDIVINTPHASE_INCVAL(phaseinc); 3078 temp |= SBI_SSCDIVINTPHASE_INCVAL(phaseinc);
3074 temp |= SBI_SSCDIVINTPHASE_DIR(phasedir); 3079 temp |= SBI_SSCDIVINTPHASE_DIR(phasedir);
3075 temp |= SBI_SSCDIVINTPHASE_PROPAGATE; 3080 temp |= SBI_SSCDIVINTPHASE_PROPAGATE;
3076 3081 intel_sbi_write(dev_priv, SBI_SSCDIVINTPHASE6, temp, SBI_ICLK);
3077 intel_sbi_write(dev_priv,
3078 SBI_SSCDIVINTPHASE6,
3079 temp);
3080 3082
3081 /* Program SSCAUXDIV */ 3083 /* Program SSCAUXDIV */
3082 temp = intel_sbi_read(dev_priv, SBI_SSCAUXDIV6); 3084 temp = intel_sbi_read(dev_priv, SBI_SSCAUXDIV6, SBI_ICLK);
3083 temp &= ~SBI_SSCAUXDIV_FINALDIV2SEL(1); 3085 temp &= ~SBI_SSCAUXDIV_FINALDIV2SEL(1);
3084 temp |= SBI_SSCAUXDIV_FINALDIV2SEL(auxdiv); 3086 temp |= SBI_SSCAUXDIV_FINALDIV2SEL(auxdiv);
3085 intel_sbi_write(dev_priv, 3087 intel_sbi_write(dev_priv, SBI_SSCAUXDIV6, temp, SBI_ICLK);
3086 SBI_SSCAUXDIV6,
3087 temp);
3088
3089 3088
3090 /* Enable modulator and associated divider */ 3089 /* Enable modulator and associated divider */
3091 temp = intel_sbi_read(dev_priv, SBI_SSCCTL6); 3090 temp = intel_sbi_read(dev_priv, SBI_SSCCTL6, SBI_ICLK);
3092 temp &= ~SBI_SSCCTL_DISABLE; 3091 temp &= ~SBI_SSCCTL_DISABLE;
3093 intel_sbi_write(dev_priv, 3092 intel_sbi_write(dev_priv, SBI_SSCCTL6, temp, SBI_ICLK);
3094 SBI_SSCCTL6,
3095 temp);
3096 3093
3097 /* Wait for initialization time */ 3094 /* Wait for initialization time */
3098 udelay(24); 3095 udelay(24);