diff options
author | Aaron Plattner <aplattner@nvidia.com> | 2007-04-13 22:29:57 -0700 |
---|---|---|
committer | Aaron Plattner <aplattner@nvidia.com> | 2007-04-13 22:29:57 -0700 |
commit | f1cda5eaba9cbbfeb913d249d014586a6e8fd7a6 (patch) | |
tree | a3c57764e7a3a3ea380a78432b16d32c5df5ae6f | |
parent | 550af781bd9f7cb7256b298281c2c27febfc4722 (diff) |
G80: Get DPMS working with RandR 1.2.
Work around xf86DisableUnusedFunctions lameness by forcing DPMSModeOn at modeset
time.
-rw-r--r-- | src/g80_dac.c | 41 | ||||
-rw-r--r-- | src/g80_display.c | 52 | ||||
-rw-r--r-- | src/g80_sor.c | 25 |
3 files changed, 62 insertions, 56 deletions
diff --git a/src/g80_dac.c b/src/g80_dac.c index ac82616..e536ef7 100644 --- a/src/g80_dac.c +++ b/src/g80_dac.c @@ -27,6 +27,9 @@ #include <unistd.h> +#define DPMS_SERVER +#include <X11/extensions/dpms.h> + #include "g80_type.h" #include "g80_display.h" #include "g80_output.h" @@ -44,7 +47,33 @@ G80DacSetPClk(xf86OutputPtr output, int pclk) static void G80DacDPMSSet(xf86OutputPtr output, int mode) { - ErrorF("DAC dpms unimplemented\n"); + G80Ptr pNv = G80PTR(output->scrn); + G80OutputPrivPtr pPriv = output->driver_private; + const int off = 0x800 * pPriv->or; + CARD32 tmp; + + /* + * DPMSModeOn everything on + * DPMSModeStandby hsync disabled, vsync enabled + * DPMSModeSuspend hsync enabled, vsync disabled + * DPMSModeOff sync disabled + */ + while(pNv->reg[(0x0061A004+off)/4] & 0x80000000); + + tmp = pNv->reg[(0x0061A004+off)/4]; + tmp &= ~0x7f; + tmp |= 0x80000000; + + if(mode == DPMSModeStandby || mode == DPMSModeOff) + tmp |= 1; + if(mode == DPMSModeSuspend || mode == DPMSModeOff) + tmp |= 4; + if(mode != DPMSModeOn) + tmp |= 0x10; + if(mode == DPMSModeOff) + tmp |= 0x40; + + pNv->reg[(0x0061A004+off)/4] = tmp; } static void @@ -63,6 +92,11 @@ G80DacModeSet(xf86OutputPtr output, DisplayModePtr mode, return; } + // This wouldn't be necessary, but the server is stupid and calls + // G80DacDPMSSet after the output is disconnected, even though the hardware + // turns it off automatically. + G80DacDPMSSet(output, DPMSModeOn); + C(0x00000400 + dacOff, (G80CrtcGetHead(output->crtc) == HEAD0 ? 1 : 2) | 0x40); C(0x00000404 + dacOff, @@ -94,12 +128,13 @@ G80DacLoadDetect(xf86OutputPtr output) G80OutputPrivPtr pPriv = output->driver_private; const int scrnIndex = pScrn->scrnIndex; const int dacOff = 2048 * pPriv->or; - CARD32 load, tmp; + CARD32 load, tmp, tmp2; xf86DrvMsg(scrnIndex, X_PROBED, "Trying load detection on VGA%i ... ", pPriv->or); pNv->reg[(0x0061A010+dacOff)/4] = 0x00000001; + tmp2 = pNv->reg[(0x0061A004+dacOff)/4]; pNv->reg[(0x0061A004+dacOff)/4] = 0x80150000; while(pNv->reg[(0x0061A004+dacOff)/4] & 0x80000000); tmp = pNv->architecture == 0x50 ? 420 : 340; @@ -107,7 +142,7 @@ G80DacLoadDetect(xf86OutputPtr output) usleep(4500); load = pNv->reg[(0x0061A00C+dacOff)/4]; pNv->reg[(0x0061A00C+dacOff)/4] = 0; - pNv->reg[(0x0061A004+dacOff)/4] = 0x80550000; + pNv->reg[(0x0061A004+dacOff)/4] = 0x80000000 | tmp2; // Use this DAC if all three channels show load. if((load & 0x38000000) == 0x38000000) { diff --git a/src/g80_display.c b/src/g80_display.c index a5a1bc8..d7f52dd 100644 --- a/src/g80_display.c +++ b/src/g80_display.c @@ -36,9 +36,6 @@ #include "g80_display.h" #include "g80_output.h" -#define DPMS_SERVER -#include <X11/extensions/dpms.h> - typedef struct G80CrtcPrivRec { Head head; int pclk; /* Target pixel clock in kHz */ @@ -423,55 +420,6 @@ G80CrtcBlankScreen(xf86CrtcPtr crtc, Bool blank) void G80CrtcDPMSSet(xf86CrtcPtr crtc, int mode) { - ErrorF("CRTC dpms unimplemented\n"); -#if 0 - G80Ptr pNv = G80PTR(pScrn); - const int off = 0x800 * pNv->or; - CARD32 tmp; - - /* - * DPMSModeOn everything on - * DPMSModeStandby hsync disabled, vsync enabled - * DPMSModeSuspend hsync enabled, vsync disabled - * DPMSModeOff sync disabled - */ - switch(pNv->orType) { - case DAC: - while(pNv->reg[(0x0061A004+off)/4] & 0x80000000); - - tmp = pNv->reg[(0x0061A004+off)/4]; - tmp &= ~0x7f; - tmp |= 0x80000000; - - if(mode == DPMSModeStandby || mode == DPMSModeOff) - tmp |= 1; - if(mode == DPMSModeSuspend || mode == DPMSModeOff) - tmp |= 4; - if(mode != DPMSModeOn) - tmp |= 0x10; - if(mode == DPMSModeOff) - tmp |= 0x40; - - pNv->reg[(0x0061A004+off)/4] = tmp; - - break; - - case SOR: - while(pNv->reg[(0x0061C004+off)/4] & 0x80000000); - - tmp = pNv->reg[(0x0061C004+off)/4]; - tmp |= 0x80000000; - - if(mode == DPMSModeOn) - tmp |= 1; - else - tmp &= ~1; - - pNv->reg[(0x0061C004+off)/4] = tmp; - - break; - } -#endif } /******************************** Cursor stuff ********************************/ diff --git a/src/g80_sor.c b/src/g80_sor.c index 74bccb0..5187d1f 100644 --- a/src/g80_sor.c +++ b/src/g80_sor.c @@ -25,6 +25,9 @@ #include "config.h" #endif +#define DPMS_SERVER +#include <X11/extensions/dpms.h> + #include "g80_type.h" #include "g80_display.h" #include "g80_output.h" @@ -42,7 +45,22 @@ G80SorSetPClk(xf86OutputPtr output, int pclk) static void G80SorDPMSSet(xf86OutputPtr output, int mode) { - ErrorF("SOR dpms unimplemented\n"); + G80Ptr pNv = G80PTR(output->scrn); + G80OutputPrivPtr pPriv = output->driver_private; + const int off = 0x800 * pPriv->or; + CARD32 tmp; + + while(pNv->reg[(0x0061C004+off)/4] & 0x80000000); + + tmp = pNv->reg[(0x0061C004+off)/4]; + tmp |= 0x80000000; + + if(mode == DPMSModeOn) + tmp |= 1; + else + tmp &= ~1; + + pNv->reg[(0x0061C004+off)/4] = tmp; } static void @@ -62,6 +80,11 @@ G80SorModeSet(xf86OutputPtr output, DisplayModePtr mode, return; } + // This wouldn't be necessary, but the server is stupid and calls + // G80SorDPMSSet after the output is disconnected, even though the hardware + // turns it off automatically. + G80SorDPMSSet(output, DPMSModeOn); + C(0x00000600 + sorOff, (G80CrtcGetHead(output->crtc) == HEAD0 ? 1 : 2) | (adjusted_mode->Clock > 165000 ? 0x500 : 0x100) | |