summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/g80_display.c87
-rw-r--r--src/g80_display.h1
-rw-r--r--src/g80_sor.c7
3 files changed, 56 insertions, 39 deletions
diff --git a/src/g80_display.c b/src/g80_display.c
index 652a5a9..d10f2d6 100644
--- a/src/g80_display.c
+++ b/src/g80_display.c
@@ -40,6 +40,7 @@ typedef struct G80CrtcPrivRec {
Head head;
int pclk; /* Target pixel clock in kHz */
Bool cursorVisible;
+ Bool skipModeFixup;
} G80CrtcPrivRec, *G80CrtcPrivPtr;
static void G80CrtcShowHideCursor(xf86CrtcPtr crtc, Bool show, Bool update);
@@ -234,14 +235,6 @@ G80DispPreInit(ScrnInfoPtr pScrn)
pNv->reg[0x006101D8/4] = pNv->reg[0x0061B000/4];
pNv->reg[0x006101E0/4] = pNv->reg[0x0061C000/4];
pNv->reg[0x006101E4/4] = pNv->reg[0x0061C800/4];
- pNv->reg[0x0061c00c/4] = 0x03010700;
- pNv->reg[0x0061c010/4] = 0x0000152f;
- pNv->reg[0x0061c014/4] = 0x00000000;
- pNv->reg[0x0061c018/4] = 0x00245af8;
- pNv->reg[0x0061c80c/4] = 0x03010700;
- pNv->reg[0x0061c810/4] = 0x0000152f;
- pNv->reg[0x0061c814/4] = 0x00000000;
- pNv->reg[0x0061c818/4] = 0x00245af8;
pNv->reg[0x0061A004/4] = 0x80550000;
pNv->reg[0x0061A010/4] = 0x00000001;
pNv->reg[0x0061A804/4] = 0x80550000;
@@ -308,13 +301,35 @@ G80DispShutdown(ScrnInfoPtr pScrn)
pNv->reg[0x00610200/4] = 0;
pNv->reg[0x00610300/4] = 0;
while((pNv->reg[0x00610200/4] & 0x1e0000) != 0);
+ while((pNv->reg[0x61C030/4] & 0x10000000));
+ while((pNv->reg[0x61C830/4] & 0x10000000));
}
static Bool
G80CrtcModeFixup(xf86CrtcPtr crtc,
DisplayModePtr mode, DisplayModePtr adjusted_mode)
{
- // TODO: Fix up the mode here
+ 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);
+
return TRUE;
}
@@ -324,36 +339,21 @@ G80CrtcModeSet(xf86CrtcPtr crtc, DisplayModePtr mode,
{
ScrnInfoPtr pScrn = crtc->scrn;
G80CrtcPrivPtr pPriv = crtc->driver_private;
- const int HDisplay = mode->HDisplay, VDisplay = mode->VDisplay;
+ const int HDisplay = adjusted_mode->HDisplay, VDisplay = adjusted_mode->VDisplay;
const int headOff = 0x400 * G80CrtcGetHead(crtc);
- int interlaceDiv, fudge;
- // TODO: Use adjusted_mode and fix it up in G80CrtcModeFixup
- pPriv->pclk = mode->Clock;
-
- /* Magic mode timing fudge factor */
- fudge = ((mode->Flags & V_INTERLACE) && (mode->Flags & V_DBLSCAN)) ? 2 : 1;
- interlaceDiv = (mode->Flags & V_INTERLACE) ? 2 : 1;
+ pPriv->pclk = adjusted_mode->Clock;
- C(0x00000804 + headOff, mode->Clock | 0x800000);
- C(0x00000808 + headOff, (mode->Flags & V_INTERLACE) ? 2 : 0);
+ C(0x00000804 + headOff, adjusted_mode->Clock | 0x800000);
+ C(0x00000808 + headOff, (adjusted_mode->Flags & V_INTERLACE) ? 2 : 0);
C(0x00000810 + headOff, 0);
C(0x0000082C + headOff, 0);
- C(0x00000814 + headOff, mode->CrtcVTotal << 16 | mode->CrtcHTotal);
- C(0x00000818 + headOff,
- ((mode->CrtcVSyncEnd - mode->CrtcVSyncStart) / interlaceDiv - 1) << 16 |
- (mode->CrtcHSyncEnd - mode->CrtcHSyncStart - 1));
- C(0x0000081C + headOff,
- ((mode->CrtcVBlankEnd - mode->CrtcVSyncStart) / interlaceDiv - fudge) << 16 |
- (mode->CrtcHBlankEnd - mode->CrtcHSyncStart - 1));
- C(0x00000820 + headOff,
- ((mode->CrtcVTotal - mode->CrtcVSyncStart + mode->CrtcVBlankStart) / interlaceDiv - fudge) << 16 |
- (mode->CrtcHTotal - mode->CrtcHSyncStart + mode->CrtcHBlankStart - 1));
- if(mode->Flags & V_INTERLACE) {
- C(0x00000824 + headOff,
- ((mode->CrtcVTotal + mode->CrtcVBlankEnd - mode->CrtcVSyncStart) / 2 - 2) << 16 |
- ((2*mode->CrtcVTotal - mode->CrtcVSyncStart + mode->CrtcVBlankStart) / 2 - 2));
- }
+ C(0x00000814 + headOff, adjusted_mode->CrtcHBlankStart);
+ C(0x00000818 + headOff, adjusted_mode->CrtcHSyncEnd);
+ C(0x0000081C + headOff, adjusted_mode->CrtcHBlankEnd);
+ C(0x00000820 + headOff, adjusted_mode->CrtcHTotal);
+ if(adjusted_mode->Flags & V_INTERLACE)
+ C(0x00000824 + headOff, adjusted_mode->CrtcHSkew);
C(0x00000868 + headOff, pScrn->virtualY << 16 | pScrn->virtualX);
C(0x0000086C + headOff, pScrn->displayWidth * (pScrn->bitsPerPixel / 8) | 0x100000);
switch(pScrn->depth) {
@@ -362,9 +362,8 @@ G80CrtcModeSet(xf86CrtcPtr crtc, DisplayModePtr mode,
case 16: C(0x00000870 + headOff, 0xE800); break;
case 24: C(0x00000870 + headOff, 0xCF00); break;
}
- C(0x000008A0 + headOff, 0);
- if((mode->Flags & V_DBLSCAN) || (mode->Flags & V_INTERLACE) ||
- mode->CrtcHDisplay != HDisplay || mode->CrtcVDisplay != VDisplay) {
+ if((adjusted_mode->Flags & V_DBLSCAN) || (adjusted_mode->Flags & V_INTERLACE) ||
+ adjusted_mode->CrtcHDisplay != HDisplay || adjusted_mode->CrtcVDisplay != VDisplay) {
C(0x000008A4 + headOff, 9);
} else {
C(0x000008A4 + headOff, 0);
@@ -373,8 +372,8 @@ G80CrtcModeSet(xf86CrtcPtr crtc, DisplayModePtr mode,
C(0x000008C0 + headOff, y << 16 | x);
C(0x000008C8 + headOff, VDisplay << 16 | HDisplay);
C(0x000008D4 + headOff, 0);
- C(0x000008D8 + headOff, mode->CrtcVDisplay << 16 | mode->CrtcHDisplay);
- C(0x000008DC + headOff, mode->CrtcVDisplay << 16 | mode->CrtcHDisplay);
+ C(0x000008D8 + headOff, adjusted_mode->CrtcVDisplay << 16 | adjusted_mode->CrtcHDisplay);
+ C(0x000008DC + headOff, adjusted_mode->CrtcVDisplay << 16 | adjusted_mode->CrtcHDisplay);
G80CrtcBlankScreen(crtc, FALSE);
}
@@ -458,6 +457,7 @@ static void
G80CrtcPrepare(xf86CrtcPtr crtc)
{
ScrnInfoPtr pScrn = crtc->scrn;
+ G80CrtcPrivPtr pPriv = crtc->driver_private;
xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
int i;
@@ -467,6 +467,15 @@ G80CrtcPrepare(xf86CrtcPtr crtc)
if(!output->crtc)
output->funcs->mode_set(output, NULL, NULL);
}
+
+ pPriv->skipModeFixup = FALSE;
+}
+
+void
+G80CrtcSkipModeFixup(xf86CrtcPtr crtc)
+{
+ G80CrtcPrivPtr pPriv = crtc->driver_private;
+ pPriv->skipModeFixup = TRUE;
}
static void
diff --git a/src/g80_display.h b/src/g80_display.h
index fac7877..d6f24f4 100644
--- a/src/g80_display.h
+++ b/src/g80_display.h
@@ -11,5 +11,6 @@ void G80CrtcBlankScreen(xf86CrtcPtr, Bool blank);
void G80CrtcEnableCursor(xf86CrtcPtr, Bool update);
void G80CrtcDisableCursor(xf86CrtcPtr, Bool update);
void G80CrtcSetCursorPosition(xf86CrtcPtr, int x, int y);
+void G80CrtcSkipModeFixup(xf86CrtcPtr);
void G80DispCreateCrtcs(ScrnInfoPtr pScrn);
diff --git a/src/g80_sor.c b/src/g80_sor.c
index 90119f0..ea7e015 100644
--- a/src/g80_sor.c
+++ b/src/g80_sor.c
@@ -129,13 +129,20 @@ static const xf86OutputFuncsRec G80SorOutputFuncs = {
xf86OutputPtr
G80CreateSor(ScrnInfoPtr pScrn, ORNum or)
{
+ G80Ptr pNv = G80PTR(pScrn);
G80OutputPrivPtr pPriv = xnfcalloc(sizeof(*pPriv), 1);
+ const int off = 0x800 * or;
xf86OutputPtr output;
char orName[5];
if(!pPriv)
return FALSE;
+ pNv->reg[(0x61C00C+off)/4] = 0x03010700;
+ pNv->reg[(0x61C010+off)/4] = 0x0000152f;
+ pNv->reg[(0x61C014+off)/4] = 0x00000000;
+ pNv->reg[(0x61C018+off)/4] = 0x00245af8;
+
snprintf(orName, 5, "DVI%i", or);
output = xf86OutputCreate(pScrn, &G80SorOutputFuncs, orName);