xf86-video-intel: Branch 'modesetting' - 4 commits - src/i830_display.c src/i830_driver.c src/i830_sdvo.c src/i830_xf86Crtc.c

Keith Packard keithp at kemper.freedesktop.org
Sun Dec 17 07:12:54 EET 2006


 src/i830_display.c  |   26 +++++------------
 src/i830_driver.c   |   78 ++++++++++++++++++++++++++++------------------------
 src/i830_sdvo.c     |   55 ++++++++++++++++++++++++------------
 src/i830_xf86Crtc.c |    2 -
 4 files changed, 88 insertions(+), 73 deletions(-)

New commits:
diff-tree 6823ca87f3b1ef3b28ed167254dcfce2a80467df (from 86558cc622b516b568cc26efdf9b64d4b660f50f)
Author: Keith Packard <keithp at mandolin.keithp.com>
Date:   Sat Dec 16 21:12:47 2006 -0800

    Follow mode setting order in RestoreHWState.
    
    Add delays after output and CRTC disable. Restore panel fit register before
    PLLs are restarted. Move all VGA restore code last. Shuffle various register
    writes around and add delays to match PipeSetMode code.

diff --git a/src/i830_driver.c b/src/i830_driver.c
index 998b36f..7da4bf5 100644
--- a/src/i830_driver.c
+++ b/src/i830_driver.c
@@ -2210,18 +2210,22 @@ RestoreHWState(ScrnInfoPtr pScrn)
 #ifdef XF86DRI
    I830DRISetVBlankInterrupt (pScrn, FALSE);
 #endif
-
    /* Disable outputs */
    for (i = 0; i < xf86_config->num_output; i++) {
       xf86OutputPtr   output = xf86_config->output[i];
       output->funcs->dpms(output, DPMSModeOff);
    }
-
+   i830WaitForVblank(pScrn);
+   
    /* Disable pipes */
    for (i = 0; i < xf86_config->num_crtc; i++) {
       xf86CrtcPtr crtc = xf86_config->crtc[i];
       crtc->funcs->dpms(crtc, DPMSModeOff);
    }
+   i830WaitForVblank(pScrn);
+
+   if (!IS_I830(pI830) && !IS_845G(pI830))
+     OUTREG(PFIT_CONTROL, pI830->savePFIT_CONTROL);
 
    if (pI830->saveDPLL_A & DPLL_VCO_ENABLE)
    {
@@ -2248,32 +2252,31 @@ RestoreHWState(ScrnInfoPtr pScrn)
    OUTREG(DSPASTRIDE, pI830->saveDSPASTRIDE);
    OUTREG(DSPASIZE, pI830->saveDSPASIZE);
    OUTREG(DSPAPOS, pI830->saveDSPAPOS);
-   OUTREG(DSPACNTR, pI830->saveDSPACNTR);
+   OUTREG(PIPEASRC, pI830->savePIPEASRC);
    OUTREG(DSPABASE, pI830->saveDSPABASE);
-   if (IS_I965G(pI830)) {
+   if (IS_I965G(pI830))
       OUTREG(DSPASURF, pI830->saveDSPASURF);
-   }
-   
-   OUTREG(PIPEASRC, pI830->savePIPEASRC);
    OUTREG(PIPEACONF, pI830->savePIPEACONF);
+   i830WaitForVblank(pScrn);
+   OUTREG(DSPACNTR, pI830->saveDSPACNTR);
+   OUTREG(DSPABASE, INREG(DSPABASE));
+   i830WaitForVblank(pScrn);
    
-   for(i = 0; i < 256; i++) {
-         OUTREG(PALETTE_A + (i << 2), pI830->savePaletteA[i]);
-   }
-
-   if(xf86_config->num_crtc == 2) {
-      OUTREG(FPB0, pI830->saveFPB0);
-      OUTREG(FPB1, pI830->saveFPB1);
-      if (IS_I965G(pI830))
-	 OUTREG(DPLL_B_MD, pI830->saveDPLL_B_MD);
+   if(xf86_config->num_crtc == 2) 
+   {
       if (pI830->saveDPLL_B & DPLL_VCO_ENABLE)
       {
 	 OUTREG(DPLL_B, pI830->saveDPLL_B & ~DPLL_VCO_ENABLE);
 	 usleep(150);
       }
+      OUTREG(FPB0, pI830->saveFPB0);
+      OUTREG(FPB1, pI830->saveFPB1);
       OUTREG(DPLL_B, pI830->saveDPLL_B);
       usleep(150);
-      OUTREG(DPLL_B, pI830->saveDPLL_B);
+      if (IS_I965G(pI830))
+	 OUTREG(DPLL_B_MD, pI830->saveDPLL_B_MD);
+      else
+	 OUTREG(DPLL_B, pI830->saveDPLL_B);
       usleep(150);
    
       OUTREG(HTOTAL_B, pI830->saveHTOTAL_B);
@@ -2286,43 +2289,48 @@ RestoreHWState(ScrnInfoPtr pScrn)
       OUTREG(DSPBSIZE, pI830->saveDSPBSIZE);
       OUTREG(DSPBPOS, pI830->saveDSPBPOS);
       OUTREG(PIPEBSRC, pI830->savePIPEBSRC);
-      OUTREG(PIPEBCONF, pI830->savePIPEBCONF);
-      OUTREG(DSPBCNTR, pI830->saveDSPBCNTR);
       OUTREG(DSPBBASE, pI830->saveDSPBBASE);
-      if (IS_I965G(pI830)) {
+      if (IS_I965G(pI830))
 	 OUTREG(DSPBSURF, pI830->saveDSPBSURF);
-      }
-      for(i= 0; i < 256; i++) {
-         OUTREG(PALETTE_B + (i << 2), pI830->savePaletteB[i]);
-      }
+      OUTREG(PIPEBCONF, pI830->savePIPEBCONF);
+      i830WaitForVblank(pScrn);
+      OUTREG(DSPBCNTR, pI830->saveDSPBCNTR);
+      OUTREG(DSPBBASE, INREG(DSPBBASE));
+      i830WaitForVblank(pScrn);
    }
 
-   if (!IS_I830(pI830) && !IS_845G(pI830))
-     OUTREG(PFIT_CONTROL, pI830->savePFIT_CONTROL);
-
+   /* Restore outputs */
+   for (i = 0; i < xf86_config->num_output; i++) {
+      xf86OutputPtr   output = xf86_config->output[i];
+      if (output->funcs->restore)
+	 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);
 
-   for (i = 0; i < xf86_config->num_output; i++) {
-      xf86OutputPtr   output = xf86_config->output[i];
-      (*output->funcs->restore) (output);
+   for(i = 0; i < 256; i++) {
+      OUTREG(PALETTE_A + (i << 2), pI830->savePaletteA[i]);
+   }
+   
+   if(xf86_config->num_crtc == 2) {
+      for(i= 0; i < 256; i++) {
+         OUTREG(PALETTE_B + (i << 2), pI830->savePaletteB[i]);
+      }
    }
 
    for(i = 0; i < 7; i++) {
-	   OUTREG(SWF0 + (i << 2), pI830->saveSWF[i]);
-	   OUTREG(SWF00 + (i << 2), pI830->saveSWF[i+7]);
+      OUTREG(SWF0 + (i << 2), pI830->saveSWF[i]);
+      OUTREG(SWF00 + (i << 2), pI830->saveSWF[i+7]);
    }
 
    OUTREG(SWF30, pI830->saveSWF[14]);
    OUTREG(SWF31, pI830->saveSWF[15]);
    OUTREG(SWF32, pI830->saveSWF[16]);
 
-   for (i = 0; i < 2; i++)
-      i830WaitForVblank(pScrn);
-
    vgaHWRestore(pScrn, vgaReg, VGA_SR_FONTS);
    vgaHWLock(hwp);
 
diff-tree 86558cc622b516b568cc26efdf9b64d4b660f50f (from 8e6ab99b3195325f9fe5432725fe328591c0c7e2)
Author: Keith Packard <keithp at mandolin.keithp.com>
Date:   Sat Dec 16 21:09:31 2006 -0800

    Prefer earliest CRTC when mapping to outputs.
    
    For some reason, the code was preferring the last possible output when
    mapping outputs to crtcs. Use the earlier CRTC instead to make the i830
    driver consistent with BIOS usage.

diff --git a/src/i830_xf86Crtc.c b/src/i830_xf86Crtc.c
index 76d6d03..51e6f1c 100644
--- a/src/i830_xf86Crtc.c
+++ b/src/i830_xf86Crtc.c
@@ -359,7 +359,7 @@ xf86PickCrtcs (ScrnInfoPtr	pScrn,
 	crtcs[n] = crtc;
 	memcpy (crtcs, best_crtcs, n * sizeof (xf86CrtcPtr));
 	score = my_score + xf86PickCrtcs (pScrn, crtcs, modes, n+1, width, height);
-	if (score >= best_score)
+	if (score > best_score)
 	{
 	    best_crtc = crtc;
 	    best_score = score;
diff-tree 8e6ab99b3195325f9fe5432725fe328591c0c7e2 (from bffd611b0a1cb05868e0f93e6ff9357a3116eaa6)
Author: Keith Packard <keithp at mandolin.keithp.com>
Date:   Sat Dec 16 21:06:36 2006 -0800

    Not restoring active outputs. Wait for input sync before enabling outputs.
    
    Oops--looks like a typo to me; the code was callint set_target_output
    instead of set_active_outputs.
    
    BIOS loops waiting for the SDVO input to sync before enabling outputs, this
    makes sense to me.

diff --git a/src/i830_sdvo.c b/src/i830_sdvo.c
index d19b8b0..cb68802 100644
--- a/src/i830_sdvo.c
+++ b/src/i830_sdvo.c
@@ -693,18 +693,16 @@ i830_sdvo_dpms(xf86OutputPtr output, int
 
 	temp = INREG(dev_priv->output_device);
 	if ((temp & SDVO_ENABLE) == 0)
+	{
 	    OUTREG(dev_priv->output_device, temp | SDVO_ENABLE);
-
-	i830_sdvo_set_active_outputs(output, dev_priv->active_outputs);
-
 #if 0
-	/* Do it again!  If we remove this below register write, or the exact
-	 * same one 2 lines up, the mac mini SDVO output doesn't turn on.
-	 */
-	OUTREG(dev_priv->output_device,
-	       INREG(dev_priv->output_device) | SDVO_ENABLE);
+	    /* Do it again!  If we remove this below register write, or the exact
+	     * same one 2 lines up, the mac mini SDVO output doesn't turn on.
+	     */
+	    OUTREG(dev_priv->output_device,
+		   INREG(dev_priv->output_device) | SDVO_ENABLE);
 #endif
-
+	}
 	for (i = 0; i < 2; i++)
 	    i830WaitForVblank(pScrn);
 
@@ -716,6 +714,8 @@ i830_sdvo_dpms(xf86OutputPtr output, int
 		       "First %s output reported failure to sync\n",
 		       SDVO_NAME(dev_priv));
 	}
+
+	i830_sdvo_set_active_outputs(output, dev_priv->active_outputs);
     }
 }
 
@@ -764,16 +764,11 @@ i830_sdvo_restore(xf86OutputPtr output)
     struct i830_sdvo_priv   *dev_priv = intel_output->dev_priv;
     I830Ptr		    pI830 = I830PTR(pScrn);
     int			    o;
+    int			    i;
+    Bool		    input1, input2;
+    CARD8		    status;
 
-    if (dev_priv->caps.sdvo_inputs_mask & 0x1) {
-       i830_sdvo_set_target_input(output, TRUE, FALSE);
-       i830_sdvo_set_input_timing(output, &dev_priv->save_input_dtd_1);
-    }
-
-    if (dev_priv->caps.sdvo_inputs_mask & 0x2) {
-       i830_sdvo_set_target_input(output, FALSE, TRUE);
-       i830_sdvo_set_input_timing(output, &dev_priv->save_input_dtd_2);
-    }
+    i830_sdvo_set_active_outputs(output, 0);
 
     for (o = SDVO_OUTPUT_FIRST; o <= SDVO_OUTPUT_LAST; o++)
     {
@@ -784,11 +779,33 @@ i830_sdvo_restore(xf86OutputPtr output)
 	    i830_sdvo_set_output_timing(output, &dev_priv->save_output_dtd[o]);
 	}
     }
-    i830_sdvo_set_target_output(output, dev_priv->save_active_outputs);
+
+    if (dev_priv->caps.sdvo_inputs_mask & 0x1) {
+       i830_sdvo_set_target_input(output, TRUE, FALSE);
+       i830_sdvo_set_input_timing(output, &dev_priv->save_input_dtd_1);
+    }
+
+    if (dev_priv->caps.sdvo_inputs_mask & 0x2) {
+       i830_sdvo_set_target_input(output, FALSE, TRUE);
+       i830_sdvo_set_input_timing(output, &dev_priv->save_input_dtd_2);
+    }
 
     i830_sdvo_set_clock_rate_mult(output, dev_priv->save_sdvo_mult);
 
     OUTREG(dev_priv->output_device, dev_priv->save_SDVOX);
+
+    if (dev_priv->save_SDVOX & SDVO_ENABLE)
+    {
+	for (i = 0; i < 2; i++)
+	    i830WaitForVblank(pScrn);
+	status = i830_sdvo_get_trained_inputs(output, &input1, &input2);
+	if (status == SDVO_CMD_STATUS_SUCCESS && !input1)
+	    xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+		       "First %s output reported failure to sync\n",
+		       SDVO_NAME(dev_priv));
+    }
+    
+    i830_sdvo_set_active_outputs(output, dev_priv->save_active_outputs);
 }
 
 static int
diff-tree bffd611b0a1cb05868e0f93e6ff9357a3116eaa6 (from 9b1a1b170befae2e705c23ce295837d0d13b60c0)
Author: Keith Packard <keithp at mandolin.keithp.com>
Date:   Sat Dec 16 21:03:15 2006 -0800

    Follow BIOS order in writing DPLL/DPLL_MD registers.
    
    965 BIOS writes DPLL and then DPLL_MD.
    945 BIOS writes DPLL twice.

diff --git a/src/i830_display.c b/src/i830_display.c
index 6971e28..f87aadc 100644
--- a/src/i830_display.c
+++ b/src/i830_display.c
@@ -787,12 +787,6 @@ i830_crtc_mode_set(xf86CrtcPtr crtc, Dis
     i830PrintPll("chosen", &clock);
     ErrorF("clock regs: 0x%08x, 0x%08x\n", (int)dpll, (int)fp);
 
-    if (IS_I965G(pI830)) {
-	int sdvo_pixel_multiply = adjusted_mode->Clock / mode->Clock;
-	OUTREG(dpll_md_reg, (0 << DPLL_MD_UDI_DIVIDER_SHIFT) |
-	       ((sdvo_pixel_multiply - 1) << DPLL_MD_UDI_MULTIPLIER_SHIFT));
-    }
-
     if (dpll & DPLL_VCO_ENABLE)
     {
 	OUTREG(fp_reg, fp);
@@ -804,21 +798,17 @@ i830_crtc_mode_set(xf86CrtcPtr crtc, Dis
     /* Wait for the clocks to stabilize. */
     usleep(150);
     
-    /* write it again -- the BIOS does, after all */
-    OUTREG(dpll_reg, dpll);
+    if (IS_I965G(pI830)) {
+	int sdvo_pixel_multiply = adjusted_mode->Clock / mode->Clock;
+	OUTREG(dpll_md_reg, (0 << DPLL_MD_UDI_DIVIDER_SHIFT) |
+	       ((sdvo_pixel_multiply - 1) << DPLL_MD_UDI_MULTIPLIER_SHIFT));
+    } else {
+       /* write it again -- the BIOS does, after all */
+       OUTREG(dpll_reg, dpll);
+    }
     /* Wait for the clocks to stabilize. */
     usleep(150);
 
-#if 0
-    /* Magic re-write of the register for the Mac Mini.  Without this, the
-     * first X invocation after a cold boot will stick in 4x pixel multiply
-     * mode.  Alternatives that don't work include sleeping and doing an
-     * INREG for presumable pci write posting magic before and after the dpll
-     * write above.
-     */
-    OUTREG(dpll_reg, dpll);
-#endif
-
     OUTREG(htot_reg, (adjusted_mode->CrtcHDisplay - 1) |
 	((adjusted_mode->CrtcHTotal - 1) << 16));
     OUTREG(hblank_reg, (adjusted_mode->CrtcHBlankStart - 1) |



More information about the xorg-commit mailing list