xf86-video-intel: Branch 'modesetting' - 2 commits - src/i830_crt.c src/i830_dvo.c src/i830.h src/i830_lvds.c src/i830_modes.c src/i830_randr.c src/i830_sdvo.c src/i830_tv.c

Eric Anholt anholt at kemper.freedesktop.org
Wed Nov 1 21:52:49 EET 2006


 src/i830.h       |   15 +++++++++
 src/i830_crt.c   |    1 
 src/i830_dvo.c   |    1 
 src/i830_lvds.c  |    5 +++
 src/i830_modes.c |   33 ++++++++++++++++++++
 src/i830_randr.c |   88 ++++++++++++++++++++++++++++---------------------------
 src/i830_sdvo.c  |    1 
 src/i830_tv.c    |   13 ++++++++
 8 files changed, 113 insertions(+), 44 deletions(-)

New commits:
diff-tree f30d7f912f36b110c3af7dc795e35456593781ab (from 7195dfabd56239f08cdd8175a2ef3a66ef9600de)
Author: Eric Anholt <eric at anholt.net>
Date:   Wed Nov 1 11:50:51 2006 -0800

    Update for the move of RandR phyiscal size information.

diff --git a/src/i830_randr.c b/src/i830_randr.c
index a1c4b12..f8064b9 100644
--- a/src/i830_randr.c
+++ b/src/i830_randr.c
@@ -723,17 +723,15 @@ I830RandRSetInfo12 (ScreenPtr pScreen)
 		return FALSE;
 	    nmode = 0;
 
+	    /* We should pull info out of EDID to get the output physical
+	     * size when available.
+	     */
+	    RROutputSetPhysicalSize(randrp->outputs[i], 0, 0);
+
 	    for (p = 1; p >= 0; p--) {
 		for (mode = modes; mode; mode = mode->next) {
 		    if ((p != 0) == ((mode->type & M_T_PREFERRED) != 0)) {
 			modeInfo.nameLength = strlen (mode->name);
-			if (mon != NULL) {
-			    modeInfo.mmWidth = mon->widthmm;
-			    modeInfo.mmHeight = mon->heightmm;
-			} else {
-			    modeInfo.mmWidth = 0;
-			    modeInfo.mmHeight = 0;
-			}
 
 			modeInfo.width = mode->HDisplay;
 			modeInfo.dotClock = mode->Clock * 1000;
diff-tree 7195dfabd56239f08cdd8175a2ef3a66ef9600de (from cc3728be2481637dda321d3bc2e4e89a220699cd)
Author: Eric Anholt <eric at anholt.net>
Date:   Tue Oct 31 17:10:08 2006 -0800

    Give each output a get_modes function and expose those modes through RandR.
    
    The get_modes should return the probed modes only.  The driver should then
    append to the list (for example, compatible modes listed in other outputs,
    or standard VESA modes) to create the list to expose through RandR.  That
    isn't done yet.

diff --git a/src/i830.h b/src/i830.h
index 27a9817..5915a17 100644
--- a/src/i830.h
+++ b/src/i830.h
@@ -269,6 +269,20 @@ struct _I830OutputRec {
     */
    enum detect_status (*detect)(ScrnInfoPtr pScrn, I830OutputPtr output);
 
+   /**
+    * Query the device for the modes it provides.
+    *
+    * \return singly-linked list of modes or NULL if no modes found.
+    */
+   DisplayModePtr (*get_modes)(ScrnInfoPtr pScrn, I830OutputPtr output);
+
+   /**
+    * List of available modes on this output.
+    *
+    * This should be the list from get_modes(), plus perhaps additional
+    * compatible modes added later.
+    */
+   DisplayModePtr probed_modes;
    xf86MonPtr MonInfo;
    I2CBusPtr pI2CBus;
    I2CBusPtr pDDCBus;
@@ -680,6 +694,7 @@ DisplayModePtr i830GetGTF(int h_pixels, 
 
 /* i830_modes.c */
 int I830ValidateXF86ModeList(ScrnInfoPtr pScrn, Bool first_time);
+DisplayModePtr i830_ddc_get_modes(ScrnInfoPtr pScrn, I830OutputPtr output);
 
 /* i830_randr.c */
 Bool I830RandRCreateScreenResources (ScreenPtr pScreen);
diff --git a/src/i830_crt.c b/src/i830_crt.c
index d271eed..bd0099a 100644
--- a/src/i830_crt.c
+++ b/src/i830_crt.c
@@ -286,6 +286,7 @@ i830_crt_init(ScrnInfoPtr pScrn)
     pI830->output[pI830->num_outputs].pre_set_mode = i830_crt_pre_set_mode;
     pI830->output[pI830->num_outputs].post_set_mode = i830_crt_post_set_mode;
     pI830->output[pI830->num_outputs].detect = i830_crt_detect;
+    pI830->output[pI830->num_outputs].get_modes = i830_ddc_get_modes;
 
     /* Set up the DDC bus. */
     I830I2CInit(pScrn, &pI830->output[pI830->num_outputs].pDDCBus,
diff --git a/src/i830_dvo.c b/src/i830_dvo.c
index ed21ecc..c788e4f 100644
--- a/src/i830_dvo.c
+++ b/src/i830_dvo.c
@@ -201,6 +201,7 @@ i830_dvo_init(ScrnInfoPtr pScrn)
     pI830->output[i].pre_set_mode  = i830_dvo_pre_set_mode;
     pI830->output[i].post_set_mode  = i830_dvo_post_set_mode;
     pI830->output[i].detect  = i830_dvo_detect;
+    pI830->output[i].get_modes = i830_ddc_get_modes;
 
     /* Set up the I2C and DDC buses */
     ret = I830I2CInit(pScrn, &pI830->output[i].pI2CBus, GPIOE, "DVOI2C_E");
diff --git a/src/i830_lvds.c b/src/i830_lvds.c
index e0e471f..4b89903 100644
--- a/src/i830_lvds.c
+++ b/src/i830_lvds.c
@@ -235,6 +235,11 @@ i830_lvds_init(ScrnInfoPtr pScrn)
     pI830->output[pI830->num_outputs].pre_set_mode = i830_lvds_pre_set_mode;
     pI830->output[pI830->num_outputs].post_set_mode = i830_lvds_post_set_mode;
     pI830->output[pI830->num_outputs].detect = i830_lvds_detect;
+    /* This will usually return NULL on laptop panels, which is no good.
+     * We need to construct a mode from the fixed panel info, and return a copy
+     * of that when DDC is unavailable.
+     */
+    pI830->output[pI830->num_outputs].get_modes = i830_ddc_get_modes;
 
     /* Set up the LVDS DDC channel.  Most panels won't support it, but it can
      * be useful if available.
diff --git a/src/i830_modes.c b/src/i830_modes.c
index 130b7fe..1ba1def 100644
--- a/src/i830_modes.c
+++ b/src/i830_modes.c
@@ -933,11 +933,22 @@ int
 I830ValidateXF86ModeList(ScrnInfoPtr pScrn, Bool first_time)
 {
     I830Ptr pI830 = I830PTR(pScrn);
-    int pipe;
+    int pipe, i;
     DisplayModePtr saved_mode, last;
     Bool pipes_reconfigured = FALSE;
     int originalVirtualX, originalVirtualY;
 
+    /* Re-probe the list of modes for each output. */
+    for (i = 0; i < pI830->num_outputs; i++) {
+	while (pI830->output[i].probed_modes != NULL) {
+	    xf86DeleteMode(&pI830->output[i].probed_modes,
+			   pI830->output[i].probed_modes);
+	}
+
+	pI830->output[i].probed_modes =
+	    pI830->output[i].get_modes(pScrn, &pI830->output[i]);
+    }
+
     for (pipe = 0; pipe < pI830->availablePipes; pipe++) {
 	I830ReprobePipeModeList(pScrn, pipe);
     }
@@ -1099,3 +1110,23 @@ I830ValidateXF86ModeList(ScrnInfoPtr pSc
 
     return 1; /* XXX */
 }
+
+/**
+ * Generic get_modes function using DDC, used by many outputs.
+ */
+DisplayModePtr
+i830_ddc_get_modes(ScrnInfoPtr pScrn, I830OutputPtr output)
+{
+    xf86MonPtr ddc_mon;
+    DisplayModePtr ddc_modes;
+
+    ddc_mon = xf86DoEDID_DDC2(pScrn->scrnIndex, output->pDDCBus);
+    if (ddc_mon == NULL)
+	return NULL;
+
+    ddc_modes = i830GetDDCModes(pScrn, ddc_mon);
+
+    xfree(ddc_mon);
+
+    return ddc_modes;
+}
diff --git a/src/i830_randr.c b/src/i830_randr.c
index 23ffaf6..a1c4b12 100644
--- a/src/i830_randr.c
+++ b/src/i830_randr.c
@@ -612,7 +612,6 @@ I830RandRSetInfo12 (ScreenPtr pScreen)
     int			p;
     int			clone_types;
     int			crtc_types;
-    int			connection;
     int			pipe_type;
     int			pipe;
     int			subpixel;
@@ -631,6 +630,8 @@ I830RandRSetInfo12 (ScreenPtr pScreen)
 			  randrp->virtualX, randrp->virtualY);
     for (i = 0; i < pI830->num_outputs; i++)
     {
+	MonPtr mon;
+
 	output = &pI830->output[i];
 	/*
 	 * Valid crtcs
@@ -705,50 +706,53 @@ I830RandRSetInfo12 (ScreenPtr pScreen)
         nmode = 0;
 	npreferred = 0;
 	rrmodes = NULL;
-	if (pipe >= 0)
-	{
-	    MonPtr  mon = pI830->pipeMon[pipe];
-	    modes = mon->Modes;
 
-	    for (mode = modes; mode; mode = mode->next)
-		nmode++;
+	modes = pI830->output[i].probed_modes;
 
-	    if (nmode)
-	    {
-		rrmodes = xalloc (nmode * sizeof (RRModePtr));
-		if (!rrmodes)
-		    return FALSE;
-		nmode = 0;
-		for (p = 1; p >= 0; p--)
-		{
-		    for (mode = modes; mode; mode = mode->next)
-		    {
-			if ((p != 0) == ((mode->type & M_T_PREFERRED) != 0))
-			{
-			    modeInfo.nameLength = strlen (mode->name);
+	if (pI830->output[i].pipe >= 0)
+	    mon = pI830->pipeMon[pipe];
+	else
+	    mon = NULL;
+
+	for (mode = modes; mode; mode = mode->next)
+	    nmode++;
+
+	if (nmode) {
+	    rrmodes = xalloc (nmode * sizeof (RRModePtr));
+	    if (!rrmodes)
+		return FALSE;
+	    nmode = 0;
+
+	    for (p = 1; p >= 0; p--) {
+		for (mode = modes; mode; mode = mode->next) {
+		    if ((p != 0) == ((mode->type & M_T_PREFERRED) != 0)) {
+			modeInfo.nameLength = strlen (mode->name);
+			if (mon != NULL) {
 			    modeInfo.mmWidth = mon->widthmm;
 			    modeInfo.mmHeight = mon->heightmm;
+			} else {
+			    modeInfo.mmWidth = 0;
+			    modeInfo.mmHeight = 0;
+			}
 
-			    modeInfo.width = mode->HDisplay;
-			    modeInfo.dotClock = mode->Clock * 1000;
-			    modeInfo.hSyncStart = mode->HSyncStart;
-			    modeInfo.hSyncEnd = mode->HSyncEnd;
-			    modeInfo.hTotal = mode->HTotal;
-			    modeInfo.hSkew = mode->HSkew;
-
-			    modeInfo.height = mode->VDisplay;
-			    modeInfo.vSyncStart = mode->VSyncStart;
-			    modeInfo.vSyncEnd = mode->VSyncEnd;
-			    modeInfo.vTotal = mode->VTotal;
-			    modeInfo.modeFlags = mode->Flags;
-
-			    rrmode = RRModeGet (pScreen, &modeInfo, mode->name);
-			    rrmode->devPrivate = mode;
-			    if (rrmode)
-			    {
-				rrmodes[nmode++] = rrmode;
-				npreferred += p;
-			    }
+			modeInfo.width = mode->HDisplay;
+			modeInfo.dotClock = mode->Clock * 1000;
+			modeInfo.hSyncStart = mode->HSyncStart;
+			modeInfo.hSyncEnd = mode->HSyncEnd;
+			modeInfo.hTotal = mode->HTotal;
+			modeInfo.hSkew = mode->HSkew;
+
+			modeInfo.height = mode->VDisplay;
+			modeInfo.vSyncStart = mode->VSyncStart;
+			modeInfo.vSyncEnd = mode->VSyncEnd;
+			modeInfo.vTotal = mode->VTotal;
+			modeInfo.modeFlags = mode->Flags;
+
+			rrmode = RRModeGet (pScreen, &modeInfo, mode->name);
+			rrmode->devPrivate = mode;
+			if (rrmode) {
+			    rrmodes[nmode++] = rrmode;
+			    npreferred += p;
 			}
 		    }
 		}
diff --git a/src/i830_sdvo.c b/src/i830_sdvo.c
index 3932ea6..b6a3d67 100644
--- a/src/i830_sdvo.c
+++ b/src/i830_sdvo.c
@@ -940,6 +940,7 @@ i830_sdvo_init(ScrnInfoPtr pScrn, int ou
     output->pre_set_mode = i830_sdvo_pre_set_mode;
     output->post_set_mode = i830_sdvo_post_set_mode;
     output->detect = i830_sdvo_detect;
+    output->get_modes = i830_ddc_get_modes;
 
     /* While it's the same bus, we just initialize a new copy to avoid trouble
      * with tracking refcounting ourselves, since the XFree86 DDX bits don't.
diff --git a/src/i830_tv.c b/src/i830_tv.c
index 3e72882..47c0d03 100644
--- a/src/i830_tv.c
+++ b/src/i830_tv.c
@@ -417,6 +417,18 @@ i830_tv_detect(ScrnInfoPtr pScrn, I830Ou
     return OUTPUT_STATUS_UNKNOWN;
 }
 
+/**
+ * Stub get_modes function.
+ *
+ * This should probably return a set of fixed modes, unless we can figure out
+ * how to probe modes off of TV connections.
+ */
+DisplayModePtr
+i830_tv_get_modes(ScrnInfoPtr pScrn, I830OutputPtr output)
+{
+    return NULL;
+}
+
 void
 i830_tv_init(ScrnInfoPtr pScrn)
 {
@@ -438,6 +450,7 @@ i830_tv_init(ScrnInfoPtr pScrn)
     pI830->output[pI830->num_outputs].pre_set_mode = i830_tv_pre_set_mode;
     pI830->output[pI830->num_outputs].post_set_mode = i830_tv_post_set_mode;
     pI830->output[pI830->num_outputs].detect = i830_tv_detect;
+    pI830->output[pI830->num_outputs].get_modes = i830_tv_get_modes;
 
     pI830->num_outputs++;
 }



More information about the xorg-commit mailing list