summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJames Simmons <jsimmons@infradead.org>2012-03-15 20:49:27 -0400
committerJames Simmons <jsimmons@infradead.org>2012-03-15 20:49:27 -0400
commitde380d662c9edc151814adfec9f96fe491bc2c11 (patch)
tree6dc4028c7cddf173264180ae787364e3751a02a8
parent56121453116cd9144ed4b3f2461f142227d94db7 (diff)
Fixed the EDID handling for the LVDS. The code was to dependent on a NativeMode being present which is not set with EDID.
-rw-r--r--src/via_lvds.c205
-rw-r--r--src/via_ums.h9
2 files changed, 95 insertions, 119 deletions
diff --git a/src/via_lvds.c b/src/via_lvds.c
index 9a20633..db07fad 100644
--- a/src/via_lvds.c
+++ b/src/via_lvds.c
@@ -613,11 +613,11 @@ ViaPanelGetNativeModeFromScratchPad(xf86OutputPtr output)
index = hwp->readCrtc(hwp, 0x3F) & 0x0F;
panel->NativeModeIndex = index;
- panel->NativeMode->Width = ViaPanelNativeModes[index].Width;
- panel->NativeMode->Height = ViaPanelNativeModes[index].Height;
+ panel->NativeWidth = ViaPanelNativeModes[index].Width;
+ panel->NativeHeight = ViaPanelNativeModes[index].Height;
xf86DrvMsg(pScrn->scrnIndex, X_INFO,
"Native Panel Resolution is %dx%d\n",
- panel->NativeMode->Width, panel->NativeMode->Height);
+ panel->NativeWidth, panel->NativeHeight);
}
/* Used only for Legacy Mode Setting */
@@ -722,8 +722,8 @@ ViaPanelGetIndex(xf86OutputPtr output, DisplayModePtr mode)
for (i = 0; ViaResolutionTable[i].Index != VIA_RES_INVALID; i++) {
if (ViaResolutionTable[i].PanelIndex == Panel->NativeModeIndex) {
- Panel->NativeMode->Width = ViaResolutionTable[i].X;
- Panel->NativeMode->Height = ViaResolutionTable[i].Y;
+ Panel->NativeWidth = ViaResolutionTable[i].X;
+ Panel->NativeHeight = ViaResolutionTable[i].Y;
break;
}
}
@@ -734,8 +734,8 @@ ViaPanelGetIndex(xf86OutputPtr output, DisplayModePtr mode)
return FALSE;
}
- if ((Panel->NativeMode->Width != mode->CrtcHDisplay) ||
- (Panel->NativeMode->Height != mode->CrtcVDisplay)) {
+ if ((Panel->NativeWidth != mode->CrtcHDisplay) ||
+ (Panel->NativeHeight != mode->CrtcVDisplay)) {
xf86DrvMsg(pScrn->scrnIndex, X_INFO, "ViaPanelGetIndex: Non-native"
" resolutions are broken.\n");
return FALSE;
@@ -760,7 +760,7 @@ ViaPanelGetIndex(xf86OutputPtr output, DisplayModePtr mode)
Panel->PanelIndex = i;
DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "ViaPanelGetIndex:"
"index: %d (%dx%d)\n", Panel->PanelIndex,
- Panel->NativeMode->Width, Panel->NativeMode->Height));
+ Panel->NativeWidth, Panel->NativeHeight));
return TRUE;
}
@@ -786,14 +786,13 @@ via_lvds_mode_valid(xf86OutputPtr output, DisplayModePtr pMode)
return MODE_BAD;
} else {
ViaPanelInfoPtr Panel = output->driver_private;
- ViaPanelModePtr nativeMode = Panel->NativeMode;
- if (nativeMode->Width < pMode->HDisplay ||
- nativeMode->Height < pMode->VDisplay)
+ if (Panel->NativeWidth < pMode->HDisplay ||
+ Panel->NativeHeight < pMode->VDisplay)
return MODE_PANEL;
- if (!Panel->Scale && nativeMode->Height != pMode->VDisplay &&
- nativeMode->Width != pMode->HDisplay)
+ if (!Panel->Scale && Panel->NativeHeight != pMode->VDisplay &&
+ Panel->NativeWidth != pMode->HDisplay)
return MODE_PANEL;
if (!ViaModeDotClockTranslate(pScrn, pMode))
@@ -802,10 +801,53 @@ via_lvds_mode_valid(xf86OutputPtr output, DisplayModePtr pMode)
return MODE_OK;
}
+static void
+ViaPanelCenterMode(DisplayModePtr mode, DisplayModePtr adjusted_mode)
+{
+ int panelHSyncTime = adjusted_mode->HSyncEnd - adjusted_mode->HSyncStart;
+ int panelVSyncTime = adjusted_mode->VSyncEnd - adjusted_mode->VSyncStart;
+ int panelHBlankStart = adjusted_mode->HDisplay;
+ int panelVBlankStart = adjusted_mode->VDisplay;
+ int hBorder = (adjusted_mode->HDisplay - mode->HDisplay)/2;
+ int vBorder = (adjusted_mode->VDisplay - mode->VDisplay)/2;
+ int newHBlankStart = hBorder + mode->HDisplay;
+ int newVBlankStart = vBorder + mode->VDisplay;
+
+ adjusted_mode->HDisplay = mode->HDisplay;
+ adjusted_mode->HSyncStart = (adjusted_mode->HSyncStart - panelHBlankStart) + newHBlankStart;
+ adjusted_mode->HSyncEnd = adjusted_mode->HSyncStart + panelHSyncTime;
+ adjusted_mode->VDisplay = mode->VDisplay;
+ adjusted_mode->VSyncStart = (adjusted_mode->VSyncStart - panelVBlankStart) + newVBlankStart;
+ adjusted_mode->VSyncEnd = adjusted_mode->VSyncStart + panelVSyncTime;
+ /* Adjust Crtc H and V */
+ adjusted_mode->CrtcHDisplay = adjusted_mode->HDisplay;
+ adjusted_mode->CrtcHBlankStart = newHBlankStart;
+ adjusted_mode->CrtcHBlankEnd = adjusted_mode->CrtcHTotal - hBorder;
+ adjusted_mode->CrtcHSyncStart = adjusted_mode->HSyncStart;
+ adjusted_mode->CrtcHSyncEnd = adjusted_mode->HSyncEnd;
+ adjusted_mode->CrtcVDisplay = adjusted_mode->VDisplay;
+ adjusted_mode->CrtcVBlankStart = newVBlankStart;
+ adjusted_mode->CrtcVBlankEnd = adjusted_mode->CrtcVTotal - vBorder;
+ adjusted_mode->CrtcVSyncStart = adjusted_mode->VSyncStart;
+ adjusted_mode->CrtcVSyncEnd = adjusted_mode->VSyncEnd;
+}
+
static Bool
via_lvds_mode_fixup(xf86OutputPtr output, DisplayModePtr mode,
DisplayModePtr adjusted_mode)
{
+ ViaPanelInfoPtr Panel = output->driver_private;
+ ScrnInfoPtr pScrn = output->scrn;
+ VIAPtr pVia = VIAPTR(pScrn);
+
+ xf86SetModeCrtc(adjusted_mode, 0);
+ if (!Panel->Center && (mode->HDisplay < Panel->NativeWidth ||
+ mode->VDisplay < Panel->NativeHeight)) {
+ Panel->Scale = TRUE;
+ } else {
+ Panel->Scale = FALSE;
+ ViaPanelCenterMode(mode, adjusted_mode);
+ }
return TRUE;
}
@@ -885,8 +927,8 @@ VIASetLCDMode(xf86OutputPtr output, DisplayModePtr mode)
ViaVgahwWrite(hwp, 0x300 + port, offset, 0x301 + port, data);
}
- if ((mode->CrtcHDisplay != Panel->NativeMode->Width)
- || (mode->CrtcVDisplay != Panel->NativeMode->Height)) {
+ if ((mode->CrtcHDisplay != Panel->NativeWidth) ||
+ (mode->CrtcVDisplay != Panel->NativeHeight)) {
VIALCDModeEntryPtr Main;
VIALCDMPatchEntryPtr Patch1, Patch2;
int numPatch1, numPatch2;
@@ -981,7 +1023,7 @@ VIASetLCDMode(xf86OutputPtr output, DisplayModePtr mode)
/* Set LCD Mode patch registers. */
for (i = 0; i < numPatch2; i++, Patch2++) {
if (Patch2->Mode == modeNum) {
- if (!Panel->Center && (mode->CrtcHDisplay == Panel->NativeMode->Width))
+ if (!Panel->Center && (mode->CrtcHDisplay == Panel->NativeWidth))
Panel->scaleY = FALSE;
for (j = 0; j < Patch2->numEntry; j++) {
@@ -1064,29 +1106,6 @@ VIASetLCDMode(xf86OutputPtr output, DisplayModePtr mode)
}
static void
-ViaPanelCenterMode(DisplayModePtr centerMode, DisplayModePtr panelMode,
- DisplayModePtr mode)
-{
- memcpy(centerMode, mode, sizeof(DisplayModeRec));
-
- CARD32 HDiff = (panelMode->CrtcHDisplay - mode->CrtcHDisplay) / 2;
- CARD32 VDiff = (panelMode->CrtcVDisplay - mode->CrtcVDisplay) / 2;
-
- centerMode->CrtcHTotal += HDiff * 2;
- centerMode->CrtcVTotal += VDiff * 2;
-
- centerMode->CrtcHSyncStart += HDiff;
- centerMode->CrtcHSyncEnd += HDiff;
- centerMode->CrtcHBlankStart += HDiff;
- centerMode->CrtcHBlankEnd += HDiff;
-
- centerMode->CrtcVSyncStart += VDiff;
- centerMode->CrtcVSyncEnd += VDiff;
- centerMode->CrtcVBlankStart += VDiff;
- centerMode->CrtcVBlankEnd += VDiff;
-}
-
-static void
ViaPanelScale(ScrnInfoPtr pScrn, int resWidth, int resHeight,
int panelWidth, int panelHeight)
{
@@ -1232,26 +1251,12 @@ via_lvds_mode_set(xf86OutputPtr output, DisplayModePtr mode,
VIABIOSInfoPtr pBIOSInfo = pVia->pBIOSInfo;
if (!pVia->UseLegacyModeSwitch) {
- DisplayModePtr nativeDisplayMode = Panel->NativeDisplayMode;
- DisplayModePtr centeredMode = Panel->CenteredMode;
- DisplayModePtr realMode = adjusted_mode;
-
- if (nativeDisplayMode) {
+ if (Panel->Scale) {
ViaPanelScale(pScrn, mode->HDisplay, mode->VDisplay,
- nativeDisplayMode->HDisplay,
- nativeDisplayMode->VDisplay);
- if (!Panel->Center &&
- (mode->HDisplay < nativeDisplayMode->HDisplay ||
- mode->VDisplay < nativeDisplayMode->VDisplay)) {
- Panel->Scale = TRUE;
- realMode = nativeDisplayMode;
- } else {
- Panel->Scale = FALSE;
- ViaPanelCenterMode(centeredMode, nativeDisplayMode, mode);
- realMode = centeredMode;
- ViaPanelScaleDisable(pScrn);
- }
- }
+ Panel->NativeWidth,
+ Panel->NativeHeight);
+ } else
+ ViaPanelScaleDisable(pScrn);
} else {
xf86CrtcPtr crtc = output->crtc;
drmmode_crtc_private_ptr iga = crtc->driver_private;
@@ -1300,7 +1305,7 @@ via_lvds_detect(xf86OutputPtr output)
if (!pVia->UseLegacyModeSwitch) {
/* First try to get the mode from EDID. */
- if (!panel->NativeMode->Width || !panel->NativeMode->Height) {
+ if (!panel->NativeWidth || !panel->NativeHeight) {
int width, height;
Bool ret;
@@ -1309,8 +1314,8 @@ via_lvds_detect(xf86OutputPtr output)
panel->NativeModeIndex = ViaPanelLookUpModeIndex(width, height);
DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "ViaPanelLookUpModeIndex, Width %d, Height %d, NativeModeIndex%d\n", width, height, panel->NativeModeIndex));
if (panel->NativeModeIndex != VIA_PANEL_INVALID) {
- panel->NativeMode->Width = width;
- panel->NativeMode->Height = height;
+ panel->NativeWidth = width;
+ panel->NativeHeight = height;
status = XF86OutputStatusConnected;
}
} else {
@@ -1325,45 +1330,45 @@ via_lvds_detect(xf86OutputPtr output)
if ((((CR6A & 0xC0) == 0xC0) || (((CR6A & 0xC0) == 0x40) &&
(CR6B & 0x08))) && (CR97 & 0x10) && (CR99 & 0x10)) {
/* Use Vertical addreess register of IGA 2 */
- panel->NativeMode->Width = (hwp->readCrtc(hwp, 0x51) |
+ panel->NativeWidth = (hwp->readCrtc(hwp, 0x51) |
((hwp->readCrtc(hwp, 0x55) & 0x70) << 4)) + 1;
- panel->NativeMode->Height = (hwp->readCrtc(hwp, 0x59) |
+ panel->NativeHeight = (hwp->readCrtc(hwp, 0x59) |
((hwp->readCrtc(hwp, 0x5D) & 0x38) << 5)) + 1;
panel->NativeModeIndex = VIA_PANEL6X4;
xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Panel Mode probed %dx%d from IGA 2\n",
- panel->NativeMode->Width, panel->NativeMode->Height);
+ panel->NativeWidth, panel->NativeHeight);
status = XF86OutputStatusConnected;
} else if (!(CR97 & 0x10) && !(CR99 & 0x10)) {
CARD8 val;
/* IGA1 Horizontal Overscan register */
- panel->NativeMode->Width = (hwp->readCrtc(hwp, 0x01) + 1) * 8;
+ panel->NativeWidth = (hwp->readCrtc(hwp, 0x01) + 1) * 8;
/* IGA1 default Vertical Overscan register is
* incorrect on some devices so use VBlank start */
- panel->NativeMode->Height = (hwp->readCrtc(hwp, 0x15) + 1);
+ panel->NativeHeight = (hwp->readCrtc(hwp, 0x15) + 1);
val = hwp->readCrtc(hwp, 0x07);
- panel->NativeMode->Height |= ((val >> 3) & 0x1) << 8;
- panel->NativeMode->Height |= ((val >> 5) & 0x1) << 9;
+ panel->NativeHeight |= ((val >> 3) & 0x1) << 8;
+ panel->NativeHeight |= ((val >> 5) & 0x1) << 9;
val = hwp->readCrtc(hwp, 0x35);
- panel->NativeMode->Height |= ((val >> 3) & 0x1) << 10;
+ panel->NativeHeight |= ((val >> 3) & 0x1) << 10;
panel->NativeModeIndex = VIA_PANEL6X4;
xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Panel Mode probed %dx%d from IGA 1\n",
- panel->NativeMode->Width,
- panel->NativeMode->Height);
+ panel->NativeWidth,
+ panel->NativeHeight);
status = XF86OutputStatusConnected;
}
- if (!panel->NativeMode->Width || !panel->NativeMode->Height)
+ if (!panel->NativeWidth || !panel->NativeHeight)
ViaPanelGetNativeModeFromScratchPad(output);
- if (panel->NativeMode->Width && panel->NativeMode->Height)
+ if (panel->NativeWidth && panel->NativeHeight)
status = XF86OutputStatusConnected;
}
DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "NativeMode: %d %d\n",
- panel->NativeMode->Width, panel->NativeMode->Height));
+ panel->NativeWidth, panel->NativeHeight));
} else
status = XF86OutputStatusConnected;
} else
@@ -1384,10 +1389,9 @@ via_lvds_get_modes(xf86OutputPtr output)
* Generates a display mode for the native panel resolution,
* using CVT.
*/
- if (Panel->NativeMode->Width && Panel->NativeMode->Height) {
- p = xf86CVTMode(Panel->NativeMode->Width,
- Panel->NativeMode->Height,
- 60.0f, FALSE, FALSE);
+ if (Panel->NativeWidth && Panel->NativeHeight) {
+ p = xf86CVTMode(Panel->NativeWidth, Panel->NativeHeight,
+ 60.0f, FALSE, FALSE);
if (p) {
p->CrtcHDisplay = p->HDisplay;
p->CrtcHSyncStart = p->HSyncStart;
@@ -1404,8 +1408,6 @@ via_lvds_get_modes(xf86OutputPtr output)
p->CrtcHBlankStart = min(p->CrtcHSyncStart, p->CrtcHDisplay);
p->CrtcHBlankEnd = max(p->CrtcHSyncEnd, p->CrtcHTotal);
p->type = M_T_DRIVER | M_T_PREFERRED;
-
- Panel->NativeDisplayMode = p;
} else {
xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
"Out of memory. Size: %d bytes\n", sizeof(DisplayModeRec));
@@ -1413,11 +1415,11 @@ via_lvds_get_modes(xf86OutputPtr output)
} else {
xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
"Invalid panel dimension (%dx%d)\n",
- Panel->NativeMode->Width,
- Panel->NativeMode->Height);
+ Panel->NativeWidth, Panel->NativeHeight);
}
- } else
+ } else {
p = xf86OutputGetEDIDModes(output);
+ }
}
return p;
}
@@ -1425,15 +1427,8 @@ via_lvds_get_modes(xf86OutputPtr output)
static void
via_lvds_destroy(xf86OutputPtr output)
{
- ViaPanelInfoPtr Panel = output->driver_private;
-
- if (Panel) {
- if (Panel->NativeMode)
- free(Panel->NativeMode);
- if (Panel->CenteredMode)
- free(Panel->CenteredMode);
- free(Panel);
- }
+ if (output->driver_private)
+ free(output->driver_private);
output->driver_private = NULL;
}
@@ -1475,8 +1470,8 @@ ViaPanelGetNativeModeFromOption(ScrnInfoPtr pScrn, ViaPanelInfoPtr panel, char *
ViaPanelNativeModes[index].Height);
if (!xf86NameCmp(name, aux)) {
panel->NativeModeIndex = index;
- panel->NativeMode->Width = ViaPanelNativeModes[index].Width;
- panel->NativeMode->Height = ViaPanelNativeModes[index].Height;
+ panel->NativeWidth = ViaPanelNativeModes[index].Width;
+ panel->NativeHeight = ViaPanelNativeModes[index].Height;
break;
}
}
@@ -1498,22 +1493,10 @@ via_lvds_init(ScrnInfoPtr pScrn)
if (!Panel)
return;
- Panel->NativeModeIndex = VIA_PANEL_INVALID;
- Panel->NativeMode = (ViaPanelModePtr) xnfcalloc(sizeof(ViaPanelModeRec), 1);
- if (!Panel->NativeMode) {
- free(Panel);
- return;
- }
- Panel->CenteredMode = (DisplayModePtr) xnfcalloc(sizeof(DisplayModeRec), 1);
- if (!Panel->CenteredMode) {
- free(Panel->NativeMode);
- free(Panel);
- return;
- }
-
memcpy(Options, ViaPanelOptions, sizeof(ViaPanelOptions));
xf86ProcessOptions(pScrn->scrnIndex, pScrn->options, Options);
+ Panel->NativeModeIndex = VIA_PANEL_INVALID;
Panel->BusWidth = VIA_DI_12BIT;
if ((s = xf86GetOptValString(Options, OPTION_BUSWIDTH))) {
from = X_CONFIG;
@@ -1545,14 +1528,12 @@ via_lvds_init(ScrnInfoPtr pScrn)
if ((s = xf86GetOptValString(Options, OPTION_PANELSIZE))) {
ViaPanelGetNativeModeFromOption(pScrn, Panel, s);
if (Panel->NativeModeIndex != VIA_PANEL_INVALID) {
- ViaPanelModePtr mode = Panel->NativeMode;
-
DEBUG(xf86DrvMsg
(pScrn->scrnIndex, X_CONFIG, "LVDS Panel mode index is %d\n",
Panel->NativeModeIndex));
xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
- "Selected Panel Size is %dx%d\n", mode->Width,
- mode->Height);
+ "Selected Panel Size is %dx%d\n", Panel->NativeWidth,
+ Panel->NativeHeight);
} else
xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
"%s is not a valid panel size.\n", s);
@@ -1582,8 +1563,6 @@ via_lvds_init(ScrnInfoPtr pScrn)
output->doubleScanAllowed = FALSE;
pBIOSInfo->lvds = output;
} else {
- free(Panel->CenteredMode);
- free(Panel->NativeMode);
free(Panel);
}
}
diff --git a/src/via_ums.h b/src/via_ums.h
index 4f273d5..facab5c 100644
--- a/src/via_ums.h
+++ b/src/via_ums.h
@@ -120,14 +120,11 @@ typedef struct ViaPanelMode {
typedef struct ViaPanelInfo {
Bool IsActive ;
- /* current native resolution */
- ViaPanelModePtr NativeMode ;
+ /* Native physical resolution */
+ int NativeHeight;
+ int NativeWidth;
/* Native resolution index, see via_panel.c */
CARD8 NativeModeIndex;
- /* Generated mode for native resolution */
- DisplayModePtr NativeDisplayMode ;
- /* Current mode but centered */
- DisplayModePtr CenteredMode ;
/* Determine if we must use the hardware scaler
* It might be false even if the "Center" option
* was specified