The following changes mostly based on what has happened in
the upstream drm code seems to resolve problems with screen corruption
on power saving/dpms on ivy bridge with ums here. Testing on ironlake/
sandy bridge/ivy bridge (aka Core i*) to make sure this doesn't break
anything appreciated.
- remove a workaround which was in itself causing issues
- switch the order of disabling fdi rx & tx
- disable DPLL_SEL when disabling the crtc
- add a few extra delays
Index: i830_display.c
===================================================================
RCS file: /cvs/xenocara/driver/xf86-video-intel/src/i830_display.c,v
retrieving revision 1.16
diff -u -p -r1.16 i830_display.c
--- i830_display.c 15 Jan 2013 06:31:43 -0000 1.16
+++ i830_display.c 29 Jan 2013 02:24:21 -0000
@@ -1535,16 +1535,6 @@ static void ivb_manual_fdi_link_train(xf
INREG(fdi_rx_reg);
usleep(150);
-
- if (HAS_PCH_CPT(intel)) {
- temp = INREG(SOUTH_CHICKEN1);
- temp |= FDI_PHASE_SYNC_OVR(pipe);
- OUTREG(SOUTH_CHICKEN1, temp); /* once to unlock... */
- temp |= FDI_PHASE_SYNC_EN(pipe);
- OUTREG(SOUTH_CHICKEN1, temp); /* then again to enable */
- INREG(SOUTH_CHICKEN1);
- usleep(150);
- }
for (i = 0; i < 4; i++) {
temp = INREG(fdi_tx_reg);
@@ -1862,11 +1852,6 @@ ironlake_crtc_disable(xf86CrtcPtr crtc)
OUTREG(pf_win_size, 0);
INREG(pf_win_size);
- ErrorF("FDI TX disable\n");
- temp = INREG(fdi_tx_reg);
- OUTREG(fdi_tx_reg, temp & ~FDI_TX_ENABLE);
- INREG(fdi_tx_reg);
-
ErrorF("FDI RX disable\n");
temp = INREG(fdi_rx_reg);
temp &= ~(0x07 << 16);
@@ -1876,14 +1861,13 @@ ironlake_crtc_disable(xf86CrtcPtr crtc)
usleep(100);
- ErrorF("FDI TX train 1 preload\n");
- /* still set train pattern 1 */
+ ErrorF("FDI TX disable\n");
temp = INREG(fdi_tx_reg);
- temp &= ~FDI_LINK_TRAIN_NONE;
- temp |= FDI_LINK_TRAIN_PATTERN_1;
- OUTREG(fdi_tx_reg, temp);
+ OUTREG(fdi_tx_reg, temp & ~FDI_TX_ENABLE);
INREG(fdi_tx_reg);
+ usleep(100);
+
ErrorF("FDI RX train 1 preload\n");
temp = INREG(fdi_rx_reg);
if (HAS_PCH_CPT(intel)) {
@@ -1898,6 +1882,16 @@ ironlake_crtc_disable(xf86CrtcPtr crtc)
usleep(100);
+ ErrorF("FDI TX train 1 preload\n");
+ /* still set train pattern 1 */
+ temp = INREG(fdi_tx_reg);
+ temp &= ~FDI_LINK_TRAIN_NONE;
+ temp |= FDI_LINK_TRAIN_PATTERN_1;
+ OUTREG(fdi_tx_reg, temp);
+ INREG(fdi_tx_reg);
+
+ usleep(100);
+
if (i830PipeHasType(crtc, I830_OUTPUT_LVDS)) {
ErrorF("LVDS port force off\n");
while ((temp = INREG(PCH_LVDS)) & PORT_ENABLE) {
@@ -1933,6 +1927,25 @@ ironlake_crtc_disable(xf86CrtcPtr crtc)
OUTREG(transconf_reg, temp);
INREG(transconf_reg);
usleep(100);
+
+ if (HAS_PCH_CPT(intel)) {
+ /* disable DPLL_SEL */
+ temp = INREG(PCH_DPLL_SEL);
+ switch (pipe) {
+ case 0:
+ temp &= ~(TRANSA_DPLL_ENABLE | TRANSA_DPLLB_SEL);
+ break;
+ case 1:
+ temp &= ~(TRANSB_DPLL_ENABLE | TRANSB_DPLLB_SEL);
+ break;
+ case 2:
+ /* C shares PLL A or B */
+ temp &= ~(TRANSC_DPLL_ENABLE | TRANSC_DPLLB_SEL);
+ break;
+ }
+ OUTREG(PCH_DPLL_SEL, temp);
+ INREG(PCH_DPLL_SEL);
+ }
ErrorF("PCH DPLL disable\n");
/* disable PCH DPLL */