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 */

Reply via email to