xf86-video-intel: Branch 'modesetting-keithp' - 4 commits - src/i810_reg.h src/i830_crt.c src/i830_display.c src/i830_driver.c src/i830_sdvo.c

Keith Packard keithp at kemper.freedesktop.org
Mon Nov 6 04:56:40 EET 2006


 src/i810_reg.h     |   17 +++++++--
 src/i830_crt.c     |    8 +++-
 src/i830_display.c |   96 ++++++++++++++++++++++++++++-------------------------
 src/i830_driver.c  |   14 ++++++-
 src/i830_sdvo.c    |    9 +++-
 5 files changed, 91 insertions(+), 53 deletions(-)

New commits:
diff-tree 997e8c9bb4235cab1fff4738387df9afcbea0a03 (from 5a355c72614ed77f2000e5ede45f3ff5990c79d9)
Author: Keith Packard <keithp at mandolin.keithp.com>
Date:   Sun Nov 5 18:56:33 2006 -0800

    Don't allocate stuff in the first 256K of video memory (GATT?)
    
    Letting the ring buffer or other objects be allocated within the lowest
    portion of memory appears to trash some memory mapping data; I'm assuming
    this is the GATT table on the 965. Just marking this out of bounds for
    allocation fixes this problem.

diff --git a/src/i830_driver.c b/src/i830_driver.c
index 8d9712a..b632073 100644
--- a/src/i830_driver.c
+++ b/src/i830_driver.c
@@ -776,6 +776,7 @@ I830PreInit(ScrnInfoPtr pScrn, int flags
    pointer pVBEModule = NULL;
    Bool enable;
    const char *chipname;
+   int mem_skip;
 
    if (pScrn->numEntities != 1)
       return FALSE;
@@ -1092,8 +1093,15 @@ I830PreInit(ScrnInfoPtr pScrn, int flags
    /*
     * Get the pre-allocated (stolen) memory size.
     */
-   pI830->StolenMemory.Size = I830DetectMemory(pScrn);
-   pI830->StolenMemory.Start = 0;
+    
+   mem_skip = 0;
+   
+   /* On 965, it looks like the GATT table is inside the aperture? */
+   if (IS_I965G(pI830))
+      mem_skip = pI830->FbMapSize >> 10;
+    
+   pI830->StolenMemory.Size = I830DetectMemory(pScrn) - mem_skip;
+   pI830->StolenMemory.Start = mem_skip;
    pI830->StolenMemory.End = pI830->StolenMemory.Size;
 
    /* Find the maximum amount of agpgart memory available. */
@@ -1341,7 +1349,7 @@ I830PreInit(ScrnInfoPtr pScrn, int flags
 	 break;
       case I830_OUTPUT_DVO:
       case I830_OUTPUT_SDVO:
-	 pI830->output[i].pipe = 0;
+	 pI830->output[i].pipe = 1;
 	 break;
       default:
 	 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Unhandled output type\n");
diff-tree 5a355c72614ed77f2000e5ede45f3ff5990c79d9 (from 68c3185046b27ab936ca6c92b924b443b3cd6fce)
Author: Keith Packard <keithp at mandolin.keithp.com>
Date:   Sun Nov 5 18:51:28 2006 -0800

    Fix CRT output on 965 chipset.
    
    A few more register settings are needed to get CRT output working on the
    965 chipset, in particular the the SDVO/UDI clock multiplier register
    needed to get set to the default value (3). No, I really don't know what
    this does, but it does get the CRT running at a wide range of sizes.

diff --git a/src/i810_reg.h b/src/i810_reg.h
index e126904..0ece7ee 100644
--- a/src/i810_reg.h
+++ b/src/i810_reg.h
@@ -800,11 +800,19 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN
 # define PLL_P1_DIVIDE_BY_TWO			(1 << 21) /* i830 */
 # define PLL_REF_INPUT_DREFCLK			(0 << 13)
 # define PLL_REF_INPUT_TVCLKINA			(1 << 13) /* i830 */
-# define PLL_REF_INPUT_TVCLKINBC		(2 << 13)
+# define PLL_REF_INPUT_TVCLKINBC		(2 << 13) /* SDVO TVCLKIN */
 # define PLLB_REF_INPUT_SPREADSPECTRUMIN	(3 << 13)
+# define PLL_LOAD_PULSE_PHASE_SHIFT		9
+/*
+ * Parallel to Serial Load Pulse phase selection.
+ * Selects the phase for the 10X DPLL clock for the PCIe
+ * digital display port. The range is 4 to 13; 10 or more
+ * is just a flip delay. The default is 6
+ */
+# define PLL_LOAD_PULSE_PHASE_MASK		(0xf << PLL_LOAD_PULSE_PHASE_SHIFT)
 # define DISPLAY_RATE_SELECT_FPA1		(1 << 8)
 /**
- * SDVO multiplier for 945G/GM.
+ * SDVO multiplier for 945G/GM. Not used on 965.
  *
  * \sa DPLL_MD_UDI_MULTIPLIER_MASK
  */
@@ -848,7 +856,10 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN
  */
 # define DPLL_MD_UDI_MULTIPLIER_MASK		0x00003f00
 # define DPLL_MD_UDI_MULTIPLIER_SHIFT		8
-/** SDVO/UDI pixel multiplier for VGA, same as DPLL_MD_UDI_MULTIPLIER_MASK. */
+/** SDVO/UDI pixel multiplier for VGA, same as DPLL_MD_UDI_MULTIPLIER_MASK. 
+ * This best be set to the default value (3) or the CRT won't work. No,
+ * I don't entirely understand what this does...
+ */
 # define DPLL_MD_VGA_UDI_MULTIPLIER_MASK	0x0000003f
 # define DPLL_MD_VGA_UDI_MULTIPLIER_SHIFT	0
 /** @} */
diff --git a/src/i830_crt.c b/src/i830_crt.c
index adc2d62..a7b0493 100644
--- a/src/i830_crt.c
+++ b/src/i830_crt.c
@@ -101,8 +101,14 @@ i830_crt_post_set_mode(ScrnInfoPtr pScrn
 		       DisplayModePtr pMode)
 {
     I830Ptr pI830 = I830PTR(pScrn);
+    int	    dpll_md_reg = (output->pipe == 0) ? DPLL_A_MD : DPLL_B_MD;
+    CARD32  adpa;
 
-    CARD32 adpa;
+    /*
+     * Not quite sure precisely what this does...
+     */
+    if (IS_I965G(pI830))
+	OUTREG(dpll_md_reg, 0x3 << DPLL_MD_VGA_UDI_MULTIPLIER_SHIFT);
 
     adpa = ADPA_DAC_ENABLE;
 
diff --git a/src/i830_display.c b/src/i830_display.c
index 795c6f9..077e318 100644
--- a/src/i830_display.c
+++ b/src/i830_display.c
@@ -570,6 +570,8 @@ i830PipeSetMode(ScrnInfoPtr pScrn, Displ
 	    dpll |= DPLLB_LVDS_P2_CLOCK_DIV_14;
 	    break;
 	}
+	if (IS_I965G(pI830))
+	    dpll |= (6 << PLL_LOAD_PULSE_PHASE_SHIFT);
     } else {
 	dpll |= (p1 - 2) << 16;
 	if (p2 == 4)
@@ -660,8 +662,14 @@ i830PipeSetMode(ScrnInfoPtr pScrn, Displ
     if (((INREG(PFIT_CONTROL) >> 29) & 0x3) == pipe)
 	OUTREG(PFIT_CONTROL, 0);
 	   
+    /* 
+     * Docs say to not mess with this register. I think we will
+     * need to eventually though
+     */
+#if 0     
     OUTREG(DSPARB, (47 << 0) | (95 << 7));
-    
+#endif
+
     OUTREG(htot_reg, htot);
     OUTREG(hblank_reg, hblank);
     OUTREG(hsync_reg, hsync);
diff-tree 68c3185046b27ab936ca6c92b924b443b3cd6fce (from 15ef08046bcc3e746453301379f7c5d1bf929ee1)
Author: Keith Packard <keithp at mandolin.keithp.com>
Date:   Sun Nov 5 13:30:32 2006 -0800

    Avoid crashing when disabling sdvo output. XXX

diff --git a/src/i830_sdvo.c b/src/i830_sdvo.c
index da61159..4d4817a 100644
--- a/src/i830_sdvo.c
+++ b/src/i830_sdvo.c
@@ -517,8 +517,8 @@ i830_sdvo_pre_set_mode(ScrnInfoPtr pScrn
 {
     I830Ptr pI830 = I830PTR(pScrn);
     struct i830_sdvo_priv *dev_priv = output->dev_priv;
-    CARD16 width = mode->CrtcHDisplay;
-    CARD16 height = mode->CrtcVDisplay;
+    CARD16 width;
+    CARD16 height;
     CARD16 h_blank_len, h_sync_len, v_blank_len, v_sync_len;
     CARD16 h_sync_offset, v_sync_offset;
     struct i830_sdvo_dtd output_dtd;
@@ -526,6 +526,11 @@ i830_sdvo_pre_set_mode(ScrnInfoPtr pScrn
 
     memset(&no_outputs, 0, sizeof(no_outputs));
 
+    if (!mode)
+	return;
+    width = mode->CrtcHDisplay;
+    height = mode->CrtcVDisplay;
+    
     /* do some mode translations */
     h_blank_len = mode->CrtcHBlankEnd - mode->CrtcHBlankStart;
     h_sync_len = mode->CrtcHSyncEnd - mode->CrtcHSyncStart;
diff-tree 15ef08046bcc3e746453301379f7c5d1bf929ee1 (from 7fcb555735a58e19ccc10875b211402983170a87)
Author: Keith Packard <keithp at mandolin.keithp.com>
Date:   Sun Nov 5 13:29:56 2006 -0800

    Move remaining pipe mode setting logic to i830PipeSetMode

diff --git a/src/i830_display.c b/src/i830_display.c
index 6c5645b..795c6f9 100644
--- a/src/i830_display.c
+++ b/src/i830_display.c
@@ -375,6 +375,22 @@ i830PipeFindClosestMode(ScrnInfoPtr pScr
 }
 
 /**
+ * Return whether any outputs are connected to the specified pipe
+ */
+
+static Bool
+i830PipeInUse (ScrnInfoPtr pScrn, int pipe)
+{
+    I830Ptr pI830 = I830PTR(pScrn);
+    int	i;
+    
+    for (i = 0; i < pI830->num_outputs; i++)
+	if (!pI830->output[i].disabled && pI830->output[i].pipe == pipe)
+	    return TRUE;
+    return FALSE;
+}
+
+/**
  * Sets the given video mode on the given pipe.  Assumes that plane A feeds
  * pipe A, and plane B feeds pipe B.  Should not affect the other planes/pipes.
  */
@@ -405,6 +421,10 @@ i830PipeSetMode(ScrnInfoPtr pScrn, Displ
     int dspstride_reg = (pipe == 0) ? DSPASTRIDE : DSPBSTRIDE;
     int dsppos_reg = (pipe == 0) ? DSPAPOS : DSPBPOS;
     int pipesrc_reg = (pipe == 0) ? PIPEASRC : PIPEBSRC;
+    Bool ret = FALSE;
+#ifdef XF86DRI
+    Bool didLock = FALSE;
+#endif
 
     if (I830ModesEqual(&pI830Pipe->curMode, pMode))
 	return TRUE;
@@ -412,10 +432,21 @@ i830PipeSetMode(ScrnInfoPtr pScrn, Displ
     xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Requested pix clock: %d\n",
 	       pMode->Clock);
 
+    pI830->pipes[pipe].planeEnabled = i830PipeInUse (pScrn, pipe);
+    
+    if (!pI830->pipes[pipe].planeEnabled)
+	return TRUE;
+
+#ifdef XF86DRI
+    didLock = I830DRILock(pScrn);
+#endif
+    
     for (i = 0; i < pI830->num_outputs; i++) {
 	if (pI830->output[i].pipe != pipe || pI830->output[i].disabled)
 	    continue;
 
+	pI830->output[i].pre_set_mode(pScrn, &pI830->output[i], pMode);
+	
 	switch (pI830->output[i].type) {
 	case I830_OUTPUT_LVDS:
 	    is_lvds = TRUE;
@@ -438,18 +469,18 @@ i830PipeSetMode(ScrnInfoPtr pScrn, Displ
     if (is_lvds && (is_sdvo || is_dvo || is_tv || is_crt)) {
 	xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
 		   "Can't enable LVDS and non-LVDS on the same pipe\n");
-	return FALSE;
+	goto done;
     }
     if (is_tv && (is_sdvo || is_dvo || is_crt || is_lvds)) {
 	xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
 		   "Can't enable a TV and any other output on the same "
 		   "pipe\n");
-	return FALSE;
+	goto done;
     }
     if (pipe == 0 && is_lvds) {
 	xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
 		   "Can't support LVDS on pipe A\n");
-	return FALSE;
+	goto done;
     }
 
     htot = (pMode->CrtcHDisplay - 1) | ((pMode->CrtcHTotal - 1) << 16);
@@ -515,7 +546,7 @@ i830PipeSetMode(ScrnInfoPtr pScrn, Displ
     if (!ok) {
 	xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
 		   "Couldn't find PLL settings for mode!\n");
-	return FALSE;
+	goto done;
     }
 
     dpll = DPLL_VCO_ENABLE | DPLL_VGA_MODE_DIS;
@@ -629,7 +660,6 @@ i830PipeSetMode(ScrnInfoPtr pScrn, Displ
     if (((INREG(PFIT_CONTROL) >> 29) & 0x3) == pipe)
 	OUTREG(PFIT_CONTROL, 0);
 	   
-    OUTREG(PFIT_PGM_RATIOS, 0x10001000);
     OUTREG(DSPARB, (47 << 0) | (95 << 7));
     
     OUTREG(htot_reg, htot);
@@ -653,7 +683,13 @@ i830PipeSetMode(ScrnInfoPtr pScrn, Displ
 
     pI830Pipe->curMode = *pMode;
 
-    return TRUE;
+    ret = TRUE;
+done:
+#ifdef XF86DRI
+    if (didLock)
+	I830DRIUnlock(pScrn);
+#endif
+    return ret;
 }
 
 void
@@ -714,22 +750,6 @@ i830DisableUnusedFunctions(ScrnInfoPtr p
 }
 
 /**
- * Return whether any outputs are connected to the specified pipe
- */
-
-static Bool
-i830PipeInUse (ScrnInfoPtr pScrn, int pipe)
-{
-    I830Ptr pI830 = I830PTR(pScrn);
-    int	i;
-    
-    for (i = 0; i < pI830->num_outputs; i++)
-	if (!pI830->output[i].disabled && pI830->output[i].pipe == pipe)
-	    return TRUE;
-    return FALSE;
-}
-
-/**
  * This function configures the screens in clone mode on
  * all active outputs using a mode similar to the specified mode.
  */
@@ -738,28 +758,13 @@ i830SetMode(ScrnInfoPtr pScrn, DisplayMo
 {
     I830Ptr pI830 = I830PTR(pScrn);
     Bool ok = TRUE;
-#ifdef XF86DRI
-    Bool didLock = FALSE;
-#endif
     int i;
 
     DPRINTF(PFX, "i830SetMode\n");
 
-#ifdef XF86DRI
-    didLock = I830DRILock(pScrn);
-#endif
-
-    for (i = 0; i < pI830->num_pipes; i++)
-	pI830->pipes[i].planeEnabled = i830PipeInUse (pScrn, i);
-
-    for (i = 0; i < pI830->num_outputs; i++)
-	pI830->output[i].pre_set_mode(pScrn, &pI830->output[i], pMode);
-
     for (i = 0; i < pI830->num_pipes; i++)
     {
-	if (pI830->pipes[i].planeEnabled)
-	    ok = i830PipeSetMode(pScrn, i830PipeFindClosestMode(pScrn, i, pMode),
-				 i);
+	ok = i830PipeSetMode(pScrn, i830PipeFindClosestMode(pScrn, i, pMode), i);
 	if (!ok)
 	    goto done;
     }
@@ -797,11 +802,6 @@ i830SetMode(ScrnInfoPtr pScrn, DisplayMo
    I830DRISetVBlankInterrupt (pScrn, TRUE);
 #endif
 done:
-#ifdef XF86DRI
-    if (didLock)
-	I830DRIUnlock(pScrn);
-#endif
-
     i830DumpRegs (pScrn);
     i830_sdvo_dump(pScrn);
     return ok;



More information about the xorg-commit mailing list