xf86-video-ati: Branch 'master'

Alex Deucher agd5f at kemper.freedesktop.org
Sun Sep 30 09:04:46 PDT 2007


 src/radeon_modes.c  |  103 ++++++++++++++++++++++++++++++++++++++++++++++++----
 src/radeon_output.c |   37 +++++++++++-------
 2 files changed, 120 insertions(+), 20 deletions(-)

New commits:
diff-tree 99ceaefa18c6e07b55106cca0ea8996fa73667be (from d808781d48adf01e80b5bb476bae2d2f599030f1)
Author: Alex Deucher <alex at t41p.hsd1.va.comcast.net>
Date:   Sun Sep 30 12:02:54 2007 -0400

    RADEON: more work on LVDS mode validation and fixups
    
    Hopefully this will fix up the weird mode issues with LVDS and
    native and RMX modes, but I can't seem to get quite the right
    combo to fix everyone.

diff --git a/src/radeon_modes.c b/src/radeon_modes.c
index 51b5366..453f4a8 100644
--- a/src/radeon_modes.c
+++ b/src/radeon_modes.c
@@ -120,7 +120,7 @@ static DisplayModePtr RADEONFPNativeMode
 
 	new->Clock      = radeon_output->DotClock;
 	new->Flags      = 0;
-	new->type       = M_T_USERDEF | M_T_PREFERRED;
+	new->type       = M_T_DRIVER | M_T_PREFERRED;
 
 	new->next       = NULL;
 	new->prev       = NULL;
@@ -132,9 +132,101 @@ static DisplayModePtr RADEONFPNativeMode
     return new;
 }
 
+/* FP mode initialization routine for using on-chip RMX to scale
+ */
+int RADEONValidateFPModes(xf86OutputPtr output, char **ppModeName, DisplayModePtr *modeList)
+{
+    ScrnInfoPtr pScrn = output->scrn;
+    RADEONOutputPrivatePtr radeon_output = output->driver_private;
+    DisplayModePtr  last       = NULL;
+    DisplayModePtr  new        = NULL;
+    DisplayModePtr  first      = NULL;
+    int             count      = 0;
+    int             i, width, height;
+
+
+    /* add the native mode */
+    if (!count) {
+	first = last = RADEONFPNativeMode(output);
+	if (first) count = 1;
+    }
+
+    /* We have a flat panel connected to the primary display, and we
+     * don't have any DDC info.
+     */
+    for (i = 0; ppModeName[i] != NULL; i++) {
+
+	if (sscanf(ppModeName[i], "%dx%d", &width, &height) != 2) continue;
+
+	/* already added the native mode */
+	if (width == radeon_output->PanelXRes && height == radeon_output->PanelYRes)
+	    continue;
+
+	/* Note: We allow all non-standard modes as long as they do not
+	 * exceed the native resolution of the panel.  Since these modes
+	 * need the internal RMX unit in the video chips (and there is
+	 * only one per card), this will only apply to the primary head.
+	 */
+	if (width < 320 || width > radeon_output->PanelXRes ||
+	    height < 200 || height > radeon_output->PanelYRes) {
+	    xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+		       "Mode %s is out of range.\n", ppModeName[i]);
+	    xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+		       "Valid modes must be between 320x200-%dx%d\n",
+		       radeon_output->PanelXRes, radeon_output->PanelYRes);
+	    continue;
+	}
+
+	new             = xnfcalloc(1, sizeof(DisplayModeRec));
+	new->name       = xnfalloc(strlen(ppModeName[i]) + 1);
+	strcpy(new->name, ppModeName[i]);
+	new->HDisplay   = width;
+	new->VDisplay   = height;
+
+	/* These values are effective values after expansion They are
+	 * not really used to set CRTC registers.
+	 */
+	new->HTotal     = radeon_output->PanelXRes + radeon_output->HBlank;
+	new->HSyncStart = radeon_output->PanelXRes + radeon_output->HOverPlus;
+	new->HSyncEnd   = new->HSyncStart + radeon_output->HSyncWidth;
+	new->VTotal     = radeon_output->PanelYRes + radeon_output->VBlank;
+	new->VSyncStart = radeon_output->PanelYRes + radeon_output->VOverPlus;
+	new->VSyncEnd   = new->VSyncStart + radeon_output->VSyncWidth;
+	new->Clock      = radeon_output->DotClock;
+	new->Flags     |= RADEON_USE_RMX;
+
+	new->type      |= M_T_USERDEF;
+
+	new->next       = NULL;
+	new->prev       = last;
+
+	if (last) last->next = new;
+	last = new;
+	if (!first) first = new;
+
+	count++;
+	xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+		   "Valid mode using on-chip RMX: %s\n", new->name);
+    }
+
+
+    /* Close the doubly-linked mode list, if we found any usable modes */
+    if (last) {
+	last->next   = NULL; //first;
+	first->prev  = NULL; //last;
+	*modeList = first;
+    }
+
+    xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+	       "Total number of valid FP mode(s) found: %d\n", count);
+
+    return count;
+}
+
 DisplayModePtr
 RADEONProbeOutputModes(xf86OutputPtr output)
 {
+    ScrnInfoPtr pScrn = output->scrn;
     RADEONOutputPrivatePtr radeon_output = output->driver_private;
     xf86MonPtr		    edid_mon;
     DisplayModePtr	    modes = NULL;
@@ -160,12 +252,11 @@ RADEONProbeOutputModes(xf86OutputPtr out
 		xf86OutputSetEDID (output, edid_mon);
 
 		modes = xf86OutputGetEDIDModes (output);
-		return modes;
-	    } else {
-		/* add native panel mode */
-		modes = RADEONFPNativeMode(output);
-		return modes;
 	    }
+	    if (modes == NULL) {
+		RADEONValidateFPModes(output, pScrn->display->modes, &modes);
+	    }
+	    return modes;
 	}
     }
 
diff --git a/src/radeon_output.c b/src/radeon_output.c
index 6ece28a..fd94266 100644
--- a/src/radeon_output.c
+++ b/src/radeon_output.c
@@ -658,7 +658,7 @@ radeon_mode_valid(xf86OutputPtr output, 
 	    pMode->VDisplay > radeon_output->PanelYRes)
 	    return MODE_PANEL;
     }
-    
+
     return MODE_OK;
 }
 
@@ -668,28 +668,37 @@ radeon_mode_fixup(xf86OutputPtr output, 
 {
     RADEONOutputPrivatePtr radeon_output = output->driver_private;
 
+    if (radeon_output->MonType == MT_LCD) {
+	adjusted_mode->HTotal     = radeon_output->PanelXRes + radeon_output->HBlank;
+	adjusted_mode->HSyncStart = radeon_output->PanelXRes + radeon_output->HOverPlus;
+	adjusted_mode->HSyncEnd   = adjusted_mode->HSyncStart + radeon_output->HSyncWidth;
+	adjusted_mode->VTotal     = radeon_output->PanelYRes + radeon_output->VBlank;
+	adjusted_mode->VSyncStart = radeon_output->PanelYRes + radeon_output->VOverPlus;
+	adjusted_mode->VSyncEnd   = adjusted_mode->VSyncStart + radeon_output->VSyncWidth;
+	adjusted_mode->Clock      = radeon_output->DotClock;
+	adjusted_mode->Flags      = radeon_output->Flags;
+    }
+
     if ((radeon_output->MonType == MT_LCD || radeon_output->MonType == MT_DFP)
 	&& radeon_output->rmx_type != RMX_OFF) {
 	xf86CrtcPtr crtc = output->crtc;
 	RADEONCrtcPrivatePtr radeon_crtc = crtc->driver_private;
 
-	if ((mode->HDisplay < radeon_output->PanelXRes ||
-	     mode->VDisplay < radeon_output->PanelYRes) &&
-	    radeon_crtc->crtc_id == 0)
+	if (radeon_crtc->crtc_id == 0)
 	    adjusted_mode->Flags |= RADEON_USE_RMX;
 
 	if (adjusted_mode->Flags & RADEON_USE_RMX) {
 	    radeon_output->Flags |= RADEON_USE_RMX;
-	    if (radeon_output->MonType == MT_DFP) {
-		adjusted_mode->CrtcHTotal     = mode->CrtcHDisplay + radeon_output->HBlank;
-		adjusted_mode->CrtcHSyncStart = mode->CrtcHDisplay + radeon_output->HOverPlus;
-		adjusted_mode->CrtcHSyncEnd   = mode->CrtcHSyncStart + radeon_output->HSyncWidth;
-		adjusted_mode->CrtcVTotal     = mode->CrtcVDisplay + radeon_output->VBlank;
-		adjusted_mode->CrtcVSyncStart = mode->CrtcVDisplay + radeon_output->VOverPlus;
-		adjusted_mode->CrtcVSyncEnd   = mode->CrtcVSyncStart + radeon_output->VSyncWidth;
-		adjusted_mode->Clock          = radeon_output->DotClock;
-		adjusted_mode->Flags          = radeon_output->Flags;
-	    }
+
+	    adjusted_mode->CrtcHTotal     = mode->CrtcHDisplay + radeon_output->HBlank;
+	    adjusted_mode->CrtcHSyncStart = mode->CrtcHDisplay + radeon_output->HOverPlus;
+	    adjusted_mode->CrtcHSyncEnd   = mode->CrtcHSyncStart + radeon_output->HSyncWidth;
+	    adjusted_mode->CrtcVTotal     = mode->CrtcVDisplay + radeon_output->VBlank;
+	    adjusted_mode->CrtcVSyncStart = mode->CrtcVDisplay + radeon_output->VOverPlus;
+	    adjusted_mode->CrtcVSyncEnd   = mode->CrtcVSyncStart + radeon_output->VSyncWidth;
+	    adjusted_mode->Clock          = radeon_output->DotClock;
+	    adjusted_mode->Flags          = radeon_output->Flags;
+
 	} else
 	    radeon_output->Flags &= ~RADEON_USE_RMX;
 


More information about the xorg-commit mailing list