xf86-video-intel: src/i830_driver.c

Jesse Barnes jbarnes at kemper.freedesktop.org
Tue Dec 18 18:10:37 PST 2007


 src/i830_driver.c |   97 ++++++++++++++++++++++++++++++++++++++----------------
 1 file changed, 69 insertions(+), 28 deletions(-)

New commits:
commit f69b48fe24ef94dac44b8123884ca71df675be4b
Author: Jesse Barnes <jbarnes at hobbes.virtuousgeek.org>
Date:   Tue Dec 18 18:10:33 2007 -0800

    Unconditionally restore pipe configuration
    
    This is a partial fix for #13196, which covers both leaving pipes disabled at
    server exit time and problems with restoring the pipe configuration on certain
    chipsets.  It restores the pipe configuration unconditionally (previously we
    made sure the PLL was running and we weren't in VGA mode) but also adds some
    additional PLL settle time to the PLL register write paths.

diff --git a/src/i830_driver.c b/src/i830_driver.c
index 7818ee4..ca4544d 100644
--- a/src/i830_driver.c
+++ b/src/i830_driver.c
@@ -1991,6 +1991,13 @@ SaveHWState(ScrnInfoPtr pScrn)
    return TRUE;
 }
 
+/* Wait for the PLL to settle down after programming */
+static void
+i830_dpll_settle(void)
+{
+    usleep(10000); /* 10 ms *should* be plenty */
+}
+
 static Bool
 RestoreHWState(ScrnInfoPtr pScrn)
 {
@@ -2025,6 +2032,23 @@ RestoreHWState(ScrnInfoPtr pScrn)
    if (!IS_I830(pI830) && !IS_845G(pI830))
      OUTREG(PFIT_CONTROL, pI830->savePFIT_CONTROL);
 
+   /*
+    * Pipe regs
+    * To restore the saved state, we first need to program the PLL regs,
+    * followed by the pipe configuration and finally the display plane
+    * configuration.  The VGA registers can program one, both or neither
+    * of the PLL regs, depending on their VGA_MOD_DIS bit value.
+    */
+
+   /*
+    * Since either or both pipes may use the VGA clocks, make sure the
+    * regs are valid.
+    */
+   OUTREG(VCLK_DIVISOR_VGA0, pI830->saveVCLK_DIVISOR_VGA0);
+   OUTREG(VCLK_DIVISOR_VGA1, pI830->saveVCLK_DIVISOR_VGA1);
+   OUTREG(VCLK_POST_DIV, pI830->saveVCLK_POST_DIV);
+
+   /* If the pipe A PLL is active, we can restore the pipe & plane config */
    if (pI830->saveDPLL_A & DPLL_VCO_ENABLE)
    {
       OUTREG(DPLL_A, pI830->saveDPLL_A & ~DPLL_VCO_ENABLE);
@@ -2033,13 +2057,14 @@ RestoreHWState(ScrnInfoPtr pScrn)
    OUTREG(FPA0, pI830->saveFPA0);
    OUTREG(FPA1, pI830->saveFPA1);
    OUTREG(DPLL_A, pI830->saveDPLL_A);
-   usleep(150);
+   i830_dpll_settle();
    if (IS_I965G(pI830))
       OUTREG(DPLL_A_MD, pI830->saveDPLL_A_MD);
    else
       OUTREG(DPLL_A, pI830->saveDPLL_A);
-   usleep(150);
+   i830_dpll_settle();
 
+   /* Restore mode config */
    OUTREG(HTOTAL_A, pI830->saveHTOTAL_A);
    OUTREG(HBLANK_A, pI830->saveHBLANK_A);
    OUTREG(HSYNC_A, pI830->saveHSYNC_A);
@@ -2058,20 +2083,31 @@ RestoreHWState(ScrnInfoPtr pScrn)
       OUTREG(DSPASURF, pI830->saveDSPASURF);
       OUTREG(DSPATILEOFF, pI830->saveDSPATILEOFF);
    }
+
+   OUTREG(PIPEACONF, pI830->savePIPEACONF);
+   i830WaitForVblank(pScrn);
+
    /*
-    * Make sure the DPLL is active and not in VGA mode or the
-    * write of PIPEnCONF may cause a crash
+    * Program Pipe A's plane
+    * The corresponding display plane may be disabled, and should only be
+    * enabled if pipe A is actually on (otherwise we have a bug in the initial
+    * state).
     */
-   if ((pI830->saveDPLL_A & DPLL_VCO_ENABLE) &&
-       (pI830->saveDPLL_A & DPLL_VGA_MODE_DIS))
-	   OUTREG(PIPEACONF, pI830->savePIPEACONF);
-   i830WaitForVblank(pScrn);
-   OUTREG(DSPACNTR, pI830->saveDSPACNTR);
-   OUTREG(DSPABASE, INREG(DSPABASE));
-   i830WaitForVblank(pScrn);
-   
+   if (pI830->saveDSPACNTR & DISPPLANE_SEL_PIPE_A) {
+       OUTREG(DSPACNTR, pI830->saveDSPACNTR);
+       OUTREG(DSPABASE, INREG(DSPABASE));
+       i830WaitForVblank(pScrn);
+   }
+   if (pI830->saveDSPBCNTR & DISPPLANE_SEL_PIPE_A) {
+       OUTREG(DSPBCNTR, pI830->saveDSPBCNTR);
+       OUTREG(DSPBBASE, INREG(DSPBBASE));
+       i830WaitForVblank(pScrn);
+   }
+
+   /* See note about pipe programming above */
    if(xf86_config->num_crtc == 2) 
    {
+      /* If the pipe B PLL is active, we can restore the pipe & plane config */
       if (pI830->saveDPLL_B & DPLL_VCO_ENABLE)
       {
 	 OUTREG(DPLL_B, pI830->saveDPLL_B & ~DPLL_VCO_ENABLE);
@@ -2080,13 +2116,14 @@ RestoreHWState(ScrnInfoPtr pScrn)
       OUTREG(FPB0, pI830->saveFPB0);
       OUTREG(FPB1, pI830->saveFPB1);
       OUTREG(DPLL_B, pI830->saveDPLL_B);
-      usleep(150);
+      i830_dpll_settle();
       if (IS_I965G(pI830))
 	 OUTREG(DPLL_B_MD, pI830->saveDPLL_B_MD);
       else
 	 OUTREG(DPLL_B, pI830->saveDPLL_B);
-      usleep(150);
+      i830_dpll_settle();
    
+      /* Restore mode config */
       OUTREG(HTOTAL_B, pI830->saveHTOTAL_B);
       OUTREG(HBLANK_B, pI830->saveHBLANK_B);
       OUTREG(HSYNC_B, pI830->saveHSYNC_B);
@@ -2105,18 +2142,28 @@ RestoreHWState(ScrnInfoPtr pScrn)
 	 OUTREG(DSPBTILEOFF, pI830->saveDSPBTILEOFF);
       }
 
+      OUTREG(PIPEBCONF, pI830->savePIPEBCONF);
+      i830WaitForVblank(pScrn);
+
       /*
-       * See PIPEnCONF note above
+       * Program Pipe B's plane
+       * Note that pipe B may be disabled, and in that case, the plane
+       * should also be disabled or we must have had a bad initial state.
        */
-      if ((pI830->saveDPLL_B & DPLL_VCO_ENABLE) &&
-	  (pI830->saveDPLL_B & DPLL_VGA_MODE_DIS))
-	      OUTREG(PIPEBCONF, pI830->savePIPEBCONF);
-      i830WaitForVblank(pScrn);
-      OUTREG(DSPBCNTR, pI830->saveDSPBCNTR);
-      OUTREG(DSPBBASE, INREG(DSPBBASE));
-      i830WaitForVblank(pScrn);
+      if (pI830->saveDSPACNTR & DISPPLANE_SEL_PIPE_B) {
+	  OUTREG(DSPACNTR, pI830->saveDSPACNTR);
+	  OUTREG(DSPABASE, INREG(DSPABASE));
+	  i830WaitForVblank(pScrn);
+      }
+      if (pI830->saveDSPBCNTR & DISPPLANE_SEL_PIPE_B) {
+	  OUTREG(DSPBCNTR, pI830->saveDSPBCNTR);
+	  OUTREG(DSPBBASE, INREG(DSPBBASE));
+	  i830WaitForVblank(pScrn);
+      }
    }
 
+   OUTREG(VGACNTRL, pI830->saveVGACNTRL);
+
    /* Restore outputs */
    for (i = 0; i < xf86_config->num_output; i++) {
       xf86OutputPtr   output = xf86_config->output[i];
@@ -2124,12 +2171,6 @@ RestoreHWState(ScrnInfoPtr pScrn)
 	 output->funcs->restore(output);
    }
     
-   OUTREG(VGACNTRL, pI830->saveVGACNTRL);
-
-   OUTREG(VCLK_DIVISOR_VGA0, pI830->saveVCLK_DIVISOR_VGA0);
-   OUTREG(VCLK_DIVISOR_VGA1, pI830->saveVCLK_DIVISOR_VGA1);
-   OUTREG(VCLK_POST_DIV, pI830->saveVCLK_POST_DIV);
-
    i830_restore_palette(pI830, PIPE_A);
    i830_restore_palette(pI830, PIPE_B);
 


More information about the xorg-commit mailing list