xf86-video-intel: 5 commits - src/i810_reg.h src/i830_debug.c src/i830_driver.c src/i830_dvo.c src/i830_memory.c

Eric Anholt anholt at kemper.freedesktop.org
Thu May 3 00:54:10 EEST 2007


 src/i810_reg.h    |    1 
 src/i830_debug.c  |   33 +++++++++++-
 src/i830_driver.c |   19 ++++++-
 src/i830_dvo.c    |  140 ++++++++++++++++++++++++++++++++++++++++++++----------
 src/i830_memory.c |   10 +++
 5 files changed, 173 insertions(+), 30 deletions(-)

New commits:
diff-tree f850d4727a2ad55c2116d0788f6684b2a0192d24 (from f3168e3b0c5664a322ca6bb1c81fc94844cb30ab)
Author: Eric Anholt <eric at anholt.net>
Date:   Wed May 2 14:16:21 2007 -0700

    Make up a fixed panel timing for DVO LVDS, and use DVOA for DVO LVDS.
    
    The fixed panel timing will only be available when the LVDS is already on
    at X startup.
    
    So far, our only mostly-working LVDS driver is for the i830, and on i830 the
    LVDS is always on DVOA, so use that for all LVDS chips.  This may need to
    change if we support the ch7017 I've seen used on embedded i845, for example.

diff --git a/src/i830_dvo.c b/src/i830_dvo.c
index 96b29e7..129651c 100644
--- a/src/i830_dvo.c
+++ b/src/i830_dvo.c
@@ -89,13 +89,19 @@ i830_dvo_dpms(xf86OutputPtr output, int 
     I830Ptr		    pI830 = I830PTR(pScrn);
     I830OutputPrivatePtr    intel_output = output->driver_private;
     void *		    dev_priv = intel_output->i2c_drv->dev_priv;
+    unsigned int	    dvo_reg;
+
+    if (intel_output->i2c_drv->type & I830_DVO_CHIP_LVDS)
+	dvo_reg = DVOA;
+    else
+	dvo_reg = DVOC;
 
     if (mode == DPMSModeOn) {
-	OUTREG(DVOC, INREG(DVOC) | DVO_ENABLE);
+	OUTREG(dvo_reg, INREG(dvo_reg) | DVO_ENABLE);
 	(*intel_output->i2c_drv->vid_rec->dpms)(dev_priv, mode);
     } else {
 	(*intel_output->i2c_drv->vid_rec->dpms)(dev_priv, mode);
-	OUTREG(DVOC, INREG(DVOC) & ~DVO_ENABLE);
+	OUTREG(dvo_reg, INREG(dvo_reg) & ~DVO_ENABLE);
     }
 }
 
@@ -166,18 +172,27 @@ i830_dvo_mode_set(xf86OutputPtr output, 
     I830OutputPrivatePtr    intel_output = output->driver_private;
     int			    pipe = intel_crtc->pipe;
     CARD32		    dvo;
+    unsigned int	    dvo_reg, dvo_srcdim_reg;
     int			    dpll_reg = (pipe == 0) ? DPLL_A : DPLL_B;
 
+    if (intel_output->i2c_drv->type & I830_DVO_CHIP_LVDS) {
+	dvo_reg = DVOA;
+	dvo_srcdim_reg = DVOA_SRCDIM;
+    } else {
+	dvo_reg = DVOC;
+	dvo_srcdim_reg = DVOC_SRCDIM;
+    }
+
     intel_output->i2c_drv->vid_rec->mode_set(intel_output->i2c_drv->dev_priv,
 					     mode);
 
     /* Save the data order, since I don't know what it should be set to. */
-    dvo = INREG(DVOC) & (DVO_PRESERVE_MASK | DVO_DATA_ORDER_GBRG);
+    dvo = INREG(dvo_reg) & (DVO_PRESERVE_MASK | DVO_DATA_ORDER_GBRG);
     dvo |= DVO_DATA_ORDER_FP | DVO_BORDER_ENABLE | DVO_BLANK_ACTIVE_HIGH;
 
     if (pipe == 1)
 	dvo |= DVO_PIPE_B_SELECT;
-
+    dvo |= DVO_PIPE_STALL;
     if (adjusted_mode->Flags & V_PHSYNC)
 	dvo |= DVO_HSYNC_ACTIVE_HIGH;
     if (adjusted_mode->Flags & V_PVSYNC)
@@ -188,11 +203,11 @@ i830_dvo_mode_set(xf86OutputPtr output, 
     /*OUTREG(DVOB_SRCDIM,
       (adjusted_mode->HDisplay << DVO_SRCDIM_HORIZONTAL_SHIFT) |
       (adjusted_mode->VDisplay << DVO_SRCDIM_VERTICAL_SHIFT));*/
-    OUTREG(DVOC_SRCDIM,
+    OUTREG(dvo_srcdim_reg,
 	   (adjusted_mode->HDisplay << DVO_SRCDIM_HORIZONTAL_SHIFT) |
 	   (adjusted_mode->VDisplay << DVO_SRCDIM_VERTICAL_SHIFT));
     /*OUTREG(DVOB, dvo);*/
-    OUTREG(DVOC, dvo);
+    OUTREG(dvo_reg, dvo);
 }
 
 /**
@@ -209,6 +224,33 @@ i830_dvo_detect(xf86OutputPtr output)
     return intel_output->i2c_drv->vid_rec->detect(dev_priv);
 }
 
+static DisplayModePtr
+i830_dvo_get_modes(xf86OutputPtr output)
+{
+    ScrnInfoPtr		    pScrn = output->scrn;
+    I830Ptr		    pI830 = I830PTR(pScrn);
+    I830OutputPrivatePtr    intel_output = output->driver_private;
+    DisplayModePtr	    modes;
+
+    /* We should probably have an i2c driver get_modes function for those
+     * devices which will have a fixed set of modes determined by the chip
+     * (TV-out, for example), but for now with just TMDS and LVDS, that's not
+     * the case.
+     */
+    modes = i830_ddc_get_modes(output);
+    if (modes != NULL)
+	return modes;
+
+    if (intel_output->i2c_drv->type & I830_DVO_CHIP_LVDS &&
+	pI830->panel_fixed_mode != NULL)
+    {
+	xf86PrintModeline(pScrn->scrnIndex, pI830->panel_fixed_mode);
+	return xf86DuplicateMode(pI830->panel_fixed_mode);
+    }
+
+    return NULL;
+}
+
 static void
 i830_dvo_destroy (xf86OutputPtr output)
 {
@@ -235,10 +277,47 @@ static const xf86OutputFuncsRec i830_dvo
     .mode_set = i830_dvo_mode_set,
     .commit = i830_output_commit,
     .detect = i830_dvo_detect,
-    .get_modes = i830_ddc_get_modes,
+    .get_modes = i830_dvo_get_modes,
     .destroy = i830_dvo_destroy
 };
 
+/**
+ * Attempts to get a fixed panel timing for LVDS (currently only the i830).
+ *
+ * Other chips with DVO LVDS will need to extend this to deal with the LVDS
+ * chip being on DVOB/C and having multiple pipes.
+ */
+static void
+i830_dvo_get_panel_timings(xf86OutputPtr output)
+{
+    ScrnInfoPtr		    pScrn = output->scrn;
+    I830Ptr		    pI830 = I830PTR(pScrn);
+    CARD32 dvoa = INREG(DVOA);
+
+    if (!IS_I830(pI830))
+	return;
+
+    assert(pI830->fixed_panel_mode == NULL);
+
+    /* If the DVOA port is active, that'll be the LVDS, so we can pull out
+     * its timings to get how the BIOS set up the panel.
+     */
+    if (dvoa & DVO_ENABLE) {
+	xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
+	int pipe = (dvoa & DVO_PIPE_B_SELECT) ? 1 : 0;
+	xf86CrtcPtr crtc = xf86_config->crtc[pipe];
+
+	pI830->panel_fixed_mode = i830_crtc_mode_get(pScrn, crtc);
+	if (pI830->panel_fixed_mode != NULL)
+	    pI830->panel_fixed_mode->type |= M_T_PREFERRED;
+
+	if (dvoa & DVO_HSYNC_ACTIVE_HIGH)
+	    pI830->panel_fixed_mode->Flags |= V_PHSYNC;
+	if (dvoa & DVO_VSYNC_ACTIVE_HIGH)
+	    pI830->panel_fixed_mode->Flags |= V_PVSYNC;
+    }
+}
+
 void
 i830_dvo_init(ScrnInfoPtr pScrn)
 {
@@ -315,6 +394,9 @@ i830_dvo_init(ScrnInfoPtr pScrn)
 		return;
 	    }
 
+	    if (drv->type & I830_DVO_CHIP_LVDS)
+		i830_dvo_get_panel_timings(output);
+
 	    output->driver_private = intel_output;
 	    output->subpixel_order = SubPixelHorizontalRGB;
 	    output->interlaceAllowed = FALSE;
diff-tree f3168e3b0c5664a322ca6bb1c81fc94844cb30ab (from 1fc630f24f8ad9e304cb0761f9cacca2224203c4)
Author: Eric Anholt <eric at anholt.net>
Date:   Wed May 2 14:08:30 2007 -0700

    Disable non-working GTT decoding on i830, and fix map/unmap of GTT.

diff --git a/src/i830_driver.c b/src/i830_driver.c
index ad88f56..43f4e04 100644
--- a/src/i830_driver.c
+++ b/src/i830_driver.c
@@ -544,7 +544,10 @@ I830MapMMIO(ScrnInfoPtr pScrn)
 	    return FALSE;
       }
    } else {
-      pI830->GTTBase = pI830->MMIOBase + I830_PTE_BASE;
+      /* The GTT aperture on i830 is write-only.  We could probably map the
+       * actual physical pages that back it, but leave it alone for now.
+       */
+      pI830->GTTBase = NULL;
    }
 
    return TRUE;
@@ -584,6 +587,15 @@ I830UnmapMMIO(ScrnInfoPtr pScrn)
    xf86UnMapVidMem(pScrn->scrnIndex, (pointer) pI830->MMIOBase,
 		   I810_REG_SIZE);
    pI830->MMIOBase = NULL;
+
+   if (IS_I9XX(pI830)) {
+      if (IS_I965G(pI830))
+	 xf86UnMapVidMem(pScrn->scrnIndex, pI830->GTTBase, 512 * 1024);
+      else {
+	 xf86UnMapVidMem(pScrn->scrnIndex, pI830->GTTBase,
+			 pI830->FbMapSize / 1024);
+      }
+   }
 }
 
 static Bool
@@ -2279,6 +2291,9 @@ I830ScreenInit(int scrnIndex, ScreenPtr 
       pI830->used3D = pI8301->used3D;
    }
 
+   /* Need MMIO mapped to do GTT lookups during memory allocation. */
+   I830MapMMIO(pScrn);
+
 #if defined(XF86DRI)
    /*
     * If DRI is potentially usable, check if there is enough memory available
@@ -2419,6 +2434,8 @@ I830ScreenInit(int scrnIndex, ScreenPtr 
       allocation_done = TRUE;
    }
 
+   I830UnmapMMIO(pScrn);
+
    i830_describe_allocations(pScrn, 1, "");
 
    if (!IS_I965G(pI830) && pScrn->displayWidth > 2048) {
diff --git a/src/i830_memory.c b/src/i830_memory.c
index 9cf14e4..3ae10cf 100644
--- a/src/i830_memory.c
+++ b/src/i830_memory.c
@@ -324,7 +324,13 @@ static unsigned long
 i830_get_gtt_physical(ScrnInfoPtr pScrn, unsigned long offset)
 {
     I830Ptr pI830 = I830PTR(pScrn);
-    CARD32 gttentry = INGTT(offset / 1024);
+    CARD32 gttentry;
+
+    /* We don't have GTTBase set up on i830 yet. */
+    if (pI830->GTTBase == NULL)
+	return -1;
+
+    gttentry = INGTT(offset / 1024);
 
     /* Mask out these reserved bits on this hardware. */
     if (!IS_I965G(pI830))
diff-tree 1fc630f24f8ad9e304cb0761f9cacca2224203c4 (from d0ec37e9c0ceab1080700cd7be4a7cc58552d465)
Author: Eric Anholt <eric at anholt.net>
Date:   Wed May 2 13:29:21 2007 -0700

    Add DVO[ABC] register debugging.

diff --git a/src/i810_reg.h b/src/i810_reg.h
index 491c389..c3db5c9 100644
--- a/src/i810_reg.h
+++ b/src/i810_reg.h
@@ -1196,6 +1196,7 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN
 #define DVO_PIPE_STALL_UNUSED		(0 << 28)
 #define DVO_PIPE_STALL			(1 << 28)
 #define DVO_PIPE_STALL_TV		(2 << 28)
+#define DVO_PIPE_STALL_MASK		(3 << 28)
 #define DVO_USE_VGA_SYNC		(1 << 15)
 #define DVO_DATA_ORDER_I740		(0 << 14)
 #define DVO_DATA_ORDER_FP		(1 << 14)
diff --git a/src/i830_debug.c b/src/i830_debug.c
index c0261a6..73b5d1c 100644
--- a/src/i830_debug.c
+++ b/src/i830_debug.c
@@ -286,6 +286,33 @@ DEBUGSTRING(i830_debug_lvds)
 		     enable, pipe, depth, channels);
 }
 
+DEBUGSTRING(i830_debug_dvo)
+{
+    char *enable = val & DVO_ENABLE ? "enabled" : "disabled";
+    char pipe = val & DVO_PIPE_B_SELECT ? 'B' : 'A';
+    char *stall;
+    char hsync = val & DVO_HSYNC_ACTIVE_HIGH ? '+' : '-';
+    char vsync = val & DVO_VSYNC_ACTIVE_HIGH ? '+' : '-';
+
+    switch (val & DVO_PIPE_STALL_MASK) {
+    case DVO_PIPE_STALL_UNUSED:
+	stall = "no stall";
+	break;
+    case DVO_PIPE_STALL:
+	stall = "stall";
+	break;
+    case DVO_PIPE_STALL_TV:
+	stall = "TV stall";
+	break;
+    default:
+	stall = "unknown stall";
+	break;
+    }
+
+    return XNFprintf("%s, pipe %c, %s, %chsync, %cvsync",
+		     enable, pipe, stall, hsync, vsync);
+}
+
 DEBUGSTRING(i830_debug_sdvo)
 {
     char *enable = val & SDVO_ENABLE ? "enabled" : "disabled";
@@ -339,9 +366,9 @@ static struct i830SnapshotRec {
 
     DEFINEREG2(ADPA, i830_debug_adpa),
     DEFINEREG2(LVDS, i830_debug_lvds),
-    DEFINEREG(DVOA),
-    DEFINEREG(DVOB),
-    DEFINEREG(DVOC),
+    DEFINEREG2(DVOA, i830_debug_dvo),
+    DEFINEREG2(DVOB, i830_debug_dvo),
+    DEFINEREG2(DVOC, i830_debug_dvo),
     DEFINEREG(DVOA_SRCDIM),
     DEFINEREG(DVOB_SRCDIM),
     DEFINEREG(DVOC_SRCDIM),
diff-tree d0ec37e9c0ceab1080700cd7be4a7cc58552d465 (from 490d05f99d2b62dd612d514d9ae0badbac9285ce)
Author: Eric Anholt <eric at anholt.net>
Date:   Tue May 1 15:56:37 2007 -0700

    Make the DVO output name LVDS if it's an LVDS chip.

diff --git a/src/i830_dvo.c b/src/i830_dvo.c
index 4b37228..96b29e7 100644
--- a/src/i830_dvo.c
+++ b/src/i830_dvo.c
@@ -242,7 +242,6 @@ static const xf86OutputFuncsRec i830_dvo
 void
 i830_dvo_init(ScrnInfoPtr pScrn)
 {
-    xf86OutputPtr output;
     I830OutputPrivatePtr intel_output;
     int ret;
     int i;
@@ -251,27 +250,15 @@ i830_dvo_init(ScrnInfoPtr pScrn)
     int gpio_inited = 0;
     I2CBusPtr pI2CBus = NULL;
 
-    output = xf86OutputCreate (pScrn, &i830_dvo_output_funcs,
-				   "TMDS");
-    if (!output)
-	return;
     intel_output = xnfcalloc (sizeof (I830OutputPrivateRec), 1);
     if (!intel_output)
-    {
-	xf86OutputDestroy (output);
 	return;
-    }
     intel_output->type = I830_OUTPUT_DVO;
-    output->driver_private = intel_output;
-    output->subpixel_order = SubPixelHorizontalRGB;
-    output->interlaceAllowed = FALSE;
-    output->doubleScanAllowed = FALSE;
-    
+
     /* Set up the DDC bus */
     ret = I830I2CInit(pScrn, &intel_output->pDDCBus, GPIOD, "DVODDC_D");
-    if (!ret)
-    {
-	xf86OutputDestroy (output);
+    if (!ret) {
+	xfree(intel_output);
 	return;
     }
 
@@ -311,6 +298,28 @@ i830_dvo_init(ScrnInfoPtr pScrn)
 	    ret_ptr = drv->vid_rec->init(pI2CBus, drv->address);
 
 	if (ret_ptr != NULL) {
+	    xf86OutputPtr output;
+
+	    if (drv->type & I830_DVO_CHIP_LVDS) {
+		output = xf86OutputCreate(pScrn, &i830_dvo_output_funcs,
+					  "LVDS");
+	    } else {
+		output = xf86OutputCreate(pScrn, &i830_dvo_output_funcs,
+					  "TMDS");
+	    }
+	    if (output == NULL) {
+		xf86DestroyI2CBusRec(pI2CBus, TRUE, TRUE);
+		xf86DestroyI2CBusRec(intel_output->pDDCBus, TRUE, TRUE);
+		xfree(intel_output);
+		xf86UnloadSubModule(drv->modhandle);
+		return;
+	    }
+
+	    output->driver_private = intel_output;
+	    output->subpixel_order = SubPixelHorizontalRGB;
+	    output->interlaceAllowed = FALSE;
+	    output->doubleScanAllowed = FALSE;
+
 	    drv->dev_priv = ret_ptr;
 	    intel_output->i2c_drv = drv;
 	    intel_output->pI2CBus = pI2CBus;
@@ -322,5 +331,6 @@ i830_dvo_init(ScrnInfoPtr pScrn)
     /* Didn't find a chip, so tear down. */
     if (pI2CBus != NULL)
 	xf86DestroyI2CBusRec(pI2CBus, TRUE, TRUE);
-    xf86OutputDestroy (output);
+    xf86DestroyI2CBusRec(intel_output->pDDCBus, TRUE, TRUE);
+    xfree(intel_output);
 }
diff-tree 490d05f99d2b62dd612d514d9ae0badbac9285ce (from c7bb34e83d7c459d932d01070cfeffbbf6c703ac)
Author: Eric Anholt <eric at anholt.net>
Date:   Tue May 1 15:47:01 2007 -0700

    Fix typo in previous commit with s/XF86_DRI/XF86DRI/

diff --git a/src/i830_memory.c b/src/i830_memory.c
index 23e7dbc..9cf14e4 100644
--- a/src/i830_memory.c
+++ b/src/i830_memory.c
@@ -250,7 +250,7 @@ i830_free_3d_memory(ScrnInfoPtr pScrn)
 {
     I830Ptr pI830 = I830PTR(pScrn);
 
-#ifdef XF86_DRI
+#ifdef XF86DRI
     i830_free_memory(pScrn, pI830->back_buffer);
     pI830->back_buffer = NULL;
     i830_free_memory(pScrn, pI830->third_buffer);



More information about the xorg-commit mailing list