summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlex Deucher <alex@t41p.hsd1.va.comcast.net>2007-10-03 00:59:37 -0400
committerAlex Deucher <alex@t41p.hsd1.va.comcast.net>2007-10-03 00:59:37 -0400
commitcc0c2d8e61600652b1f9cb3dc49db2ef62b1e40d (patch)
tree455fa1f01590b6dd60ead79b1185048e24c9b616
parent0ca184c3c35032df39ea7ce5d2d4aba1a97b6426 (diff)
RADEON: Finally sort out LVDS modes
- The panel timing from the bios tables is for the crtc, not the native panel mode, so add cvt modes for the panel and fix up the crtc values in mode_fixup(). - rename and reconfigure RADEONValidateFPModes() to what it really does: add screen modes. I suppose for backwards compatibility we ought to add the screen modes to every reasonable output, but everyone should really use xrandr or an output monitor section to add custom modes. Hopefully this will go away at some point.
-rw-r--r--src/radeon.h1
-rw-r--r--src/radeon_modes.c96
-rw-r--r--src/radeon_output.c44
3 files changed, 49 insertions, 92 deletions
diff --git a/src/radeon.h b/src/radeon.h
index 288fe00..610e2b3 100644
--- a/src/radeon.h
+++ b/src/radeon.h
@@ -940,7 +940,6 @@ extern Bool RADEONAllocateConnectors(ScrnInfoPtr pScrn);
extern int RADEONValidateMergeModes(ScrnInfoPtr pScrn);
extern int RADEONValidateDDCModes(ScrnInfoPtr pScrn1, char **ppModeName,
RADEONMonitorType DisplayType, int crtc2);
-extern int RADEONValidateFPModes(xf86OutputPtr output, char **ppModeName, DisplayModePtr *modeList);
extern void RADEONSetPitch (ScrnInfoPtr pScrn);
extern void RADEONUpdateHVPosition(xf86OutputPtr output, DisplayModePtr mode);
diff --git a/src/radeon_modes.c b/src/radeon_modes.c
index 453f4a8..ea2c229 100644
--- a/src/radeon_modes.c
+++ b/src/radeon_modes.c
@@ -97,29 +97,14 @@ static DisplayModePtr RADEONFPNativeMode(xf86OutputPtr output)
ScrnInfoPtr pScrn = output->scrn;
RADEONOutputPrivatePtr radeon_output = output->driver_private;
DisplayModePtr new = NULL;
- char stmp[32];
if (radeon_output->PanelXRes != 0 &&
radeon_output->PanelYRes != 0 &&
radeon_output->DotClock != 0) {
/* Add native panel size */
- new = xnfcalloc(1, sizeof (DisplayModeRec));
- sprintf(stmp, "%dx%d", radeon_output->PanelXRes, radeon_output->PanelYRes);
- new->name = xnfalloc(strlen(stmp) + 1);
- strcpy(new->name, stmp);
- new->HDisplay = radeon_output->PanelXRes;
- new->VDisplay = radeon_output->PanelYRes;
-
- new->HTotal = new->HDisplay + radeon_output->HBlank;
- new->HSyncStart = new->HDisplay + radeon_output->HOverPlus;
- new->HSyncEnd = new->HSyncStart + radeon_output->HSyncWidth;
- new->VTotal = new->VDisplay + radeon_output->VBlank;
- new->VSyncStart = new->VDisplay + radeon_output->VOverPlus;
- new->VSyncEnd = new->VSyncStart + radeon_output->VSyncWidth;
-
- new->Clock = radeon_output->DotClock;
- new->Flags = 0;
+ new = xf86CVTMode(radeon_output->PanelXRes, radeon_output->PanelYRes, 60.0, TRUE, FALSE);
+
new->type = M_T_DRIVER | M_T_PREFERRED;
new->next = NULL;
@@ -132,9 +117,8 @@ static DisplayModePtr RADEONFPNativeMode(xf86OutputPtr output)
return new;
}
-/* FP mode initialization routine for using on-chip RMX to scale
- */
-int RADEONValidateFPModes(xf86OutputPtr output, char **ppModeName, DisplayModePtr *modeList)
+/* this function is basically a hack to add the screen modes */
+static void RADEONAddScreenModes(xf86OutputPtr output, DisplayModePtr *modeList)
{
ScrnInfoPtr pScrn = output->scrn;
RADEONOutputPrivatePtr radeon_output = output->driver_private;
@@ -143,13 +127,9 @@ int RADEONValidateFPModes(xf86OutputPtr output, char **ppModeName, DisplayModePt
DisplayModePtr first = NULL;
int count = 0;
int i, width, height;
+ char **ppModeName = pScrn->display->modes;
-
- /* add the native mode */
- if (!count) {
- first = last = RADEONFPNativeMode(output);
- if (first) count = 1;
- }
+ first = last = *modeList;
/* We have a flat panel connected to the primary display, and we
* don't have any DDC info.
@@ -158,42 +138,28 @@ int RADEONValidateFPModes(xf86OutputPtr output, char **ppModeName, DisplayModePt
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;
+ if (radeon_output->type == OUTPUT_LVDS) {
+ /* 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 FP 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 = xf86CVTMode(width, height, 60.0, TRUE, FALSE);
new->type |= M_T_USERDEF;
@@ -206,7 +172,7 @@ int RADEONValidateFPModes(xf86OutputPtr output, char **ppModeName, DisplayModePt
count++;
xf86DrvMsg(pScrn->scrnIndex, X_INFO,
- "Valid mode using on-chip RMX: %s\n", new->name);
+ "Adding Screen mode: %s\n", new->name);
}
@@ -218,15 +184,13 @@ int RADEONValidateFPModes(xf86OutputPtr output, char **ppModeName, DisplayModePt
}
xf86DrvMsg(pScrn->scrnIndex, X_INFO,
- "Total number of valid FP mode(s) found: %d\n", count);
+ "Total number of valid Screen mode(s) added: %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;
@@ -254,7 +218,9 @@ RADEONProbeOutputModes(xf86OutputPtr output)
modes = xf86OutputGetEDIDModes (output);
}
if (modes == NULL) {
- RADEONValidateFPModes(output, pScrn->display->modes, &modes);
+ modes = RADEONFPNativeMode(output);
+ /* add the screen modes */
+ RADEONAddScreenModes(output, &modes);
}
return modes;
}
diff --git a/src/radeon_output.c b/src/radeon_output.c
index 358aa0e..27c6928 100644
--- a/src/radeon_output.c
+++ b/src/radeon_output.c
@@ -750,40 +750,32 @@ radeon_mode_fixup(xf86OutputPtr output, DisplayModePtr mode,
{
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;
- }
-
+ /* decide if we are using RMX */
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 (radeon_crtc->crtc_id == 0)
- adjusted_mode->Flags |= RADEON_USE_RMX;
-
- if (adjusted_mode->Flags & RADEON_USE_RMX) {
- radeon_output->Flags |= RADEON_USE_RMX;
-
- 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;
-
+ if (radeon_crtc->crtc_id == 0) {
+ if (mode->HDisplay < radeon_output->PanelXRes ||
+ mode->VDisplay < radeon_output->PanelYRes)
+ radeon_output->Flags |= RADEON_USE_RMX;
} else
radeon_output->Flags &= ~RADEON_USE_RMX;
+ }
+ /* update crtc timing for LVDS always and DFP if RMX is active */
+ if ((radeon_output->MonType == MT_LCD) ||
+ ((radeon_output->MonType == MT_DFP) &&
+ (radeon_output->Flags & RADEON_USE_RMX))) {
+ 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;
}
return TRUE;