diff options
author | Aaron Plattner <aplattner@nvidia.com> | 2007-07-24 20:36:04 -0700 |
---|---|---|
committer | Aaron Plattner <aaron@weasel.nvidia.com> | 2007-07-24 20:36:04 -0700 |
commit | 08b68473351081fe1ed96ba7e206ed0d301b8a91 (patch) | |
tree | daa06fca777bb68abb66d8b124d0c533edc5109f /src/g80_display.c | |
parent | f0ebb42ee94eac4b294d12d02f4406a444b347ff (diff) |
G80: Allow DVI scaling.
Revamp how the scaling code works. When a mode is set on a DVI output,
determine the current preferred mode and scale to that. Add a new scaling
option, "off", which disables scaling and scans out the actual timings in the
mode to be set.
Diffstat (limited to 'src/g80_display.c')
-rw-r--r-- | src/g80_display.c | 46 |
1 files changed, 22 insertions, 24 deletions
diff --git a/src/g80_display.c b/src/g80_display.c index 14352aa..542a68e 100644 --- a/src/g80_display.c +++ b/src/g80_display.c @@ -42,7 +42,6 @@ typedef struct G80CrtcPrivRec { Bool cursorVisible; Bool skipModeFixup; Bool dither; - enum G80ScaleMode scale; } G80CrtcPrivRec, *G80CrtcPrivPtr; static void G80CrtcShowHideCursor(xf86CrtcPtr crtc, Bool show, Bool update); @@ -307,31 +306,35 @@ G80DispShutdown(ScrnInfoPtr pScrn) while((pNv->reg[0x61C830/4] & 0x10000000)); } +void +G80CrtcDoModeFixup(DisplayModePtr dst, const DisplayModePtr src) +{ + /* Magic mode timing fudge factor */ + const int fudge = ((src->Flags & V_INTERLACE) && (src->Flags & V_DBLSCAN)) ? 2 : 1; + const int interlaceDiv = (src->Flags & V_INTERLACE) ? 2 : 1; + + /* Stash the src timings in the Crtc fields in dst */ + dst->CrtcHBlankStart = src->CrtcVTotal << 16 | src->CrtcHTotal; + dst->CrtcHSyncEnd = ((src->CrtcVSyncEnd - src->CrtcVSyncStart) / interlaceDiv - 1) << 16 | + (src->CrtcHSyncEnd - src->CrtcHSyncStart - 1); + dst->CrtcHBlankEnd = ((src->CrtcVBlankEnd - src->CrtcVSyncStart) / interlaceDiv - fudge) << 16 | + (src->CrtcHBlankEnd - src->CrtcHSyncStart - 1); + dst->CrtcHTotal = ((src->CrtcVTotal - src->CrtcVSyncStart + src->CrtcVBlankStart) / interlaceDiv - fudge) << 16 | + (src->CrtcHTotal - src->CrtcHSyncStart + src->CrtcHBlankStart - 1); + dst->CrtcHSkew = ((src->CrtcVTotal + src->CrtcVBlankEnd - src->CrtcVSyncStart) / 2 - 2) << 16 | + ((2*src->CrtcVTotal - src->CrtcVSyncStart + src->CrtcVBlankStart) / 2 - 2); +} + static Bool G80CrtcModeFixup(xf86CrtcPtr crtc, DisplayModePtr mode, DisplayModePtr adjusted_mode) { G80CrtcPrivPtr pPriv = crtc->driver_private; - int interlaceDiv, fudge; if(pPriv->skipModeFixup) return TRUE; - /* Magic mode timing fudge factor */ - fudge = ((adjusted_mode->Flags & V_INTERLACE) && (adjusted_mode->Flags & V_DBLSCAN)) ? 2 : 1; - interlaceDiv = (adjusted_mode->Flags & V_INTERLACE) ? 2 : 1; - - /* Stash the mode timings in the Crtc fields in adjusted_mode */ - adjusted_mode->CrtcHBlankStart = mode->CrtcVTotal << 16 | mode->CrtcHTotal; - adjusted_mode->CrtcHSyncEnd = ((mode->CrtcVSyncEnd - mode->CrtcVSyncStart) / interlaceDiv - 1) << 16 | - (mode->CrtcHSyncEnd - mode->CrtcHSyncStart - 1); - adjusted_mode->CrtcHBlankEnd = ((mode->CrtcVBlankEnd - mode->CrtcVSyncStart) / interlaceDiv - fudge) << 16 | - (mode->CrtcHBlankEnd - mode->CrtcHSyncStart - 1); - adjusted_mode->CrtcHTotal = ((mode->CrtcVTotal - mode->CrtcVSyncStart + mode->CrtcVBlankStart) / interlaceDiv - fudge) << 16 | - (mode->CrtcHTotal - mode->CrtcHSyncStart + mode->CrtcHBlankStart - 1); - adjusted_mode->CrtcHSkew = ((mode->CrtcVTotal + mode->CrtcVBlankEnd - mode->CrtcVSyncStart) / 2 - 2) << 16 | - ((2*mode->CrtcVTotal - mode->CrtcVSyncStart + mode->CrtcVBlankStart) / 2 - 2); - + G80CrtcDoModeFixup(adjusted_mode, mode); return TRUE; } @@ -365,7 +368,6 @@ G80CrtcModeSet(xf86CrtcPtr crtc, DisplayModePtr mode, case 24: C(0x00000870 + headOff, 0xCF00); break; } G80CrtcSetDither(crtc, pPriv->dither, FALSE); - G80CrtcSetScale(crtc, adjusted_mode, pPriv->scale, FALSE); C(0x000008A8 + headOff, 0x40000); C(0x000008C0 + headOff, y << 16 | x); C(0x000008C8 + headOff, VDisplay << 16 | HDisplay); @@ -504,20 +506,19 @@ static void ComputeAspectScale(DisplayModePtr mode, int *outX, int *outY) } void G80CrtcSetScale(xf86CrtcPtr crtc, DisplayModePtr mode, - enum G80ScaleMode scale, Bool update) + enum G80ScaleMode scale) { ScrnInfoPtr pScrn = crtc->scrn; G80CrtcPrivPtr pPriv = crtc->driver_private; const int headOff = 0x400 * pPriv->head; int outX, outY; - pPriv->scale = scale; - switch(scale) { case G80_SCALE_ASPECT: ComputeAspectScale(mode, &outX, &outY); break; + case G80_SCALE_OFF: case G80_SCALE_FILL: outX = mode->CrtcHDisplay; outY = mode->CrtcVDisplay; @@ -537,8 +538,6 @@ void G80CrtcSetScale(xf86CrtcPtr crtc, DisplayModePtr mode, } C(0x000008D8 + headOff, outY << 16 | outX); C(0x000008DC + headOff, outY << 16 | outX); - - if(update) C(0x00000080, 0); } static void @@ -600,7 +599,6 @@ G80DispCreateCrtcs(ScrnInfoPtr pScrn) g80_crtc = xnfcalloc(sizeof(*g80_crtc), 1); g80_crtc->head = head; g80_crtc->dither = pNv->Dither; - g80_crtc->scale = G80_SCALE_ASPECT; crtc->driver_private = g80_crtc; } } |