Skip to content

Commit

Permalink
drm/i915: add support for mPHY destination on intel_sbi_{read, write}
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Paulo Zanoni authored and Daniel Vetter committed Dec 10, 2012
1 parent d4b1931 commit 988d6ee
Show file tree
Hide file tree
Showing 3 changed files with 40 additions and 34 deletions.
5 changes: 5 additions & 0 deletions drivers/gpu/drm/i915/i915_drv.h
Original file line number Diff line number Diff line change
Expand Up @@ -382,6 +382,11 @@ enum intel_pch {
PCH_LPT, /* Lynxpoint PCH */
};

enum intel_sbi_destination {
SBI_ICLK,
SBI_MPHY,
};

#define QUIRK_PIPEA_FORCE (1<<0)
#define QUIRK_LVDS_SSC_DISABLE (1<<1)
#define QUIRK_INVERT_BRIGHTNESS (1<<2)
Expand Down
4 changes: 4 additions & 0 deletions drivers/gpu/drm/i915/i915_reg.h
Original file line number Diff line number Diff line change
Expand Up @@ -4534,6 +4534,10 @@
#define SBI_ADDR 0xC6000
#define SBI_DATA 0xC6004
#define SBI_CTL_STAT 0xC6008
#define SBI_CTL_DEST_ICLK (0x0<<16)
#define SBI_CTL_DEST_MPHY (0x1<<16)
#define SBI_CTL_OP_IORD (0x2<<8)
#define SBI_CTL_OP_IOWR (0x3<<8)
#define SBI_CTL_OP_CRRD (0x6<<8)
#define SBI_CTL_OP_CRWR (0x7<<8)
#define SBI_RESPONSE_FAIL (0x1<<1)
Expand Down
65 changes: 31 additions & 34 deletions drivers/gpu/drm/i915/intel_display.c
Original file line number Diff line number Diff line change
Expand Up @@ -1506,24 +1506,26 @@ static void intel_disable_pll(struct drm_i915_private *dev_priv, enum pipe pipe)

/* SBI access */
static void
intel_sbi_write(struct drm_i915_private *dev_priv, u16 reg, u32 value)
intel_sbi_write(struct drm_i915_private *dev_priv, u16 reg, u32 value,
enum intel_sbi_destination destination)
{
unsigned long flags;
u32 tmp;

spin_lock_irqsave(&dev_priv->dpio_lock, flags);
if (wait_for((I915_READ(SBI_CTL_STAT) & SBI_BUSY) == 0,
100)) {
if (wait_for((I915_READ(SBI_CTL_STAT) & SBI_BUSY) == 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);
I915_WRITE(SBI_ADDR, (reg << 16));
I915_WRITE(SBI_DATA, value);

if (destination == SBI_ICLK)
tmp = SBI_CTL_DEST_ICLK | SBI_CTL_OP_CRWR;
else
tmp = SBI_CTL_DEST_MPHY | SBI_CTL_OP_IOWR;
I915_WRITE(SBI_CTL_STAT, SBI_BUSY | tmp);

if (wait_for((I915_READ(SBI_CTL_STAT) & (SBI_BUSY | SBI_RESPONSE_FAIL)) == 0,
100)) {
Expand All @@ -1536,23 +1538,25 @@ intel_sbi_write(struct drm_i915_private *dev_priv, u16 reg, u32 value)
}

static u32
intel_sbi_read(struct drm_i915_private *dev_priv, u16 reg)
intel_sbi_read(struct drm_i915_private *dev_priv, u16 reg,
enum intel_sbi_destination destination)
{
unsigned long flags;
u32 value = 0;

spin_lock_irqsave(&dev_priv->dpio_lock, flags);
if (wait_for((I915_READ(SBI_CTL_STAT) & SBI_BUSY) == 0,
100)) {
if (wait_for((I915_READ(SBI_CTL_STAT) & SBI_BUSY) == 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);
I915_WRITE(SBI_ADDR, (reg << 16));

if (destination == SBI_ICLK)
value = SBI_CTL_DEST_ICLK | SBI_CTL_OP_CRRD;
else
value = SBI_CTL_DEST_MPHY | SBI_CTL_OP_IORD;
I915_WRITE(SBI_CTL_STAT, value | SBI_BUSY);

if (wait_for((I915_READ(SBI_CTL_STAT) & (SBI_BUSY | SBI_RESPONSE_FAIL)) == 0,
100)) {
Expand Down Expand Up @@ -3024,8 +3028,9 @@ static void lpt_program_iclkip(struct drm_crtc *crtc)

/* Disable SSCCTL */
intel_sbi_write(dev_priv, SBI_SSCCTL6,
intel_sbi_read(dev_priv, SBI_SSCCTL6) |
SBI_SSCCTL_DISABLE);
intel_sbi_read(dev_priv, SBI_SSCCTL6, SBI_ICLK) |
SBI_SSCCTL_DISABLE,
SBI_ICLK);

/* 20MHz is a corner case which is out of range for the 7-bit divisor */
if (crtc->mode.clock == 20000) {
Expand Down Expand Up @@ -3066,33 +3071,25 @@ static void lpt_program_iclkip(struct drm_crtc *crtc)
phaseinc);

/* Program SSCDIVINTPHASE6 */
temp = intel_sbi_read(dev_priv, SBI_SSCDIVINTPHASE6);
temp = intel_sbi_read(dev_priv, SBI_SSCDIVINTPHASE6, SBI_ICLK);
temp &= ~SBI_SSCDIVINTPHASE_DIVSEL_MASK;
temp |= SBI_SSCDIVINTPHASE_DIVSEL(divsel);
temp &= ~SBI_SSCDIVINTPHASE_INCVAL_MASK;
temp |= SBI_SSCDIVINTPHASE_INCVAL(phaseinc);
temp |= SBI_SSCDIVINTPHASE_DIR(phasedir);
temp |= SBI_SSCDIVINTPHASE_PROPAGATE;

intel_sbi_write(dev_priv,
SBI_SSCDIVINTPHASE6,
temp);
intel_sbi_write(dev_priv, SBI_SSCDIVINTPHASE6, temp, SBI_ICLK);

/* Program SSCAUXDIV */
temp = intel_sbi_read(dev_priv, SBI_SSCAUXDIV6);
temp = intel_sbi_read(dev_priv, SBI_SSCAUXDIV6, SBI_ICLK);
temp &= ~SBI_SSCAUXDIV_FINALDIV2SEL(1);
temp |= SBI_SSCAUXDIV_FINALDIV2SEL(auxdiv);
intel_sbi_write(dev_priv,
SBI_SSCAUXDIV6,
temp);

intel_sbi_write(dev_priv, SBI_SSCAUXDIV6, temp, SBI_ICLK);

/* Enable modulator and associated divider */
temp = intel_sbi_read(dev_priv, SBI_SSCCTL6);
temp = intel_sbi_read(dev_priv, SBI_SSCCTL6, SBI_ICLK);
temp &= ~SBI_SSCCTL_DISABLE;
intel_sbi_write(dev_priv,
SBI_SSCCTL6,
temp);
intel_sbi_write(dev_priv, SBI_SSCCTL6, temp, SBI_ICLK);

/* Wait for initialization time */
udelay(24);
Expand Down

0 comments on commit 988d6ee

Please sign in to comment.