Skip to content

Commit

Permalink
drm/i915: fix issue in display pipe setup on IGDNG
Browse files Browse the repository at this point in the history
During pipe DPMS off, instead of busy waiting pipe off, insert
delays during wait and don't loop after enough tries which matches
spec requirement. Also try to match DPMS on path by disable FDI TX
PLL in DPMS off. Disable PF by writing PF_WIN_SZ which really trigger
the update.

Signed-off-by: Zhenyu Wang <zhenyuw@linux.intel.com>
Signed-off-by: Eric Anholt <eric@anholt.net>
  • Loading branch information
Zhenyu Wang authored and Eric Anholt committed Jul 29, 2009
1 parent 24f119c commit 249c0e6
Show file tree
Hide file tree
Showing 2 changed files with 46 additions and 12 deletions.
2 changes: 2 additions & 0 deletions drivers/gpu/drm/i915/i915_reg.h
Original file line number Diff line number Diff line change
Expand Up @@ -1848,6 +1848,8 @@
#define PFA_CTL_1 0x68080
#define PFB_CTL_1 0x68880
#define PF_ENABLE (1<<31)
#define PFA_WIN_SZ 0x68074
#define PFB_WIN_SZ 0x68874

/* legacy palette */
#define LGC_PALETTE_A 0x4a000
Expand Down
56 changes: 44 additions & 12 deletions drivers/gpu/drm/i915/intel_display.c
Original file line number Diff line number Diff line change
Expand Up @@ -1038,6 +1038,7 @@ static void igdng_crtc_dpms(struct drm_crtc *crtc, int mode)
int fdi_rx_imr_reg = (pipe == 0) ? FDI_RXA_IMR : FDI_RXB_IMR;
int transconf_reg = (pipe == 0) ? TRANSACONF : TRANSBCONF;
int pf_ctl_reg = (pipe == 0) ? PFA_CTL_1 : PFB_CTL_1;
int pf_win_size = (pipe == 0) ? PFA_WIN_SZ : PFB_WIN_SZ;
int cpu_htot_reg = (pipe == 0) ? HTOTAL_A : HTOTAL_B;
int cpu_hblank_reg = (pipe == 0) ? HBLANK_A : HBLANK_B;
int cpu_hsync_reg = (pipe == 0) ? HSYNC_A : HSYNC_B;
Expand All @@ -1051,7 +1052,7 @@ static void igdng_crtc_dpms(struct drm_crtc *crtc, int mode)
int trans_vblank_reg = (pipe == 0) ? TRANS_VBLANK_A : TRANS_VBLANK_B;
int trans_vsync_reg = (pipe == 0) ? TRANS_VSYNC_A : TRANS_VSYNC_B;
u32 temp;
int tries = 5, j;
int tries = 5, j, n;

/* XXX: When our outputs are all unaware of DPMS modes other than off
* and on, we should map those modes to DRM_MODE_DPMS_OFF in the CRTC.
Expand Down Expand Up @@ -1239,19 +1240,21 @@ static void igdng_crtc_dpms(struct drm_crtc *crtc, int mode)
if ((temp & PIPEACONF_ENABLE) != 0) {
I915_WRITE(pipeconf_reg, temp & ~PIPEACONF_ENABLE);
I915_READ(pipeconf_reg);
n = 0;
/* wait for cpu pipe off, pipe state */
while ((I915_READ(pipeconf_reg) & I965_PIPECONF_ACTIVE) != 0)
;
while ((I915_READ(pipeconf_reg) & I965_PIPECONF_ACTIVE) != 0) {
n++;
if (n < 60) {
udelay(500);
continue;
} else {
DRM_DEBUG("pipe %d off delay\n", pipe);
break;
}
}
} else
DRM_DEBUG("crtc %d is disabled\n", pipe);

/* IGDNG-A : disable cpu panel fitter ? */
temp = I915_READ(pf_ctl_reg);
if ((temp & PF_ENABLE) != 0) {
I915_WRITE(pf_ctl_reg, temp & ~PF_ENABLE);
I915_READ(pf_ctl_reg);
}

/* disable CPU FDI tx and PCH FDI rx */
temp = I915_READ(fdi_tx_reg);
I915_WRITE(fdi_tx_reg, temp & ~FDI_TX_ENABLE);
Expand All @@ -1261,6 +1264,8 @@ static void igdng_crtc_dpms(struct drm_crtc *crtc, int mode)
I915_WRITE(fdi_rx_reg, temp & ~FDI_RX_ENABLE);
I915_READ(fdi_rx_reg);

udelay(100);

/* still set train pattern 1 */
temp = I915_READ(fdi_tx_reg);
temp &= ~FDI_LINK_TRAIN_NONE;
Expand All @@ -1272,14 +1277,25 @@ static void igdng_crtc_dpms(struct drm_crtc *crtc, int mode)
temp |= FDI_LINK_TRAIN_PATTERN_1;
I915_WRITE(fdi_rx_reg, temp);

udelay(100);

/* disable PCH transcoder */
temp = I915_READ(transconf_reg);
if ((temp & TRANS_ENABLE) != 0) {
I915_WRITE(transconf_reg, temp & ~TRANS_ENABLE);
I915_READ(transconf_reg);
n = 0;
/* wait for PCH transcoder off, transcoder state */
while ((I915_READ(transconf_reg) & TRANS_STATE_ENABLE) != 0)
;
while ((I915_READ(transconf_reg) & TRANS_STATE_ENABLE) != 0) {
n++;
if (n < 60) {
udelay(500);
continue;
} else {
DRM_DEBUG("transcoder %d off delay\n", pipe);
break;
}
}
}

/* disable PCH DPLL */
Expand All @@ -1297,6 +1313,22 @@ static void igdng_crtc_dpms(struct drm_crtc *crtc, int mode)
I915_READ(fdi_rx_reg);
}

/* Disable CPU FDI TX PLL */
temp = I915_READ(fdi_tx_reg);
if ((temp & FDI_TX_PLL_ENABLE) != 0) {
I915_WRITE(fdi_tx_reg, temp & ~FDI_TX_PLL_ENABLE);
I915_READ(fdi_tx_reg);
udelay(100);
}

/* Disable PF */
temp = I915_READ(pf_ctl_reg);
if ((temp & PF_ENABLE) != 0) {
I915_WRITE(pf_ctl_reg, temp & ~PF_ENABLE);
I915_READ(pf_ctl_reg);
}
I915_WRITE(pf_win_size, 0);

/* Wait for the clocks to turn off. */
udelay(150);
break;
Expand Down

0 comments on commit 249c0e6

Please sign in to comment.