diff options
-rw-r--r-- | src/Makefile.am | 12 | ||||
-rw-r--r-- | src/i2c_vid.h | 16 | ||||
-rw-r--r-- | src/local_xf86Rename.h | 23 | ||||
-rw-r--r-- | src/nv50_cursor.c | 104 | ||||
-rw-r--r-- | src/nv50_cursor.h | 12 | ||||
-rw-r--r-- | src/nv50_dac.c | 199 | ||||
-rw-r--r-- | src/nv50_display.c | 535 | ||||
-rw-r--r-- | src/nv50_display.h | 22 | ||||
-rw-r--r-- | src/nv50_exa.c | 254 | ||||
-rw-r--r-- | src/nv50_output.c | 372 | ||||
-rw-r--r-- | src/nv50_output.h | 34 | ||||
-rw-r--r-- | src/nv50_sor.c | 152 | ||||
-rw-r--r-- | src/nv50_type.h | 22 | ||||
-rw-r--r-- | src/nv_accel_common.c | 82 | ||||
-rw-r--r-- | src/nv_bios.c | 90 | ||||
-rw-r--r-- | src/nv_crtc.c | 1436 | ||||
-rw-r--r-- | src/nv_cursor.c | 76 | ||||
-rw-r--r-- | src/nv_dac.c | 425 | ||||
-rw-r--r-- | src/nv_dma.c | 81 | ||||
-rw-r--r-- | src/nv_dma.h | 2 | ||||
-rw-r--r-- | src/nv_driver.c | 3719 | ||||
-rw-r--r-- | src/nv_exa.c | 46 | ||||
-rw-r--r-- | src/nv_hw.c | 439 | ||||
-rw-r--r-- | src/nv_i2c.c | 70 | ||||
-rw-r--r-- | src/nv_include.h | 2 | ||||
-rw-r--r-- | src/nv_local.h | 27 | ||||
-rw-r--r-- | src/nv_output.c | 885 | ||||
-rw-r--r-- | src/nv_proto.h | 63 | ||||
-rw-r--r-- | src/nv_setup.c | 146 | ||||
-rw-r--r-- | src/nv_type.h | 117 | ||||
-rw-r--r-- | src/nv_xaa.c | 2 | ||||
-rw-r--r-- | src/nv_xf86Rename.h | 66 | ||||
-rw-r--r-- | src/nvreg.h | 90 |
33 files changed, 6766 insertions, 2855 deletions
diff --git a/src/Makefile.am b/src/Makefile.am index 7e4f5b1..d2dc5b5 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -33,7 +33,6 @@ nouveau_drv_la_SOURCES = \ nv_bios.c \ nv_const.h \ nv_cursor.c \ - nv_dac.c \ nv_dma.c \ nv_dma.h \ nv_dri.c \ @@ -54,7 +53,16 @@ nouveau_drv_la_SOURCES = \ nv_type.h \ nv_video.c \ nv_xaa.c \ - nv30_exa.c + nv_output.c \ + nv_crtc.c \ + nv_i2c.c \ + nv30_exa.c \ + nv50_cursor.c \ + nv50_dac.c \ + nv50_display.c \ + nv50_exa.c \ + nv50_output.c \ + nv50_sor.c #riva128_la_LTLIBRARIES = riva128.la #riva128_la_LDFLAGS = -module -avoid-version diff --git a/src/i2c_vid.h b/src/i2c_vid.h new file mode 100644 index 0000000..87ebe7a --- /dev/null +++ b/src/i2c_vid.h @@ -0,0 +1,16 @@ +/* this needs to go in the server */ +#ifndef I2C_VID_H +#define I2C_VID_H + +typedef struct _NVI2CVidOutputRec { + void *(*init)(I2CBusPtr b, I2CSlaveAddr addr); + xf86OutputStatus (*detect)(I2CDevPtr d); + ModeStatus (*mode_valid)(I2CDevPtr d, DisplayModePtr mode); + void (*mode_set)(I2CDevPtr d, DisplayModePtr mode); + void (*dpms)(I2CDevPtr d, int mode); + void (*dump_regs)(I2CDevPtr d); + void (*save)(I2CDevPtr d); + void (*restore)(I2CDevPtr d); +} NVI2CVidOutputRec, *NVI2CVidOutputPtr; + +#endif diff --git a/src/local_xf86Rename.h b/src/local_xf86Rename.h new file mode 100644 index 0000000..708877f --- /dev/null +++ b/src/local_xf86Rename.h @@ -0,0 +1,23 @@ +/* + * Copyright © 2006 Keith Packard + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that copyright + * notice and this permission notice appear in supporting documentation, and + * that the name of the copyright holders not be used in advertising or + * publicity pertaining to distribution of the software without specific, + * written prior permission. The copyright holders make no representations + * about the suitability of this software for any purpose. It is provided "as + * is" without express or implied warranty. + * + * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, + * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE + * OF THIS SOFTWARE. + */ + +#define XF86NAME(x) nv_##x diff --git a/src/nv50_cursor.c b/src/nv50_cursor.c new file mode 100644 index 0000000..9b51afa --- /dev/null +++ b/src/nv50_cursor.c @@ -0,0 +1,104 @@ +/* + * Copyright (c) 2007 NVIDIA, Corporation + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <string.h> + +#include <cursorstr.h> + +#include "nv_include.h" +#include "nv50_type.h" +#include "nv50_cursor.h" +#include "nv50_display.h" + +#define CURSOR_PTR ((CARD32*)pNv->Cursor->map) + +void NV50SetCursorPosition(xf86CrtcPtr crtc, int x, int y) +{ + NVPtr pNv = NVPTR(crtc->scrn); + const int headOff = 0x1000*NV50CrtcGetHead(crtc); + + x &= 0xffff; + y &= 0xffff; + pNv->REGS[(0x00647084 + headOff)/4] = y << 16 | x; + pNv->REGS[(0x00647080 + headOff)/4] = 0; +} + +void NV50LoadCursorARGB(xf86CrtcPtr crtc, CARD32 *src) +{ + NVPtr pNv = NVPTR(crtc->scrn); + CARD32 *dst = CURSOR_PTR; + + /* Assume cursor is 64x64 */ + memcpy(dst, src, 64 * 64 * 4); +} + +Bool NV50CursorAcquire(ScrnInfoPtr pScrn) +{ + NVPtr pNv = NVPTR(pScrn); + xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn); + int i; + + if(!pNv->HWCursor) return TRUE; + + /* Initialize the cursor on each head */ + for(i = 0; i < xf86_config->num_crtc; i++) { + const int headOff = 0x10 * NV50CrtcGetHead(xf86_config->crtc[i]); + + pNv->REGS[(0x00610270+headOff)/4] = 0x2000; + while(pNv->REGS[(0x00610270+headOff)/4] & 0x30000); + + pNv->REGS[(0x00610270+headOff)/4] = 1; + while((pNv->REGS[(0x00610270+headOff)/4] & 0x30000) != 0x10000); + } + + return TRUE; +} + +void NV50CursorRelease(ScrnInfoPtr pScrn) +{ + NVPtr pNv = NVPTR(pScrn); + xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn); + int i; + + if(!pNv->HWCursor) return; + + /* Release the cursor on each head */ + for(i = 0; i < xf86_config->num_crtc; i++) { + const int headOff = 0x10 * NV50CrtcGetHead(xf86_config->crtc[i]); + + pNv->REGS[(0x00610270+headOff)/4] = 0; + while(pNv->REGS[(0x00610270+headOff)/4] & 0x30000); + } +} + +Bool NV50CursorInit(ScreenPtr pScreen) +{ + return xf86_cursors_init(pScreen, 64, 64, + HARDWARE_CURSOR_TRUECOLOR_AT_8BPP | + HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_32 | + HARDWARE_CURSOR_ARGB); +} diff --git a/src/nv50_cursor.h b/src/nv50_cursor.h new file mode 100644 index 0000000..c856780 --- /dev/null +++ b/src/nv50_cursor.h @@ -0,0 +1,12 @@ +#ifndef __NV50_CURSOR_H__ +#define __NV50_CURSOR_H__ + +Bool NV50CursorInit(ScreenPtr); +Bool NV50CursorAcquire(ScrnInfoPtr); +void NV50CursorRelease(ScrnInfoPtr); + +/* CRTC cursor functions */ +void NV50SetCursorPosition(xf86CrtcPtr crtc, int x, int y); +void NV50LoadCursorARGB(xf86CrtcPtr crtc, CARD32 *src); + +#endif diff --git a/src/nv50_dac.c b/src/nv50_dac.c new file mode 100644 index 0000000..fcb4e97 --- /dev/null +++ b/src/nv50_dac.c @@ -0,0 +1,199 @@ +/* + * Copyright (c) 2007 NVIDIA, Corporation + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <unistd.h> + +#define DPMS_SERVER +#include <X11/extensions/dpms.h> + +#include "nv_include.h" +#include "nv50_display.h" +#include "nv50_output.h" + +static void +NV50DacSetPClk(xf86OutputPtr output, int pclk) +{ + NVPtr pNv = NVPTR(output->scrn); + NV50OutputPrivPtr pPriv = output->driver_private; + const int orOff = 0x800 * pPriv->or; + + pNv->REGS[(0x00614280+orOff)/4] = 0; +} + +static void +NV50DacDPMSSet(xf86OutputPtr output, int mode) +{ + NVPtr pNv = NVPTR(output->scrn); + NV50OutputPrivPtr 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->REGS[(0x0061A004+off)/4] & 0x80000000); + + tmp = pNv->REGS[(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->REGS[(0x0061A004+off)/4] = tmp; +} + +static void +NV50DacModeSet(xf86OutputPtr output, DisplayModePtr mode, + DisplayModePtr adjusted_mode) +{ + ScrnInfoPtr pScrn = output->scrn; + NV50OutputPrivPtr pPriv = output->driver_private; + const int dacOff = 0x80 * pPriv->or; + + if(!adjusted_mode) { + C(0x00000400 + dacOff, 0); + return; + } + + // This wouldn't be necessary, but the server is stupid and calls + // NV50DacDPMSSet after the output is disconnected, even though the hardware + // turns it off automatically. + NV50DacDPMSSet(output, DPMSModeOn); + + C(0x00000400 + dacOff, + (NV50CrtcGetHead(output->crtc) == HEAD0 ? 1 : 2) | 0x40); + C(0x00000404 + dacOff, + (adjusted_mode->Flags & V_NHSYNC) ? 1 : 0 | + (adjusted_mode->Flags & V_NVSYNC) ? 2 : 0); +} + +/* + * Perform DAC load detection to determine if there is a connected display. + */ +static xf86OutputStatus +NV50DacDetect(xf86OutputPtr output) +{ + NV50OutputPrivPtr pPriv = output->driver_private; + + /* Assume physical status isn't going to change before the BlockHandler */ + if(pPriv->cached_status != XF86OutputStatusUnknown) + return pPriv->cached_status; + + NV50OutputPartnersDetect(output, pPriv->partner, pPriv->i2c); + return pPriv->cached_status; +} + +Bool +NV50DacLoadDetect(xf86OutputPtr output) +{ + ScrnInfoPtr pScrn = output->scrn; + NVPtr pNv = NVPTR(pScrn); + NV50OutputPrivPtr pPriv = output->driver_private; + const int scrnIndex = pScrn->scrnIndex; + const int dacOff = 2048 * pPriv->or; + CARD32 load, tmp, tmp2; + + xf86DrvMsg(scrnIndex, X_PROBED, "Trying load detection on VGA%i ... ", + pPriv->or); + + pNv->REGS[(0x0061A010+dacOff)/4] = 0x00000001; + tmp2 = pNv->REGS[(0x0061A004+dacOff)/4]; + pNv->REGS[(0x0061A004+dacOff)/4] = 0x80150000; + while(pNv->REGS[(0x0061A004+dacOff)/4] & 0x80000000); + tmp = pNv->_Chipset == 0x50 ? 420 : 340; + pNv->REGS[(0x0061A00C+dacOff)/4] = tmp | 0x100000; + usleep(4500); + load = pNv->REGS[(0x0061A00C+dacOff)/4]; + pNv->REGS[(0x0061A00C+dacOff)/4] = 0; + pNv->REGS[(0x0061A004+dacOff)/4] = 0x80000000 | tmp2; + + // Use this DAC if all three channels show load. + if((load & 0x38000000) == 0x38000000) { + xf86ErrorF("found one!\n"); + return TRUE; + } + + xf86ErrorF("nothing.\n"); + return FALSE; +} + +static void +NV50DacDestroy(xf86OutputPtr output) +{ + NV50OutputDestroy(output); + + xfree(output->driver_private); + output->driver_private = NULL; +} + +static const xf86OutputFuncsRec NV50DacOutputFuncs = { + .dpms = NV50DacDPMSSet, + .save = NULL, + .restore = NULL, + .mode_valid = NV50OutputModeValid, + .mode_fixup = NV50OutputModeFixup, + .prepare = NV50OutputPrepare, + .commit = NV50OutputCommit, + .mode_set = NV50DacModeSet, + .detect = NV50DacDetect, + .get_modes = NV50OutputGetDDCModes, + .destroy = NV50DacDestroy, +}; + +xf86OutputPtr +NV50CreateDac(ScrnInfoPtr pScrn, ORNum or) +{ + NV50OutputPrivPtr pPriv = xnfcalloc(sizeof(*pPriv), 1); + xf86OutputPtr output; + char orName[5]; + + if(!pPriv) + return FALSE; + + snprintf(orName, 5, "VGA%i", or); + output = xf86OutputCreate(pScrn, &NV50DacOutputFuncs, orName); + + pPriv->type = DAC; + pPriv->or = or; + pPriv->cached_status = XF86OutputStatusUnknown; + pPriv->set_pclk = NV50DacSetPClk; + output->driver_private = pPriv; + output->interlaceAllowed = TRUE; + output->doubleScanAllowed = TRUE; + + return output; +} diff --git a/src/nv50_display.c b/src/nv50_display.c new file mode 100644 index 0000000..394c924 --- /dev/null +++ b/src/nv50_display.c @@ -0,0 +1,535 @@ +/* + * Copyright (c) 2007 NVIDIA, Corporation + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <float.h> +#include <math.h> +#include <strings.h> +#include <unistd.h> + +#include "nv_include.h" +#include "nv50_type.h" +#include "nv50_cursor.h" +#include "nv50_display.h" +#include "nv50_output.h" + +typedef struct NV50CrtcPrivRec { + Head head; + int pclk; /* Target pixel clock in kHz */ + Bool cursorVisible; +} NV50CrtcPrivRec, *NV50CrtcPrivPtr; + +static void NV50CrtcShowHideCursor(xf86CrtcPtr crtc, Bool show, Bool update); + +/* + * PLL calculation. pclk is in kHz. + */ +static void +NV50CalcPLL(float pclk, int *pNA, int *pMA, int *pNB, int *pMB, int *pP) +{ + const float refclk = 27000.0f; + const float minVcoA = 100000; + const float maxVcoA = 400000; + const float minVcoB = 600000; + float maxVcoB = 1400000; + const float minUA = 2000; + const float maxUA = 400000; + const float minUB = 50000; + const float maxUB = 200000; + const int minNA = 1, maxNA = 255; + const int minNB = 1, maxNB = 31; + const int minMA = 1, maxMA = 255; + const int minMB = 1, maxMB = 31; + const int minP = 0, maxP = 6; + int lowP, highP; + float vcoB; + + int na, ma, nb, mb, p; + float bestError = FLT_MAX; + + *pNA = *pMA = *pNB = *pMB = *pP = 0; + + if(maxVcoB < pclk + pclk / 200) + maxVcoB = pclk + pclk / 200; + if(minVcoB / (1 << maxP) > pclk) + pclk = minVcoB / (1 << maxP); + + vcoB = maxVcoB - maxVcoB / 200; + lowP = minP; + vcoB /= 1 << (lowP + 1); + + while(pclk <= vcoB && lowP < maxP) + { + vcoB /= 2; + lowP++; + } + + vcoB = maxVcoB + maxVcoB / 200; + highP = lowP; + vcoB /= 1 << (highP + 1); + + while(pclk <= vcoB && highP < maxP) + { + vcoB /= 2; + highP++; + } + + for(p = lowP; p <= highP; p++) + { + for(ma = minMA; ma <= maxMA; ma++) + { + if(refclk / ma < minUA) + break; + else if(refclk / ma > maxUA) + continue; + + for(na = minNA; na <= maxNA; na++) + { + if(refclk * na / ma < minVcoA || refclk * na / ma > maxVcoA) + continue; + + for(mb = minMB; mb <= maxMB; mb++) + { + if(refclk * na / ma / mb < minUB) + break; + else if(refclk * na / ma / mb > maxUB) + continue; + + nb = rint(pclk * (1 << p) * (ma / (float)na) * mb / refclk); + + if(nb > maxNB) + break; + else if(nb < minNB) + continue; + else + { + float freq = refclk * (na / (float)ma) * (nb / (float)mb) / (1 << p); + float error = fabsf(pclk - freq); + if(error < bestError) { + *pNA = na; + *pMA = ma; + *pNB = nb; + *pMB = mb; + *pP = p; + bestError = error; + } + } + } + } + } + } +} + +static void +NV50CrtcSetPClk(xf86CrtcPtr crtc) +{ + NVPtr pNv = NVPTR(crtc->scrn); + NV50CrtcPrivPtr pPriv = crtc->driver_private; + xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(crtc->scrn); + const int headOff = 0x800 * pPriv->head; + int lo_n, lo_m, hi_n, hi_m, p, i; + CARD32 lo = pNv->REGS[(0x00614104+headOff)/4]; + CARD32 hi = pNv->REGS[(0x00614108+headOff)/4]; + + pNv->REGS[(0x00614100+headOff)/4] = 0x10000610; + lo &= 0xff00ff00; + hi &= 0x8000ff00; + + NV50CalcPLL(pPriv->pclk, &lo_n, &lo_m, &hi_n, &hi_m, &p); + + lo |= (lo_m << 16) | lo_n; + hi |= (p << 28) | (hi_m << 16) | hi_n; + pNv->REGS[(0x00614104+headOff)/4] = lo; + pNv->REGS[(0x00614108+headOff)/4] = hi; + pNv->REGS[(0x00614200+headOff)/4] = 0; + + for(i = 0; i < xf86_config->num_output; i++) { + xf86OutputPtr output = xf86_config->output[i]; + + if(output->crtc != crtc) + continue; + NV50OutputSetPClk(output, pPriv->pclk); + } +} + +void +NV50DispCommand(ScrnInfoPtr pScrn, CARD32 addr, CARD32 data) +{ + NVPtr pNv = NVPTR(pScrn); + + pNv->REGS[0x00610304/4] = data; + pNv->REGS[0x00610300/4] = addr | 0x80010001; + + while(pNv->REGS[0x00610300/4] & 0x80000000) { + const int super = ffs((pNv->REGS[0x00610024/4] >> 4) & 7); + + if(super) { + if(super == 2) { + xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn); + const CARD32 r = pNv->REGS[0x00610030/4]; + int i; + + for(i = 0; i < xf86_config->num_crtc; i++) + { + xf86CrtcPtr crtc = xf86_config->crtc[i]; + NV50CrtcPrivPtr pPriv = crtc->driver_private; + + if(r & (0x200 << pPriv->head)) + NV50CrtcSetPClk(crtc); + } + } + + pNv->REGS[0x00610024/4] = 8 << super; + pNv->REGS[0x00610030/4] = 0x80000000; + } + } +} + +Head +NV50CrtcGetHead(xf86CrtcPtr crtc) +{ + NV50CrtcPrivPtr pPriv = crtc->driver_private; + return pPriv->head; +} + +Bool +NV50DispPreInit(ScrnInfoPtr pScrn) +{ + NVPtr pNv = NVPTR(pScrn); + + pNv->REGS[0x00610184/4] = pNv->REGS[0x00614004/4]; + pNv->REGS[0x00610190/4] = pNv->REGS[0x00616100/4]; + pNv->REGS[0x006101a0/4] = pNv->REGS[0x00616900/4]; + pNv->REGS[0x00610194/4] = pNv->REGS[0x00616104/4]; + pNv->REGS[0x006101a4/4] = pNv->REGS[0x00616904/4]; + pNv->REGS[0x00610198/4] = pNv->REGS[0x00616108/4]; + pNv->REGS[0x006101a8/4] = pNv->REGS[0x00616908/4]; + pNv->REGS[0x0061019C/4] = pNv->REGS[0x0061610C/4]; + pNv->REGS[0x006101ac/4] = pNv->REGS[0x0061690c/4]; + pNv->REGS[0x006101D0/4] = pNv->REGS[0x0061A000/4]; + pNv->REGS[0x006101D4/4] = pNv->REGS[0x0061A800/4]; + pNv->REGS[0x006101D8/4] = pNv->REGS[0x0061B000/4]; + pNv->REGS[0x006101E0/4] = pNv->REGS[0x0061C000/4]; + pNv->REGS[0x006101E4/4] = pNv->REGS[0x0061C800/4]; + pNv->REGS[0x0061c00c/4] = 0x03010700; + pNv->REGS[0x0061c010/4] = 0x0000152f; + pNv->REGS[0x0061c014/4] = 0x00000000; + pNv->REGS[0x0061c018/4] = 0x00245af8; + pNv->REGS[0x0061c80c/4] = 0x03010700; + pNv->REGS[0x0061c810/4] = 0x0000152f; + pNv->REGS[0x0061c814/4] = 0x00000000; + pNv->REGS[0x0061c818/4] = 0x00245af8; + pNv->REGS[0x0061A004/4] = 0x80550000; + pNv->REGS[0x0061A010/4] = 0x00000001; + pNv->REGS[0x0061A804/4] = 0x80550000; + pNv->REGS[0x0061A810/4] = 0x00000001; + pNv->REGS[0x0061B004/4] = 0x80550000; + pNv->REGS[0x0061B010/4] = 0x00000001; + + return TRUE; +} + +Bool +NV50DispInit(ScrnInfoPtr pScrn) +{ + NVPtr pNv = NVPTR(pScrn); + + if(pNv->REGS[0x00610024/4] & 0x100) { + pNv->REGS[0x00610024/4] = 0x100; + pNv->REGS[0x006194E8/4] &= ~1; + while(pNv->REGS[0x006194E8/4] & 2); + } + + pNv->REGS[0x00610200/4] = 0x2b00; + while((pNv->REGS[0x00610200/4] & 0x1e0000) != 0); + pNv->REGS[0x00610300/4] = 1; + pNv->REGS[0x00610200/4] = 0x1000b03; + while(!(pNv->REGS[0x00610200/4] & 0x40000000)); + + C(0x00000084, 0); + C(0x00000088, 0); + C(0x00000874, 0); + C(0x00000800, 0); + C(0x00000810, 0); + C(0x0000082C, 0); + + return TRUE; +} + +void +NV50DispShutdown(ScrnInfoPtr pScrn) +{ + NVPtr pNv = NVPTR(pScrn); + xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn); + int i; + + for(i = 0; i < xf86_config->num_crtc; i++) { + xf86CrtcPtr crtc = xf86_config->crtc[i]; + + NV50CrtcBlankScreen(crtc, TRUE); + } + + C(0x00000080, 0); + + for(i = 0; i < xf86_config->num_crtc; i++) { + xf86CrtcPtr crtc = xf86_config->crtc[i]; + + if(crtc->enabled) { + const CARD32 mask = 4 << NV50CrtcGetHead(crtc); + + pNv->REGS[0x00610024/4] = mask; + while(!(pNv->REGS[0x00610024/4] & mask)); + } + } + + pNv->REGS[0x00610200/4] = 0; + pNv->REGS[0x00610300/4] = 0; + while((pNv->REGS[0x00610200/4] & 0x1e0000) != 0); +} + +static Bool +NV50CrtcModeFixup(xf86CrtcPtr crtc, + DisplayModePtr mode, DisplayModePtr adjusted_mode) +{ + // TODO: Fix up the mode here + return TRUE; +} + +static void +NV50CrtcModeSet(xf86CrtcPtr crtc, DisplayModePtr mode, + DisplayModePtr adjusted_mode, int x, int y) +{ + ScrnInfoPtr pScrn = crtc->scrn; + NV50CrtcPrivPtr pPriv = crtc->driver_private; + const int HDisplay = mode->HDisplay, VDisplay = mode->VDisplay; + const int headOff = 0x400 * NV50CrtcGetHead(crtc); + int interlaceDiv, fudge; + + // TODO: Use adjusted_mode and fix it up in NV50CrtcModeFixup + 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; + + C(0x00000804 + headOff, mode->Clock | 0x800000); + C(0x00000808 + headOff, (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(0x00000868 + headOff, pScrn->virtualY << 16 | pScrn->virtualX); + C(0x0000086C + headOff, pScrn->displayWidth * (pScrn->bitsPerPixel / 8) | 0x100000); + switch(pScrn->depth) { + case 8: C(0x00000870 + headOff, 0x1E00); break; + case 15: C(0x00000870 + headOff, 0xE900); break; + 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) { + C(0x000008A4 + headOff, 9); + } else { + C(0x000008A4 + headOff, 0); + } + C(0x000008A8 + headOff, 0x40000); + 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); + + NV50CrtcBlankScreen(crtc, FALSE); +} + +void +NV50CrtcBlankScreen(xf86CrtcPtr crtc, Bool blank) +{ + ScrnInfoPtr pScrn = crtc->scrn; + NVPtr pNv = NVPTR(pScrn); + NV50CrtcPrivPtr pPriv = crtc->driver_private; + const int headOff = 0x400 * pPriv->head; + + if(blank) { + NV50CrtcShowHideCursor(crtc, FALSE, FALSE); + + C(0x00000840 + headOff, 0); + C(0x00000844 + headOff, 0); + if(pNv->_Chipset != 0x50) + C(0x0000085C + headOff, 0); + C(0x00000874 + headOff, 0); + if(pNv->_Chipset != 0x50) + C(0x0000089C + headOff, 0); + } else { + C(0x00000860 + headOff, pNv->FB->offset >> 8); + C(0x00000864 + headOff, 0); + pNv->REGS[0x00610380/4] = 0; + /*XXX: in "nv" this is total vram size. our RamAmountKBytes is clamped + * to 256MiB. + */ + pNv->REGS[0x00610384/4] = pNv->RamAmountKBytes * 1024 - 1; + pNv->REGS[0x00610388/4] = 0x150000; + pNv->REGS[0x0061038C/4] = 0; + C(0x00000884 + headOff, pNv->Cursor->offset >> 8); + if(pNv->_Chipset != 0x50) + C(0x0000089C + headOff, 1); + if(pPriv->cursorVisible) + NV50CrtcShowHideCursor(crtc, TRUE, FALSE); + C(0x00000840 + headOff, pScrn->depth == 8 ? 0x80000000 : 0xc0000000); + C(0x00000844 + headOff, pNv->CLUT->offset >> 8); + if(pNv->_Chipset != 0x50) + C(0x0000085C + headOff, 1); + C(0x00000874 + headOff, 1); + } +} + +void +NV50CrtcDPMSSet(xf86CrtcPtr crtc, int mode) +{ +} + +/******************************** Cursor stuff ********************************/ +static void NV50CrtcShowHideCursor(xf86CrtcPtr crtc, Bool show, Bool update) +{ + ScrnInfoPtr pScrn = crtc->scrn; + NV50CrtcPrivPtr pPriv = crtc->driver_private; + const int headOff = 0x400 * NV50CrtcGetHead(crtc); + + C(0x00000880 + headOff, show ? 0x85000000 : 0x5000000); + if(update) { + pPriv->cursorVisible = show; + C(0x00000080, 0); + } +} + +void NV50CrtcShowCursor(xf86CrtcPtr crtc) +{ + NV50CrtcShowHideCursor(crtc, TRUE, TRUE); +} + +void NV50CrtcHideCursor(xf86CrtcPtr crtc) +{ + NV50CrtcShowHideCursor(crtc, FALSE, TRUE); +} + +/******************************** CRTC stuff ********************************/ + +static Bool +NV50CrtcLock(xf86CrtcPtr crtc) +{ + return FALSE; +} + +static void +NV50CrtcPrepare(xf86CrtcPtr crtc) +{ + ScrnInfoPtr pScrn = crtc->scrn; + xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn); + int i; + + for(i = 0; i < xf86_config->num_output; i++) { + xf86OutputPtr output = xf86_config->output[i]; + + if(!output->crtc) + output->funcs->mode_set(output, NULL, NULL); + } +} + +static void +NV50CrtcCommit(xf86CrtcPtr crtc) +{ + ScrnInfoPtr pScrn = crtc->scrn; + xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(crtc->scrn); + int i, crtc_mask = 0; + + /* If any heads are unused, blank them */ + for(i = 0; i < xf86_config->num_output; i++) { + xf86OutputPtr output = xf86_config->output[i]; + + if(output->crtc) + /* XXXagp: This assumes that xf86_config->crtc[i] is HEADi */ + crtc_mask |= 1 << NV50CrtcGetHead(output->crtc); + } + + for(i = 0; i < xf86_config->num_crtc; i++) + if(!((1 << i) & crtc_mask)) + NV50CrtcBlankScreen(xf86_config->crtc[i], TRUE); + + C(0x00000080, 0); +} + +static const xf86CrtcFuncsRec nv50_crtc_funcs = { + .dpms = NV50CrtcDPMSSet, + .save = NULL, + .restore = NULL, + .lock = NV50CrtcLock, + .unlock = NULL, + .mode_fixup = NV50CrtcModeFixup, + .prepare = NV50CrtcPrepare, + .mode_set = NV50CrtcModeSet, + // .gamma_set = NV50DispGammaSet, + .commit = NV50CrtcCommit, + .shadow_create = NULL, + .shadow_destroy = NULL, + .set_cursor_position = NV50SetCursorPosition, + .show_cursor = NV50CrtcShowCursor, + .hide_cursor = NV50CrtcHideCursor, + .load_cursor_argb = NV50LoadCursorARGB, + .destroy = NULL, +}; + +void +NV50DispCreateCrtcs(ScrnInfoPtr pScrn) +{ + Head head; + xf86CrtcPtr crtc; + NV50CrtcPrivPtr nv50_crtc; + + /* Create a "crtc" object for each head */ + for(head = HEAD0; head <= HEAD1; head++) { + crtc = xf86CrtcCreate(pScrn, &nv50_crtc_funcs); + if(!crtc) return; + + nv50_crtc = xnfcalloc(sizeof(*nv50_crtc), 1); + nv50_crtc->head = head; + crtc->driver_private = nv50_crtc; + } +} diff --git a/src/nv50_display.h b/src/nv50_display.h new file mode 100644 index 0000000..4f43e32 --- /dev/null +++ b/src/nv50_display.h @@ -0,0 +1,22 @@ +#ifndef __NV50_DISPLAY_H__ +#define __NV50_DISPLAY_H__ + +#include "nv50_type.h" + +Bool NV50DispPreInit(ScrnInfoPtr); +Bool NV50DispInit(ScrnInfoPtr); +void NV50DispShutdown(ScrnInfoPtr); + +void NV50DispCommand(ScrnInfoPtr, CARD32 addr, CARD32 data); +#define C(mthd, data) NV50DispCommand(pScrn, (mthd), (data)) + +Head NV50CrtcGetHead(xf86CrtcPtr); + +void NV50CrtcBlankScreen(xf86CrtcPtr, Bool blank); +void NV50CrtcEnableCursor(xf86CrtcPtr, Bool update); +void NV50CrtcDisableCursor(xf86CrtcPtr, Bool update); +void NV50CrtcSetCursorPosition(xf86CrtcPtr, int x, int y); + +void NV50DispCreateCrtcs(ScrnInfoPtr pScrn); + +#endif diff --git a/src/nv50_exa.c b/src/nv50_exa.c new file mode 100644 index 0000000..2ff4f6a --- /dev/null +++ b/src/nv50_exa.c @@ -0,0 +1,254 @@ +#include "nv_include.h" + +#define NV50_2D_NOP 0x00000100 +#define NV50_2D_UNK110 0x00000110 +#define NV50_2D_DST_FORMAT 0x00000200 +#define NV50_2D_SRC_FORMAT 0x00000230 +#define NV50_2D_SRC_FORMAT_8BPP 0x000000f3 +#define NV50_2D_SRC_FORMAT_15BPP 0x000000f8 +#define NV50_2D_SRC_FORMAT_16BPP 0x000000e8 +#define NV50_2D_SRC_FORMAT_24BPP 0x000000e6 +#define NV50_2D_SRC_FORMAT_32BPP 0x000000cf +#define NV50_2D_CLIP_X 0x00000280 +#define NV50_2D_SET_OPERATION 0x000002ac +#define NV50_2D_SET_OPERATION_ROP_AND 0x00000001 +#define NV50_2D_SET_OPERATION_SRCCOPY 0x00000003 +#define NV50_2D_RASTER_OP 0x000002a0 +#define NV50_2D_PATTERN_FORMAT 0x000002e8 +#define NV50_2D_PATTERN_COLOR_0 0x000002f0 +#define NV50_2D_RECT_UNK580 0x00000580 +#define NV50_2D_RECT_FORMAT 0x00000584 +#define NV50_2D_RECT_X1 0x00000600 +#define NV50_2D_BLIT_DST_X 0x000008b0 + +#define NV50EXA_LOCALS(p) \ + ScrnInfoPtr pScrn = xf86Screens[(p)->drawable.pScreen->myNum]; \ + NVPtr pNv = NVPTR(pScrn); \ + (void)pNv + +static Bool +NV50EXA2DSurfaceFormat(PixmapPtr pPix, uint32_t *fmt) +{ + NV50EXA_LOCALS(pPix); + + switch (pPix->drawable.depth) { + case 8 : *fmt = NV50_2D_SRC_FORMAT_8BPP; break; + case 15: *fmt = NV50_2D_SRC_FORMAT_15BPP; break; + case 16: *fmt = NV50_2D_SRC_FORMAT_16BPP; break; + case 24: *fmt = NV50_2D_SRC_FORMAT_24BPP; break; + case 32: *fmt = NV50_2D_SRC_FORMAT_32BPP; break; + default: + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "Unknown surface format for bpp=%d\n", + pPix->drawable.depth); + return FALSE; + } + + return TRUE; +} + +static Bool +NV50EXAAcquireSurface2D(PixmapPtr pPix, int is_src) +{ + NV50EXA_LOCALS(pPix); + int mthd = is_src ? NV50_2D_SRC_FORMAT : NV50_2D_DST_FORMAT; + uint32_t fmt; + + if (!NV50EXA2DSurfaceFormat(pPix, &fmt)) + return FALSE; + + NVDmaStart(pNv, Nv2D, mthd, 2); + NVDmaNext (pNv, fmt); + NVDmaNext (pNv, 1); + + NVDmaStart(pNv, Nv2D, mthd + 0x14, 5); + NVDmaNext (pNv, (uint32_t)exaGetPixmapPitch(pPix)); + NVDmaNext (pNv, pPix->drawable.width); + NVDmaNext (pNv, pPix->drawable.height); + NVDmaNext (pNv, 0); + NVDmaNext (pNv, NVAccelGetPixmapOffset(pPix)); + + if (is_src == 0) { + NVDmaStart(pNv, Nv2D, NV50_2D_CLIP_X, 4); + NVDmaNext (pNv, 0); + NVDmaNext (pNv, 0); + NVDmaNext (pNv, pPix->drawable.width); + NVDmaNext (pNv, pPix->drawable.height); + } + + return TRUE; +} + +static Bool +NV50EXAAcquireSurfaces(PixmapPtr pdPix) +{ + NV50EXA_LOCALS(pdPix); + + return TRUE; +} + +static void +NV50EXAReleaseSurfaces(PixmapPtr pdPix) +{ + NV50EXA_LOCALS(pdPix); + + NVDmaStart(pNv, Nv2D, NV50_2D_NOP, 1); + NVDmaNext (pNv, 0); + NVDmaKickoff(pNv); +} + +static void +NV50EXASetPattern(PixmapPtr pdPix, int col0, int col1, int pat0, int pat1) +{ + NV50EXA_LOCALS(pdPix); + + NVDmaStart(pNv, Nv2D, NV50_2D_PATTERN_COLOR_0, 4); + NVDmaNext (pNv, col0); + NVDmaNext (pNv, col1); + NVDmaNext (pNv, pat0); + NVDmaNext (pNv, pat1); +} + +extern const int NVCopyROP[16]; +static void +NV50EXASetROP(PixmapPtr pdPix, int alu, Pixel planemask) +{ + NV50EXA_LOCALS(pdPix); + int rop = NVCopyROP[alu]; + + NVDmaStart(pNv, Nv2D, NV50_2D_SET_OPERATION, 1); + if(alu == GXcopy && planemask == ~0) { + NVDmaNext (pNv, NV50_2D_SET_OPERATION_SRCCOPY); + return; + } else { + NVDmaNext (pNv, NV50_2D_SET_OPERATION_ROP_AND); + } + + NVDmaStart(pNv, Nv2D, NV50_2D_PATTERN_FORMAT, 1); + switch (pdPix->drawable.depth) { + case 8: NVDmaNext(pNv, 3); break; + case 15: NVDmaNext(pNv, 1); break; + case 16: NVDmaNext(pNv, 0); break; + case 24: + case 32: + default: + NVDmaNext(pNv, 2); + break; + } + + if(planemask != ~0) { + NV50EXASetPattern(pdPix, 0, planemask, ~0, ~0); + rop = (rop & 0xf0) | 0x0a; + } else + if((pNv->currentRop & 0x0f) == 0x0a) { + NV50EXASetPattern(pdPix, ~0, ~0, ~0, ~0); + } + + if (pNv->currentRop != rop) { + NVDmaStart(pNv, Nv2D, NV50_2D_RASTER_OP, 1); + NVDmaNext (pNv, rop); + pNv->currentRop = rop; + } +} + +Bool +NV50EXAPrepareSolid(PixmapPtr pdPix, int alu, Pixel planemask, Pixel fg) +{ + NV50EXA_LOCALS(pdPix); + uint32_t fmt; + + if(pdPix->drawable.depth > 24) + return FALSE; + if (!NV50EXA2DSurfaceFormat(pdPix, &fmt)) + return FALSE; + + if (!NV50EXAAcquireSurface2D(pdPix, 0)) + return FALSE; + if (!NV50EXAAcquireSurfaces(pdPix)) + return FALSE; + NV50EXASetROP(pdPix, alu, planemask); + + NVDmaStart(pNv, Nv2D, NV50_2D_RECT_UNK580, 3); + NVDmaNext (pNv, 4); + NVDmaNext (pNv, fmt); + NVDmaNext (pNv, fg); + + return TRUE; +} + +void +NV50EXASolid(PixmapPtr pdPix, int x1, int y1, int x2, int y2) +{ + NV50EXA_LOCALS(pdPix); + + NVDmaStart(pNv, Nv2D, NV50_2D_RECT_X1, 4); + NVDmaNext (pNv, x1); + NVDmaNext (pNv, y1); + NVDmaNext (pNv, x2); + NVDmaNext (pNv, y2); + + if((x2 - x1) * (y2 - y1) >= 512) + NVDmaKickoff(pNv); +} + +void +NV50EXADoneSolid(PixmapPtr pdPix) +{ + NV50EXA_LOCALS(pdPix); + + NV50EXAReleaseSurfaces(pdPix); +} + +Bool +NV50EXAPrepareCopy(PixmapPtr psPix, PixmapPtr pdPix, int dx, int dy, + int alu, Pixel planemask) +{ + NV50EXA_LOCALS(pdPix); + + if (!NV50EXAAcquireSurface2D(psPix, 1)) + return FALSE; + if (!NV50EXAAcquireSurface2D(pdPix, 0)) + return FALSE; + if (!NV50EXAAcquireSurfaces(pdPix)) + return FALSE; + NV50EXASetROP(pdPix, alu, planemask); + + return TRUE; +} + +void +NV50EXACopy(PixmapPtr pdPix, int srcX , int srcY, + int dstX , int dstY, + int width, int height) +{ + NV50EXA_LOCALS(pdPix); + + NVDmaStart(pNv, Nv2D, NV50_2D_UNK110, 1); + NVDmaNext (pNv, 0); + NVDmaStart(pNv, Nv2D, NV50_2D_BLIT_DST_X, 12); + NVDmaNext (pNv, dstX); + NVDmaNext (pNv, dstY); + NVDmaNext (pNv, width); + NVDmaNext (pNv, height); + NVDmaNext (pNv, 0); + NVDmaNext (pNv, 1); + NVDmaNext (pNv, 0); + NVDmaNext (pNv, 1); + NVDmaNext (pNv, 0); + NVDmaNext (pNv, srcX); + NVDmaNext (pNv, 0); + NVDmaNext (pNv, srcY); + + if(width * height >= 512) + NVDmaKickoff(pNv); +} + +void +NV50EXADoneCopy(PixmapPtr pdPix) +{ + NV50EXA_LOCALS(pdPix); + + NV50EXAReleaseSurfaces(pdPix); +} + + diff --git a/src/nv50_output.c b/src/nv50_output.c new file mode 100644 index 0000000..74ea05e --- /dev/null +++ b/src/nv50_output.c @@ -0,0 +1,372 @@ +/* + * Copyright (c) 2007 NVIDIA, Corporation + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <strings.h> +#include <xf86DDC.h> + +#include "nv_include.h" +#include "nv50_type.h" +#include "nv50_output.h" + +static unsigned const char * +NV50GetVBIOSImage(NVPtr pNv) +{ + unsigned char *VBIOS; + uint32_t old_bar0_pramin; + + VBIOS = xalloc(65536); + if (VBIOS) { + old_bar0_pramin = pNv->REGS[0x1700/4]; + pNv->REGS[0x1700/4] = pNv->REGS[0x00619f04/4] >> 8; + + memcpy(VBIOS, (const void *)&pNv->REGS[0x700000/4], 65536); + + pNv->REGS[0x1700/4] = old_bar0_pramin; + } + + return (unsigned const char *)VBIOS; +} + +static Bool NV50ReadPortMapping(int scrnIndex, NVPtr pNv) +{ + unsigned const char *VBIOS; + unsigned char *table2; + unsigned char headerSize, entries; + int i; + CARD16 a; + CARD32 b; + + VBIOS = NV50GetVBIOSImage(pNv); + if (!VBIOS) + goto fail; + + /* Clear the i2c map to invalid */ + for(i = 0; i < 4; i++) + pNv->i2cMap[i].dac = pNv->i2cMap[i].sor = -1; + + if(*(CARD16*)VBIOS != 0xaa55) goto fail; + + a = *(CARD16*)(VBIOS + 0x36); + table2 = (unsigned char*)VBIOS + a; + + if(table2[0] != 0x40) goto fail; + + b = *(CARD32*)(table2 + 6); + if(b != 0x4edcbdcb) goto fail; + + headerSize = table2[1]; + entries = table2[2]; + + for(i = 0; i < entries; i++) { + int type, port; + ORNum or; + + b = *(CARD32*)&table2[headerSize + 8*i]; + type = b & 0xf; + port = (b >> 4) & 0xf; + or = ffs((b >> 24) & 0xf) - 1; + + if(type < 4 && port != 0xf) { + switch(type) { + case 0: /* CRT */ + case 1: /* TV */ + if(pNv->i2cMap[port].dac != -1) { + xf86DrvMsg(scrnIndex, X_WARNING, + "DDC routing table corrupt! DAC %i -> %i " + "for port %i\n", + or, pNv->i2cMap[port].dac, port); + } + pNv->i2cMap[port].dac = or; + break; + case 2: /* TMDS */ + case 3: /* LVDS */ + if(pNv->i2cMap[port].sor != -1) + xf86DrvMsg(scrnIndex, X_WARNING, + "DDC routing table corrupt! SOR %i -> %i " + "for port %i\n", + or, pNv->i2cMap[port].sor, port); + pNv->i2cMap[port].sor = or; + break; + } + } + } + + xf86DrvMsg(scrnIndex, X_PROBED, "I2C map:\n"); + for(i = 0; i < 4; i++) { + if(pNv->i2cMap[i].dac != -1) + xf86DrvMsg(scrnIndex, X_PROBED, " Bus %i -> DAC%i\n", i, pNv->i2cMap[i].dac); + if(pNv->i2cMap[i].sor != -1) + xf86DrvMsg(scrnIndex, X_PROBED, " Bus %i -> SOR%i\n", i, pNv->i2cMap[i].sor); + } + + return TRUE; + +fail: + xf86DrvMsg(scrnIndex, X_ERROR, "Couldn't find the DDC routing table. " + "Mode setting will probably fail!\n"); + return FALSE; +} + +static void NV50_I2CPutBits(I2CBusPtr b, int clock, int data) +{ + NVPtr pNv = NVPTR(xf86Screens[b->scrnIndex]); + const int off = b->DriverPrivate.val * 0x18; + + pNv->REGS[(0x0000E138+off)/4] = 4 | clock | data << 1; +} + +static void NV50_I2CGetBits(I2CBusPtr b, int *clock, int *data) +{ + NVPtr pNv = NVPTR(xf86Screens[b->scrnIndex]); + const int off = b->DriverPrivate.val * 0x18; + unsigned char val; + + val = pNv->REGS[(0x0000E138+off)/4]; + *clock = !!(val & 1); + *data = !!(val & 2); +} + +static I2CBusPtr +NV50I2CInit(ScrnInfoPtr pScrn, const char *name, const int port) +{ + I2CBusPtr i2c; + + /* Allocate the I2C bus structure */ + i2c = xf86CreateI2CBusRec(); + if(!i2c) return NULL; + + i2c->BusName = strdup(name); + i2c->scrnIndex = pScrn->scrnIndex; + i2c->I2CPutBits = NV50_I2CPutBits; + i2c->I2CGetBits = NV50_I2CGetBits; + i2c->ByteTimeout = 2200; /* VESA DDC spec 3 p. 43 (+10 %) */ + i2c->StartTimeout = 550; + i2c->BitTimeout = 40; + i2c->ByteTimeout = 40; + i2c->AcknTimeout = 40; + i2c->DriverPrivate.val = port; + + if(xf86I2CBusInit(i2c)) { + return i2c; + } else { + xfree(i2c); + return NULL; + } +} + +void +NV50OutputSetPClk(xf86OutputPtr output, int pclk) +{ + NV50OutputPrivPtr pPriv = output->driver_private; + pPriv->set_pclk(output, pclk); +} + +int +NV50OutputModeValid(xf86OutputPtr output, DisplayModePtr mode) +{ + if(mode->Clock > 400000 || mode->Clock < 25000) + return MODE_CLOCK_RANGE; + + return MODE_OK; +} + +Bool +NV50OutputModeFixup(xf86OutputPtr output, DisplayModePtr mode, + DisplayModePtr adjusted_mode) +{ + return TRUE; +} + +void +NV50OutputPrepare(xf86OutputPtr output) +{ +} + +void +NV50OutputCommit(xf86OutputPtr output) +{ +} + +static xf86MonPtr +ProbeDDC(I2CBusPtr i2c) +{ + ScrnInfoPtr pScrn = xf86Screens[i2c->scrnIndex]; + NVPtr pNv = NVPTR(pScrn); + xf86MonPtr monInfo = NULL; + const int bus = i2c->DriverPrivate.val, off = bus * 0x18; + + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "Probing for EDID on I2C bus %i...\n", bus); + pNv->REGS[(0x0000E138+off)/4] = 7; + /* Should probably use xf86OutputGetEDID here */ + monInfo = xf86DoEDID_DDC2(pScrn->scrnIndex, i2c); + pNv->REGS[(0x0000E138+off)/4] = 3; + + if(monInfo) { + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, + "DDC detected a %s:\n", monInfo->features.input_type ? + "DFP" : "CRT"); + xf86PrintEDID(monInfo); + } else { + xf86DrvMsg(pScrn->scrnIndex, X_INFO, " ... none found\n"); + } + + return monInfo; +} + +/* + * Read an EDID from the i2c port. Perform load detection on the DAC (if + * present) to see if the display is connected via VGA. Sets the cached status + * of both outputs. The status is marked dirty again in the BlockHandler. + */ +void NV50OutputPartnersDetect(xf86OutputPtr dac, xf86OutputPtr sor, I2CBusPtr i2c) +{ + xf86MonPtr monInfo = ProbeDDC(i2c); + xf86OutputPtr connected = NULL; + Bool load = dac && NV50DacLoadDetect(dac); + + if(dac) { + NV50OutputPrivPtr pPriv = dac->driver_private; + + if(load) { + pPriv->cached_status = XF86OutputStatusConnected; + connected = dac; + } else { + pPriv->cached_status = XF86OutputStatusDisconnected; + } + } + + if(sor) { + NV50OutputPrivPtr pPriv = sor->driver_private; + + if(monInfo && !load) { + pPriv->cached_status = XF86OutputStatusConnected; + connected = sor; + } else { + pPriv->cached_status = XF86OutputStatusDisconnected; + } + } + + if(connected) + xf86OutputSetEDID(connected, monInfo); +} + +/* + * Reset the cached output status for all outputs. Called from NV50BlockHandler. + */ +void +NV50OutputResetCachedStatus(ScrnInfoPtr pScrn) +{ + xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn); + int i; + + for(i = 0; i < xf86_config->num_output; i++) { + NV50OutputPrivPtr pPriv = xf86_config->output[i]->driver_private; + pPriv->cached_status = XF86OutputStatusUnknown; + } +} + +DisplayModePtr +NV50OutputGetDDCModes(xf86OutputPtr output) +{ + /* The EDID is read as part of the detect step */ + output->funcs->detect(output); + return xf86OutputGetEDIDModes(output); +} + +void +NV50OutputDestroy(xf86OutputPtr output) +{ + NV50OutputPrivPtr pPriv = output->driver_private; + + if(pPriv->partner) + ((NV50OutputPrivPtr)pPriv->partner->driver_private)->partner = NULL; + else + xf86DestroyI2CBusRec(pPriv->i2c, TRUE, TRUE); + pPriv->i2c = NULL; +} + +Bool +NV50CreateOutputs(ScrnInfoPtr pScrn) +{ + NVPtr pNv = NVPTR(pScrn); + xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn); + int i; + + if(!NV50ReadPortMapping(pScrn->scrnIndex, pNv)) + return FALSE; + + /* For each DDC port, create an output for the attached ORs */ + for(i = 0; i < 4; i++) { + xf86OutputPtr dac = NULL, sor = NULL; + I2CBusPtr i2c; + char i2cName[16]; + + if(pNv->i2cMap[i].dac == -1 && pNv->i2cMap[i].sor == -1) + /* No outputs on this port */ + continue; + + snprintf(i2cName, sizeof(i2cName), "I2C%i", i); + i2c = NV50I2CInit(pScrn, i2cName, i); + if(!i2c) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "Failed to initialize I2C for port %i.\n", + i); + continue; + } + + if(pNv->i2cMap[i].dac != -1) + dac = NV50CreateDac(pScrn, pNv->i2cMap[i].dac); + if(pNv->i2cMap[i].sor != -1) + sor = NV50CreateSor(pScrn, pNv->i2cMap[i].sor); + + if(dac) { + NV50OutputPrivPtr pPriv = dac->driver_private; + + pPriv->partner = sor; + pPriv->i2c = i2c; + } + if(sor) { + NV50OutputPrivPtr pPriv = sor->driver_private; + + pPriv->partner = dac; + pPriv->i2c = i2c; + } + } + + /* For each output, set the crtc and clone masks */ + for(i = 0; i < xf86_config->num_output; i++) { + xf86OutputPtr output = xf86_config->output[i]; + + /* Any output can connect to any head */ + output->possible_crtcs = 0x3; + output->possible_clones = 0; + } + + return TRUE; +} diff --git a/src/nv50_output.h b/src/nv50_output.h new file mode 100644 index 0000000..4fac55a --- /dev/null +++ b/src/nv50_output.h @@ -0,0 +1,34 @@ +#ifndef __NV50_OUTPUT_H__ +#define __NV50_OUTPUT_H__ + +typedef struct NV50OutputPrivRec { + ORType type; + ORNum or; + + xf86OutputPtr partner; + I2CBusPtr i2c; + + xf86OutputStatus cached_status; + + void (*set_pclk)(xf86OutputPtr, int pclk); +} NV50OutputPrivRec, *NV50OutputPrivPtr; + +void NV50OutputSetPClk(xf86OutputPtr, int pclk); +int NV50OutputModeValid(xf86OutputPtr, DisplayModePtr); +Bool NV50OutputModeFixup(xf86OutputPtr, DisplayModePtr mode, DisplayModePtr adjusted_mode); +void NV50OutputPrepare(xf86OutputPtr); +void NV50OutputCommit(xf86OutputPtr); +void NV50OutputPartnersDetect(xf86OutputPtr dac, xf86OutputPtr sor, I2CBusPtr i2c); +void NV50OutputResetCachedStatus(ScrnInfoPtr); +DisplayModePtr NV50OutputGetDDCModes(xf86OutputPtr); +void NV50OutputDestroy(xf86OutputPtr); +Bool NV50CreateOutputs(ScrnInfoPtr); + +/* nv50_dac.c */ +xf86OutputPtr NV50CreateDac(ScrnInfoPtr, ORNum); +Bool NV50DacLoadDetect(xf86OutputPtr); + +/* nv50_sor.c */ +xf86OutputPtr NV50CreateSor(ScrnInfoPtr, ORNum); + +#endif diff --git a/src/nv50_sor.c b/src/nv50_sor.c new file mode 100644 index 0000000..d33bf4c --- /dev/null +++ b/src/nv50_sor.c @@ -0,0 +1,152 @@ +/* + * Copyright (c) 2007 NVIDIA, Corporation + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#define DPMS_SERVER +#include <X11/extensions/dpms.h> + +#include "nv_include.h" +#include "nv50_type.h" +#include "nv50_display.h" +#include "nv50_output.h" + +static void +NV50SorSetPClk(xf86OutputPtr output, int pclk) +{ + NVPtr pNv = NVPTR(output->scrn); + NV50OutputPrivPtr pPriv = output->driver_private; + const int orOff = 0x800 * pPriv->or; + + pNv->REGS[(0x00614300+orOff)/4] = (pclk > 165000) ? 0x101 : 0; +} + +static void +NV50SorDPMSSet(xf86OutputPtr output, int mode) +{ + NVPtr pNv = NVPTR(output->scrn); + NV50OutputPrivPtr pPriv = output->driver_private; + const int off = 0x800 * pPriv->or; + CARD32 tmp; + + while(pNv->REGS[(0x0061C004+off)/4] & 0x80000000); + + tmp = pNv->REGS[(0x0061C004+off)/4]; + tmp |= 0x80000000; + + if(mode == DPMSModeOn) + tmp |= 1; + else + tmp &= ~1; + + pNv->REGS[(0x0061C004+off)/4] = tmp; +} + +static void +NV50SorModeSet(xf86OutputPtr output, DisplayModePtr mode, + DisplayModePtr adjusted_mode) +{ + ScrnInfoPtr pScrn = output->scrn; + NV50OutputPrivPtr pPriv = output->driver_private; + const int sorOff = 0x40 * pPriv->or; + + if(!adjusted_mode) { + /* Disconnect the SOR */ + C(0x00000600 + sorOff, 0); + return; + } + + // This wouldn't be necessary, but the server is stupid and calls + // NV50SorDPMSSet after the output is disconnected, even though the hardware + // turns it off automatically. + NV50SorDPMSSet(output, DPMSModeOn); + + C(0x00000600 + sorOff, + (NV50CrtcGetHead(output->crtc) == HEAD0 ? 1 : 2) | + (adjusted_mode->Clock > 165000 ? 0x500 : 0x100) | + ((adjusted_mode->Flags & V_NHSYNC) ? 0x1000 : 0) | + ((adjusted_mode->Flags & V_NVSYNC) ? 0x2000 : 0)); +} + +static xf86OutputStatus +NV50SorDetect(xf86OutputPtr output) +{ + + NV50OutputPrivPtr pPriv = output->driver_private; + + /* Assume physical status isn't going to change before the BlockHandler */ + if(pPriv->cached_status != XF86OutputStatusUnknown) + return pPriv->cached_status; + + NV50OutputPartnersDetect(pPriv->partner, output, pPriv->i2c); + return pPriv->cached_status; +} + +static void +NV50SorDestroy(xf86OutputPtr output) +{ + NV50OutputDestroy(output); + + xfree(output->driver_private); + output->driver_private = NULL; +} + +static const xf86OutputFuncsRec NV50SorOutputFuncs = { + .dpms = NV50SorDPMSSet, + .save = NULL, + .restore = NULL, + .mode_valid = NV50OutputModeValid, + .mode_fixup = NV50OutputModeFixup, + .prepare = NV50OutputPrepare, + .commit = NV50OutputCommit, + .mode_set = NV50SorModeSet, + .detect = NV50SorDetect, + .get_modes = NV50OutputGetDDCModes, + .destroy = NV50SorDestroy, +}; + +xf86OutputPtr +NV50CreateSor(ScrnInfoPtr pScrn, ORNum or) +{ + NV50OutputPrivPtr pPriv = xnfcalloc(sizeof(*pPriv), 1); + xf86OutputPtr output; + char orName[5]; + + if(!pPriv) + return FALSE; + + snprintf(orName, 5, "DVI%i", or); + output = xf86OutputCreate(pScrn, &NV50SorOutputFuncs, orName); + + pPriv->type = SOR; + pPriv->or = or; + pPriv->cached_status = XF86OutputStatusUnknown; + pPriv->set_pclk = NV50SorSetPClk; + output->driver_private = pPriv; + output->interlaceAllowed = TRUE; + output->doubleScanAllowed = TRUE; + + return output; +} diff --git a/src/nv50_type.h b/src/nv50_type.h new file mode 100644 index 0000000..e3cba74 --- /dev/null +++ b/src/nv50_type.h @@ -0,0 +1,22 @@ +#ifndef __NV50_TYPE_H__ +#define __NV50_TYPE_H__ + +typedef enum Head { + HEAD0 = 0, + HEAD1 +} Head; + +typedef enum ORType { + DAC, + SOR +} ORType; + +typedef enum ORNum { + DAC0 = 0, + DAC1 = 1, + DAC2 = 2, + SOR0 = 0, + SOR1 = 1 +} ORNum; + +#endif diff --git a/src/nv_accel_common.c b/src/nv_accel_common.c index 805d698..23fc940 100644 --- a/src/nv_accel_common.c +++ b/src/nv_accel_common.c @@ -16,6 +16,21 @@ NVAccelInitNullObject(ScrnInfoPtr pScrn) return TRUE; } +static Bool +NVAccelInitNull3D(ScrnInfoPtr pScrn) +{ + NVPtr pNv = NVPTR(pScrn); + static int have_object = FALSE; + + if (!have_object) { + if (!NVDmaCreateContextObject(pNv, Nv3D, 0x30)) + return FALSE; + have_object = TRUE; + } + + return TRUE; +} + uint32_t NVAccelGetPixmapOffset(PixmapPtr pPix) { @@ -372,7 +387,10 @@ NVAccelInitMemFormat(ScrnInfoPtr pScrn) static int have_object = FALSE; uint32_t class; - class = NV_MEMORY_TO_MEMORY_FORMAT; + if (pNv->Architecture < NV_ARCH_50) + class = NV_MEMORY_TO_MEMORY_FORMAT; + else + class = NV_MEMORY_TO_MEMORY_FORMAT | 0x5000; if (!have_object) { if (!NVDmaCreateContextObject(pNv, NvMemFormat, class)) @@ -392,6 +410,39 @@ NVAccelInitMemFormat(ScrnInfoPtr pScrn) return TRUE; } +static Bool +NVAccelInit2D_NV50(ScrnInfoPtr pScrn) +{ + NVPtr pNv = NVPTR(pScrn); + static int have_object = FALSE; + + if (!have_object) { + if (!NVDmaCreateContextObject(pNv, Nv2D, 0x502d)) + return FALSE; + have_object = TRUE; + } + + NVDmaStart(pNv, Nv2D, 0x180, 3); + NVDmaNext (pNv, NvDmaNotifier0); + NVDmaNext (pNv, NvDmaFB); + NVDmaNext (pNv, NvDmaFB); + + /* Magics from nv, no clue what they do, but at least some + * of them are needed to avoid crashes. + */ + NVDmaStart(pNv, Nv2D, 0x260, 1); + NVDmaNext (pNv, 1); + NVDmaStart(pNv, Nv2D, 0x290, 1); + NVDmaNext (pNv, 1); + NVDmaStart(pNv, Nv2D, 0x29c, 1); + NVDmaNext (pNv, 0); + NVDmaStart(pNv, Nv2D, 0x58c, 1); + NVDmaNext (pNv, 0x111); + + pNv->currentRop = 0xfffffffa; + return TRUE; +} + #define INIT_CONTEXT_OBJECT(name) do { \ ret = NVAccelInit##name(pScrn); \ if (!ret) { \ @@ -407,31 +458,32 @@ NVAccelCommonInit(ScrnInfoPtr pScrn) { NVPtr pNv = NVPTR(pScrn); Bool ret; - if(pNv->NoAccel) return TRUE; INIT_CONTEXT_OBJECT(NullObject); INIT_CONTEXT_OBJECT(DmaNotifier0); - INIT_CONTEXT_OBJECT(ContextSurfaces); - INIT_CONTEXT_OBJECT(ImagePattern); - INIT_CONTEXT_OBJECT(RasterOp); - INIT_CONTEXT_OBJECT(Rectangle); - INIT_CONTEXT_OBJECT(ImageBlit); - INIT_CONTEXT_OBJECT(ScaledImage); - - /* XAA-only */ - INIT_CONTEXT_OBJECT(ClipRectangle); - INIT_CONTEXT_OBJECT(SolidLine); - - /* EXA-only */ + /* 2D engine */ + if (pNv->Architecture < NV_ARCH_50) { + INIT_CONTEXT_OBJECT(ContextSurfaces); + INIT_CONTEXT_OBJECT(ImagePattern); + INIT_CONTEXT_OBJECT(RasterOp); + INIT_CONTEXT_OBJECT(Rectangle); + INIT_CONTEXT_OBJECT(ImageBlit); + INIT_CONTEXT_OBJECT(ScaledImage); + INIT_CONTEXT_OBJECT(ClipRectangle); + INIT_CONTEXT_OBJECT(SolidLine); + } else { + INIT_CONTEXT_OBJECT(2D_NV50); + } INIT_CONTEXT_OBJECT(MemFormat); - /* 3D init */ + /* 3D engine */ switch (pNv->Architecture) { case NV_ARCH_40: INIT_CONTEXT_OBJECT(NV40TCL); break; default: + INIT_CONTEXT_OBJECT(Null3D); break; } diff --git a/src/nv_bios.c b/src/nv_bios.c index d093100..a5ecf66 100644 --- a/src/nv_bios.c +++ b/src/nv_bios.c @@ -31,6 +31,7 @@ * * PLL algorithms. */ +#include <byteswap.h> typedef struct { Bool execute; Bool repeat; @@ -1519,6 +1520,14 @@ static void parse_bit_structure(ScrnInfoPtr pScrn, bios_t *bios, unsigned int of } } +static unsigned short brs(unsigned char *data, int offset) +{ + unsigned short ret; + + ret = (data[offset]) | ((data[offset+1]) << 8); + return ret; +} + static void parse_pins_structure(ScrnInfoPtr pScrn, bios_t *bios, unsigned int offset) { int pins_version_major=bios->data[offset+5]; @@ -1527,7 +1536,6 @@ static void parse_pins_structure(ScrnInfoPtr pScrn, bios_t *bios, unsigned int o int init2 = bios->data[offset + 20] + (bios->data[offset + 21] * 256); int init_size = bios->data[offset + 22] + (bios->data[offset + 23] * 256) + 1; int ram_tab; - xf86DrvMsg(pScrn->scrnIndex, X_INFO, "PINS version %d.%d\n",pins_version_major,pins_version_minor); #if 0 @@ -1562,6 +1570,77 @@ static unsigned int findstr(bios_t* bios, unsigned char *str, int len) return 0; } +#define G5_FIXED_LOC 0xe2f8 + + +static unsigned int nv_find_dcb_table(ScrnInfoPtr pScrn, bios_t *bios) +{ + NVPtr pNv = NVPTR(pScrn); + CARD16 bufloc; + int is_g5 = 0; + CARD32 sig; + char *table2; + unsigned char headerSize, entries; + CARD32 header_word; + int i; + int sig_offsets[2] = { 0x4, 0x6 }; + int offset = -1; + + /* get the offset from 0x36 */ + + bufloc = *(CARD16 *)&bios->data[0x36]; + + if (bufloc == 0x0) { + if ((pNv->Chipset & 0x0ff0) == CHIPSET_NV43) { + is_g5 = 1; + bufloc = G5_FIXED_LOC; + } else { + return 0; + } + } + + table2 = &bios->data[bufloc]; + + /* lets play hunt the signature */ + for (i = 0; i < sizeof(sig_offsets) / sizeof(int); i++) { + sig = *(uint32_t*)(table2 + sig_offsets[i]); + if ((sig == 0x4edcbdcb) || (sig == 0xcbbddc4e)) { + offset = sig_offsets[i]; + break; + } + } + if (offset == -1) + return 0; + + if (offset == 6) { + header_word = *(uint32_t *)table2; + if (is_g5) { + headerSize = 0x3c; + entries = 0xa; + } else { + headerSize = (header_word >> 8) & 0xff; + entries = (header_word >> 16) & 0xff; + } + } else { + entries = 0xa; + headerSize = 0x8; + } + + ErrorF("DCB size is %02X, entries is %02X\n", headerSize, entries); + if (entries >= NV40_NUM_DCB_ENTRIES) + entries = NV40_NUM_DCB_ENTRIES; + + for (i = 0; i < entries; i++) { + if (is_g5) + pNv->dcb_table[i] = __bswap_32(*(uint32_t *)&table2[headerSize + 8 * i]); + else + pNv->dcb_table[i] = *(uint32_t *)&table2[headerSize + 8 * i]; + } + + return entries; +} + + unsigned int NVParseBios(ScrnInfoPtr pScrn) { unsigned int bit_offset; @@ -1591,6 +1670,15 @@ unsigned int NVParseBios(ScrnInfoPtr pScrn) xf86DrvMsg(pScrn->scrnIndex, X_INFO, "No known script signature found.\n"); } + /* look for NV40+ DCB table - and make a copy somewhere for output setup code */ + ret = nv_find_dcb_table(pScrn, &bios); + if (ret) + { + pNv->dcb_entries = ret; + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "DCB found %d entries.\n", ret); + } + else + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "No DCB table found\n"); xfree(bios.data); return 1; } diff --git a/src/nv_crtc.c b/src/nv_crtc.c new file mode 100644 index 0000000..97f06ef --- /dev/null +++ b/src/nv_crtc.c @@ -0,0 +1,1436 @@ +/* + * Copyright 2006 Dave Airlie + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECT + */ +/* + * this code uses ideas taken from the NVIDIA nv driver - the nvidia license + * decleration is at the bottom of this file as it is rather ugly + */ + + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <assert.h> +#include "xf86.h" +#include "os.h" +#include "mibank.h" +#include "globals.h" +#include "xf86.h" +#include "xf86Priv.h" +#include "xf86DDC.h" +#include "mipointer.h" +#include "windowstr.h" +#include <randrstr.h> +#include <X11/extensions/render.h> + +#include "xf86Crtc.h" +#include "nv_include.h" + +#include "vgaHW.h" + +#define CRTC_INDEX 0x3d4 +#define CRTC_DATA 0x3d5 +#define CRTC_IN_STAT_1 0x3da + +#define WHITE_VALUE 0x3F +#define BLACK_VALUE 0x00 +#define OVERSCAN_VALUE 0x01 + +static void nv_crtc_load_state_vga(xf86CrtcPtr crtc, RIVA_HW_STATE *state); +static void nv_crtc_load_state_ext (xf86CrtcPtr crtc, RIVA_HW_STATE *state); +static void nv_crtc_save_state_ext(xf86CrtcPtr crtc, RIVA_HW_STATE *state); +static void nv_crtc_save_state_vga(xf86CrtcPtr crtc, RIVA_HW_STATE *state); + +static void NVWriteMiscOut(xf86CrtcPtr crtc, CARD8 value) +{ + ScrnInfoPtr pScrn = crtc->scrn; + NVCrtcPrivatePtr nv_crtc = crtc->driver_private; + NVPtr pNv = NVPTR(pScrn); + + NV_WR08(pNv->PVIO, VGA_MISC_OUT_W, value); +} + +static CARD8 NVReadMiscOut(xf86CrtcPtr crtc) +{ + ScrnInfoPtr pScrn = crtc->scrn; + NVCrtcPrivatePtr nv_crtc = crtc->driver_private; + NVPtr pNv = NVPTR(pScrn); + + return NV_RD08(pNv->PVIO, VGA_MISC_OUT_R); +} + + +static void NVWriteVgaCrtc(xf86CrtcPtr crtc, CARD8 index, CARD8 value) +{ + ScrnInfoPtr pScrn = crtc->scrn; + NVCrtcPrivatePtr nv_crtc = crtc->driver_private; + NVPtr pNv = NVPTR(pScrn); + volatile CARD8 *pCRTCReg = nv_crtc->crtc ? pNv->PCIO1 : pNv->PCIO0; + + NV_WR08(pCRTCReg, CRTC_INDEX, index); + NV_WR08(pCRTCReg, CRTC_DATA, value); +} + +static CARD8 NVReadVgaCrtc(xf86CrtcPtr crtc, CARD8 index) +{ + ScrnInfoPtr pScrn = crtc->scrn; + NVCrtcPrivatePtr nv_crtc = crtc->driver_private; + NVPtr pNv = NVPTR(pScrn); + volatile CARD8 *pCRTCReg = nv_crtc->crtc ? pNv->PCIO1 : pNv->PCIO0; + + NV_WR08(pCRTCReg, CRTC_INDEX, index); + return NV_RD08(pCRTCReg, CRTC_DATA); +} + +static void NVWriteVgaSeq(xf86CrtcPtr crtc, CARD8 index, CARD8 value) +{ + ScrnInfoPtr pScrn = crtc->scrn; + NVCrtcPrivatePtr nv_crtc = crtc->driver_private; + NVPtr pNv = NVPTR(pScrn); + + NV_WR08(pNv->PVIO, VGA_SEQ_INDEX, index); + NV_WR08(pNv->PVIO, VGA_SEQ_DATA, value); +} + +static CARD8 NVReadVgaSeq(xf86CrtcPtr crtc, CARD8 index) +{ + ScrnInfoPtr pScrn = crtc->scrn; + NVCrtcPrivatePtr nv_crtc = crtc->driver_private; + NVPtr pNv = NVPTR(pScrn); + volatile CARD8 *pVGAReg = pNv->PVIO; + + NV_WR08(pNv->PVIO, VGA_SEQ_INDEX, index); + return NV_RD08(pNv->PVIO, VGA_SEQ_DATA); +} + +static void NVWriteVgaGr(xf86CrtcPtr crtc, CARD8 index, CARD8 value) +{ + ScrnInfoPtr pScrn = crtc->scrn; + NVCrtcPrivatePtr nv_crtc = crtc->driver_private; + NVPtr pNv = NVPTR(pScrn); + + NV_WR08(pNv->PVIO, VGA_GRAPH_INDEX, index); + NV_WR08(pNv->PVIO, VGA_GRAPH_DATA, value); +} + +static CARD8 NVReadVgaGr(xf86CrtcPtr crtc, CARD8 index) +{ + ScrnInfoPtr pScrn = crtc->scrn; + NVCrtcPrivatePtr nv_crtc = crtc->driver_private; + NVPtr pNv = NVPTR(pScrn); + volatile CARD8 *pVGAReg = pNv->PVIO; + + NV_WR08(pVGAReg, VGA_GRAPH_INDEX, index); + return NV_RD08(pVGAReg, VGA_GRAPH_DATA); +} + + +static void NVWriteVgaAttr(xf86CrtcPtr crtc, CARD8 index, CARD8 value) +{ + ScrnInfoPtr pScrn = crtc->scrn; + NVCrtcPrivatePtr nv_crtc = crtc->driver_private; + NVPtr pNv = NVPTR(pScrn); + volatile CARD8 *pCRTCReg = nv_crtc->crtc ? pNv->PCIO1 : pNv->PCIO0; + + NV_RD08(pCRTCReg, CRTC_IN_STAT_1); + if (nv_crtc->paletteEnabled) + index &= ~0x20; + else + index |= 0x20; + NV_WR08(pCRTCReg, VGA_ATTR_INDEX, index); + NV_WR08(pCRTCReg, VGA_ATTR_DATA_W, value); +} + +static CARD8 NVReadVgaAttr(xf86CrtcPtr crtc, CARD8 index) +{ + ScrnInfoPtr pScrn = crtc->scrn; + NVCrtcPrivatePtr nv_crtc = crtc->driver_private; + NVPtr pNv = NVPTR(pScrn); + volatile CARD8 *pCRTCReg = nv_crtc->crtc ? pNv->PCIO1 : pNv->PCIO0; + + NV_RD08(pCRTCReg, CRTC_IN_STAT_1); + if (nv_crtc->paletteEnabled) + index &= ~0x20; + else + index |= 0x20; + NV_WR08(pCRTCReg, VGA_ATTR_INDEX, index); + return NV_RD08(pCRTCReg, VGA_ATTR_DATA_R); +} + +void NVCrtcSetOwner(xf86CrtcPtr crtc) +{ + NVCrtcPrivatePtr nv_crtc = crtc->driver_private; + /*TODO beos double writes this on nv11 */ + NVWriteVgaCrtc(crtc, NV_VGA_CRTCX_OWNER, nv_crtc->crtc * 0x3); +} + +static void +NVEnablePalette(xf86CrtcPtr crtc) +{ + ScrnInfoPtr pScrn = crtc->scrn; + NVCrtcPrivatePtr nv_crtc = crtc->driver_private; + NVPtr pNv = NVPTR(pScrn); + volatile CARD8 *pCRTCReg = nv_crtc->crtc ? pNv->PCIO1 : pNv->PCIO0; + + NV_RD08(pCRTCReg, CRTC_IN_STAT_1); + NV_WR08(pCRTCReg, VGA_ATTR_INDEX, 0); + nv_crtc->paletteEnabled = TRUE; +} + +static void +NVDisablePalette(xf86CrtcPtr crtc) +{ + ScrnInfoPtr pScrn = crtc->scrn; + NVCrtcPrivatePtr nv_crtc = crtc->driver_private; + NVPtr pNv = NVPTR(pScrn); + volatile CARD8 *pCRTCReg = nv_crtc->crtc ? pNv->PCIO1 : pNv->PCIO0; + + NV_RD08(pCRTCReg, CRTC_IN_STAT_1); + NV_WR08(pCRTCReg, VGA_ATTR_INDEX, 0x20); + nv_crtc->paletteEnabled = FALSE; +} + +static void NVWriteVgaReg(xf86CrtcPtr crtc, CARD32 reg, CARD8 value) +{ + ScrnInfoPtr pScrn = crtc->scrn; + NVCrtcPrivatePtr nv_crtc = crtc->driver_private; + NVPtr pNv = NVPTR(pScrn); + volatile CARD8 *pCRTCReg = nv_crtc->crtc ? pNv->PCIO1 : pNv->PCIO0; + + NV_WR08(pCRTCReg, reg, value); +} + +/* perform a sequencer reset */ +static void NVVgaSeqReset(xf86CrtcPtr crtc, Bool start) +{ + if (start) + NVWriteVgaSeq(crtc, 0x00, 0x1); + else + NVWriteVgaSeq(crtc, 0x00, 0x3); + +} +static void NVVgaProtect(xf86CrtcPtr crtc, Bool on) +{ + CARD8 tmp; + + if (on) { + tmp = NVReadVgaSeq(crtc, 0x1); + NVVgaSeqReset(crtc, TRUE); + NVWriteVgaSeq(crtc, 0x01, tmp | 0x20); + + NVEnablePalette(crtc); + } else { + /* + * Reenable sequencer, then turn on screen. + */ + tmp = NVReadVgaSeq(crtc, 0x1); + NVWriteVgaSeq(crtc, 0x01, tmp & ~0x20); /* reenable display */ + NVVgaSeqReset(crtc, FALSE); + + NVDisablePalette(crtc); + } +} + +void NVCrtcLockUnlock(xf86CrtcPtr crtc, Bool Lock) +{ + CARD8 cr11; + + NVWriteVgaCrtc(crtc, NV_VGA_CRTCX_LOCK, Lock ? 0x99 : 0x57); + cr11 = NVReadVgaCrtc(crtc, NV_VGA_CRTCX_VSYNCE); + if (Lock) cr11 |= 0x80; + else cr11 &= ~0x80; + NVWriteVgaCrtc(crtc, NV_VGA_CRTCX_VSYNCE, cr11); +} +/* + * Calculate the Video Clock parameters for the PLL. + */ +static void CalcVClock ( + int clockIn, + int *clockOut, + CARD32 *pllOut, + NVPtr pNv +) +{ + unsigned lowM, highM; + unsigned DeltaNew, DeltaOld; + unsigned VClk, Freq; + unsigned M, N, P; + + DeltaOld = 0xFFFFFFFF; + + VClk = (unsigned)clockIn; + + if (pNv->CrystalFreqKHz == 13500) { + lowM = 7; + highM = 13; + } else { + lowM = 8; + highM = 14; + } + + for (P = 0; P <= 4; P++) { + Freq = VClk << P; + if ((Freq >= 128000) && (Freq <= 350000)) { + for (M = lowM; M <= highM; M++) { + N = ((VClk << P) * M) / pNv->CrystalFreqKHz; + if(N <= 255) { + Freq = ((pNv->CrystalFreqKHz * N) / M) >> P; + if (Freq > VClk) + DeltaNew = Freq - VClk; + else + DeltaNew = VClk - Freq; + if (DeltaNew < DeltaOld) { + *pllOut = (P << 16) | (N << 8) | M; + *clockOut = Freq; + DeltaOld = DeltaNew; + } + } + } + } + } +} + +static void CalcVClock2Stage ( + int clockIn, + int *clockOut, + CARD32 *pllOut, + CARD32 *pllBOut, + NVPtr pNv +) +{ + unsigned DeltaNew, DeltaOld; + unsigned VClk, Freq; + unsigned M, N, P; + + DeltaOld = 0xFFFFFFFF; + + *pllBOut = 0x80000401; /* fixed at x4 for now */ + + VClk = (unsigned)clockIn; + + for (P = 0; P <= 6; P++) { + Freq = VClk << P; + if ((Freq >= 400000) && (Freq <= 1000000)) { + for (M = 1; M <= 13; M++) { + N = ((VClk << P) * M) / (pNv->CrystalFreqKHz << 2); + if((N >= 5) && (N <= 255)) { + Freq = (((pNv->CrystalFreqKHz << 2) * N) / M) >> P; + if (Freq > VClk) + DeltaNew = Freq - VClk; + else + DeltaNew = VClk - Freq; + if (DeltaNew < DeltaOld) { + *pllOut = (P << 16) | (N << 8) | M; + *clockOut = Freq; + DeltaOld = DeltaNew; + } + } + } + } + } +} + +static void nv_crtc_save_state_pll(NVPtr pNv, RIVA_HW_STATE *state) +{ + state->vpll = nvReadRAMDAC0(pNv, NV_RAMDAC_VPLL); + if(pNv->twoHeads) + state->vpll2 = nvReadRAMDAC0(pNv, NV_RAMDAC_VPLL2); + if(pNv->twoStagePLL) { + state->vpllB = nvReadRAMDAC0(pNv, NV_RAMDAC_VPLL_B); + state->vpll2B = nvReadRAMDAC0(pNv, NV_RAMDAC_VPLL2_B); + } + state->pllsel = nvReadRAMDAC0(pNv, NV_RAMDAC_PLL_SELECT); +} + + +static void nv_crtc_load_state_pll(NVPtr pNv, RIVA_HW_STATE *state) +{ + nvWriteRAMDAC0(pNv, NV_RAMDAC_PLL_SELECT, state->pllsel); + + ErrorF("writting vpll %08X\n", state->vpll); + ErrorF("writting vpll2 %08X\n", state->vpll2); + nvWriteRAMDAC0(pNv, NV_RAMDAC_VPLL, state->vpll); + if(pNv->twoHeads) + nvWriteRAMDAC0(pNv, NV_RAMDAC_VPLL2, state->vpll2); + if(pNv->twoStagePLL) { + nvWriteRAMDAC0(pNv, NV_RAMDAC_VPLL_B, state->vpllB); + nvWriteRAMDAC0(pNv, NV_RAMDAC_VPLL2_B, state->vpll2B); + } +} + +/* + * Calculate extended mode parameters (SVGA) and save in a + * mode state structure. + */ +void nv_crtc_calc_state_ext( + xf86CrtcPtr crtc, + int bpp, + int width, + int hDisplaySize, + int height, + int dotClock, + int flags +) +{ + ScrnInfoPtr pScrn = crtc->scrn; + int pixelDepth, VClk; + CARD32 CursorStart; + NVCrtcPrivatePtr nv_crtc = crtc->driver_private; + xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn); + NVCrtcRegPtr regp; + NVPtr pNv = NVPTR(pScrn); + RIVA_HW_STATE *state; + int num_crtc_enabled, i; + + state = &pNv->ModeReg; + + regp = &pNv->ModeReg.crtc_reg[nv_crtc->crtc]; + + /* + * Extended RIVA registers. + */ + pixelDepth = (bpp + 1)/8; + if(pNv->twoStagePLL) + CalcVClock2Stage(dotClock, &VClk, &state->pll, &state->pllB, pNv); + else + CalcVClock(dotClock, &VClk, &state->pll, pNv); + + switch (pNv->Architecture) + { + case NV_ARCH_04: + nv4UpdateArbitrationSettings(VClk, + pixelDepth * 8, + &(state->arbitration0), + &(state->arbitration1), + pNv); + regp->CRTC[NV_VGA_CRTCX_CURCTL0] = 0x00; + regp->CRTC[NV_VGA_CRTCX_CURCTL1] = 0xbC; + if (flags & V_DBLSCAN) + regp->CRTC[NV_VGA_CRTCX_CURCTL1] |= 2; + regp->CRTC[NV_VGA_CRTCX_CURCTL2] = 0x00000000; + state->pllsel |= NV_RAMDAC_PLL_SELECT_VCLK_RATIO_DB2 | NV_RAMDAC_PLL_SELECT_PLL_SOURCE_ALL; + state->config = 0x00001114; + regp->CRTC[NV_VGA_CRTCX_REPAINT1] = hDisplaySize < 1280 ? 0x04 : 0x00; + break; + case NV_ARCH_10: + case NV_ARCH_20: + case NV_ARCH_30: + default: + if(((pNv->Chipset & 0xfff0) == CHIPSET_C51) || + ((pNv->Chipset & 0xfff0) == CHIPSET_C512)) + { + state->arbitration0 = 128; + state->arbitration1 = 0x0480; + } else + if(((pNv->Chipset & 0xffff) == CHIPSET_NFORCE) || + ((pNv->Chipset & 0xffff) == CHIPSET_NFORCE2)) + { + nForceUpdateArbitrationSettings(VClk, + pixelDepth * 8, + &(state->arbitration0), + &(state->arbitration1), + pNv); + } else if(pNv->Architecture < NV_ARCH_30) { + nv10UpdateArbitrationSettings(VClk, + pixelDepth * 8, + &(state->arbitration0), + &(state->arbitration1), + pNv); + } else { + nv30UpdateArbitrationSettings(pNv, + &(state->arbitration0), + &(state->arbitration1)); + } + + + CursorStart = pNv->Cursor->offset; + + regp->CRTC[NV_VGA_CRTCX_CURCTL0] = 0x80 | (CursorStart >> 17); + regp->CRTC[NV_VGA_CRTCX_CURCTL1] = (CursorStart >> 11) << 2; + regp->CRTC[NV_VGA_CRTCX_CURCTL2] = CursorStart >> 24; + + if (flags & V_DBLSCAN) + regp->CRTC[NV_VGA_CRTCX_CURCTL1]|= 2; + + + state->config = nvReadFB(pNv, NV_PFB_CFG0); + regp->CRTC[NV_VGA_CRTCX_REPAINT1] = hDisplaySize < 1280 ? 0x04 : 0x00; + break; + } + + /* okay do we have 2 CRTCs running ? */ + num_crtc_enabled = 0; + for (i = 0; i < xf86_config->num_crtc; i++) { + if (xf86_config->crtc[i]->enabled) + num_crtc_enabled++; + } + + if (num_crtc_enabled > 1) { + if (nv_crtc->crtc == 1) { + state->vpll2 = state->pll; + state->vpll2B = state->pllB; + state->pllsel |= (1<<29) | (1<<11); + } else { + state->vpll = state->pll; + state->vpllB = state->pllB; + state->pllsel |= NV_RAMDAC_PLL_SELECT_PLL_SOURCE_ALL; + state->pllsel &= ~NV_RAMDAC_PLL_SELECT_VCLK_RATIO_DB2; + } + } else { + state->vpll = state->pll; + state->vpllB = state->pllB; + state->pllsel |= NV_RAMDAC_PLL_SELECT_PLL_SOURCE_ALL; + state->pllsel &= ~NV_RAMDAC_PLL_SELECT_VCLK_RATIO_DB2; + } + + + regp->CRTC[NV_VGA_CRTCX_FIFO0] = state->arbitration0; + regp->CRTC[NV_VGA_CRTCX_FIFO_LWM] = state->arbitration1 & 0xff; + if (pNv->Architecture >= NV_ARCH_30) { + regp->CRTC[NV_VGA_CRTCX_FIFO_LWM_NV30] = state->arbitration1 >> 8; + } + + + regp->CRTC[NV_VGA_CRTCX_REPAINT0] = (((width / 8) * pixelDepth) & 0x700) >> 3; + regp->CRTC[NV_VGA_CRTCX_PIXEL] = (pixelDepth > 2) ? 3 : pixelDepth; +} + + +static void +nv_crtc_dpms(xf86CrtcPtr crtc, int mode) +{ + NVCrtcPrivatePtr nv_crtc = crtc->driver_private; + unsigned char seq1 = 0, crtc17 = 0; + unsigned char crtc1A; + int ret; + + NVCrtcSetOwner(crtc); + + crtc1A = NVReadVgaCrtc(crtc, NV_VGA_CRTCX_REPAINT1) & ~0xC0; + switch(mode) { + case DPMSModeStandby: + /* Screen: Off; HSync: Off, VSync: On -- Not Supported */ + seq1 = 0x20; + crtc17 = 0x80; + crtc1A |= 0x80; + break; + case DPMSModeSuspend: + /* Screen: Off; HSync: On, VSync: Off -- Not Supported */ + seq1 = 0x20; + crtc17 = 0x80; + crtc1A |= 0x40; + break; + case DPMSModeOff: + /* Screen: Off; HSync: Off, VSync: Off */ + seq1 = 0x20; + crtc17 = 0x00; + crtc1A |= 0xC0; + break; + case DPMSModeOn: + default: + /* Screen: On; HSync: On, VSync: On */ + seq1 = 0x00; + crtc17 = 0x80; + break; + } + + NVWriteVgaSeq(crtc, 0x00, 0x1); + seq1 = NVReadVgaSeq(crtc, 0x01) & ~0x20; + NVWriteVgaSeq(crtc, 0x1, seq1); + crtc17 |= NVReadVgaCrtc(crtc, NV_VGA_CRTCX_MODECTL) & ~0x80; + usleep(10000); + NVWriteVgaCrtc(crtc, NV_VGA_CRTCX_MODECTL, crtc17); + NVWriteVgaSeq(crtc, 0x0, 0x3); + + NVWriteVgaCrtc(crtc, NV_VGA_CRTCX_REPAINT1, crtc1A); + +} + +static Bool +nv_crtc_mode_fixup(xf86CrtcPtr crtc, DisplayModePtr mode, + DisplayModePtr adjusted_mode) +{ + return TRUE; +} + +static void +nv_crtc_mode_set_vga(xf86CrtcPtr crtc, DisplayModePtr mode) +{ + ScrnInfoPtr pScrn = crtc->scrn; + NVCrtcPrivatePtr nv_crtc = crtc->driver_private; + NVCrtcRegPtr regp; + NVPtr pNv = NVPTR(pScrn); + int depth = pScrn->depth; + unsigned int i; + + regp = &pNv->ModeReg.crtc_reg[nv_crtc->crtc]; + + + /* + * compute correct Hsync & Vsync polarity + */ + if ((mode->Flags & (V_PHSYNC | V_NHSYNC)) + && (mode->Flags & (V_PVSYNC | V_NVSYNC))) + { + regp->MiscOutReg = 0x23; + if (mode->Flags & V_NHSYNC) regp->MiscOutReg |= 0x40; + if (mode->Flags & V_NVSYNC) regp->MiscOutReg |= 0x80; + } + else + { + int VDisplay = mode->VDisplay; + if (mode->Flags & V_DBLSCAN) + VDisplay *= 2; + if (mode->VScan > 1) + VDisplay *= mode->VScan; + if (VDisplay < 400) + regp->MiscOutReg = 0xA3; /* +hsync -vsync */ + else if (VDisplay < 480) + regp->MiscOutReg = 0x63; /* -hsync +vsync */ + else if (VDisplay < 768) + regp->MiscOutReg = 0xE3; /* -hsync -vsync */ + else + regp->MiscOutReg = 0x23; /* +hsync +vsync */ + } + + regp->MiscOutReg |= (mode->ClockIndex & 0x03) << 2; + + /* + * Time Sequencer + */ + if (depth == 4) + regp->Sequencer[0] = 0x02; + else + regp->Sequencer[0] = 0x00; + if (mode->Flags & V_CLKDIV2) + regp->Sequencer[1] = 0x09; + else + regp->Sequencer[1] = 0x01; + if (depth == 1) + regp->Sequencer[2] = 1 << BIT_PLANE; + else + regp->Sequencer[2] = 0x0F; + regp->Sequencer[3] = 0x00; /* Font select */ + if (depth < 8) + regp->Sequencer[4] = 0x06; /* Misc */ + else + regp->Sequencer[4] = 0x0E; /* Misc */ + + /* + * CRTC Controller + */ + regp->CRTC[0] = (mode->CrtcHTotal >> 3) - 5; + regp->CRTC[1] = (mode->CrtcHDisplay >> 3) - 1; + regp->CRTC[2] = (mode->CrtcHBlankStart >> 3) - 1; + regp->CRTC[3] = (((mode->CrtcHBlankEnd >> 3) - 1) & 0x1F) | 0x80; + i = (((mode->CrtcHSkew << 2) + 0x10) & ~0x1F); + if (i < 0x80) + regp->CRTC[3] |= i; + regp->CRTC[4] = (mode->CrtcHSyncStart >> 3); + regp->CRTC[5] = ((((mode->CrtcHBlankEnd >> 3) - 1) & 0x20) << 2) + | (((mode->CrtcHSyncEnd >> 3)) & 0x1F); + regp->CRTC[6] = (mode->CrtcVTotal - 2) & 0xFF; + regp->CRTC[7] = (((mode->CrtcVTotal - 2) & 0x100) >> 8) + | (((mode->CrtcVDisplay - 1) & 0x100) >> 7) + | ((mode->CrtcVSyncStart & 0x100) >> 6) + | (((mode->CrtcVBlankStart - 1) & 0x100) >> 5) + | 0x10 + | (((mode->CrtcVTotal - 2) & 0x200) >> 4) + | (((mode->CrtcVDisplay - 1) & 0x200) >> 3) + | ((mode->CrtcVSyncStart & 0x200) >> 2); + regp->CRTC[8] = 0x00; + regp->CRTC[9] = (((mode->CrtcVBlankStart - 1) & 0x200) >> 4) | 0x40; + if (mode->Flags & V_DBLSCAN) + regp->CRTC[9] |= 0x80; + if (mode->VScan >= 32) + regp->CRTC[9] |= 0x1F; + else if (mode->VScan > 1) + regp->CRTC[9] |= mode->VScan - 1; + regp->CRTC[10] = 0x00; + regp->CRTC[11] = 0x00; + regp->CRTC[12] = 0x00; + regp->CRTC[13] = 0x00; + regp->CRTC[14] = 0x00; + regp->CRTC[15] = 0x00; + regp->CRTC[16] = mode->CrtcVSyncStart & 0xFF; + regp->CRTC[17] = (mode->CrtcVSyncEnd & 0x0F) | 0x20; + regp->CRTC[18] = (mode->CrtcVDisplay - 1) & 0xFF; + regp->CRTC[19] = mode->CrtcHDisplay >> 4; /* just a guess */ + regp->CRTC[20] = 0x00; + regp->CRTC[21] = (mode->CrtcVBlankStart - 1) & 0xFF; + regp->CRTC[22] = (mode->CrtcVBlankEnd - 1) & 0xFF; + if (depth < 8) + regp->CRTC[23] = 0xE3; + else + regp->CRTC[23] = 0xC3; + regp->CRTC[24] = 0xFF; + + /* + * Theory resumes here.... + */ + + /* + * Graphics Display Controller + */ + regp->Graphics[0] = 0x00; + regp->Graphics[1] = 0x00; + regp->Graphics[2] = 0x00; + regp->Graphics[3] = 0x00; + if (depth == 1) { + regp->Graphics[4] = BIT_PLANE; + regp->Graphics[5] = 0x00; + } else { + regp->Graphics[4] = 0x00; + if (depth == 4) + regp->Graphics[5] = 0x02; + else + regp->Graphics[5] = 0x40; + } + regp->Graphics[6] = 0x05; /* only map 64k VGA memory !!!! */ + regp->Graphics[7] = 0x0F; + regp->Graphics[8] = 0xFF; + + if (depth == 1) { + /* Initialise the Mono map according to which bit-plane gets used */ + + Bool flipPixels = xf86GetFlipPixels(); + + for (i=0; i<16; i++) + if (((i & (1 << BIT_PLANE)) != 0) != flipPixels) + regp->Attribute[i] = WHITE_VALUE; + else + regp->Attribute[i] = BLACK_VALUE; + + } else { + regp->Attribute[0] = 0x00; /* standard colormap translation */ + regp->Attribute[1] = 0x01; + regp->Attribute[2] = 0x02; + regp->Attribute[3] = 0x03; + regp->Attribute[4] = 0x04; + regp->Attribute[5] = 0x05; + regp->Attribute[6] = 0x06; + regp->Attribute[7] = 0x07; + regp->Attribute[8] = 0x08; + regp->Attribute[9] = 0x09; + regp->Attribute[10] = 0x0A; + regp->Attribute[11] = 0x0B; + regp->Attribute[12] = 0x0C; + regp->Attribute[13] = 0x0D; + regp->Attribute[14] = 0x0E; + regp->Attribute[15] = 0x0F; + if (depth == 4) + regp->Attribute[16] = 0x81; /* wrong for the ET4000 */ + else + regp->Attribute[16] = 0x41; /* wrong for the ET4000 */ + if (depth > 4) + regp->Attribute[17] = 0xff; + /* Attribute[17] (overscan) initialised in vgaHWGetHWRec() */ + } + regp->Attribute[18] = 0x0F; + regp->Attribute[19] = 0x00; + regp->Attribute[20] = 0x00; + +} + + + +/** + * Sets up registers for the given mode/adjusted_mode pair. + * + * The clocks, CRTCs and outputs attached to this CRTC must be off. + * + * This shouldn't enable any clocks, CRTCs, or outputs, but they should + * be easily turned on/off after this. + */ +static void +nv_crtc_mode_set_regs(xf86CrtcPtr crtc, DisplayModePtr mode) +{ + ScrnInfoPtr pScrn = crtc->scrn; + NVPtr pNv = NVPTR(pScrn); + NVRegPtr state = &pNv->ModeReg; + xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn); + NVCrtcPrivatePtr nv_crtc = crtc->driver_private; + NVFBLayout *pLayout = &pNv->CurrentLayout; + NVCrtcRegPtr regp, savep; + unsigned int i; + int horizDisplay = (mode->CrtcHDisplay/8) - 1; + int horizStart = (mode->CrtcHSyncStart/8) - 1; + int horizEnd = (mode->CrtcHSyncEnd/8) - 1; + int horizTotal = (mode->CrtcHTotal/8) - 5; + int horizBlankStart = (mode->CrtcHDisplay/8) - 1; + int horizBlankEnd = (mode->CrtcHTotal/8) - 1; + int vertDisplay = mode->CrtcVDisplay - 1; + int vertStart = mode->CrtcVSyncStart - 1; + int vertEnd = mode->CrtcVSyncEnd - 1; + int vertTotal = mode->CrtcVTotal - 2; + int vertBlankStart = mode->CrtcVDisplay - 1; + int vertBlankEnd = mode->CrtcVTotal - 1; + Bool is_fp = FALSE; + + for (i = 0; i < xf86_config->num_output; i++) { + xf86OutputPtr output = xf86_config->output[i]; + NVOutputPrivatePtr nv_output = output->driver_private; + + if (output->crtc == crtc) + if ((nv_output->type == OUTPUT_PANEL) || + (nv_output->type == OUTPUT_DIGITAL)) + is_fp = TRUE; + + } + + regp = &pNv->ModeReg.crtc_reg[nv_crtc->crtc]; + savep = &pNv->SavedReg.crtc_reg[nv_crtc->crtc]; + + if(mode->Flags & V_INTERLACE) + vertTotal |= 1; + + regp->CRTC[NV_VGA_CRTCX_HTOTAL] = Set8Bits(horizTotal); + regp->CRTC[NV_VGA_CRTCX_HDISPE] = Set8Bits(horizDisplay); + regp->CRTC[NV_VGA_CRTCX_HBLANKS] = Set8Bits(horizBlankStart); + regp->CRTC[NV_VGA_CRTCX_HBLANKE] = SetBitField(horizBlankEnd,4:0,4:0) + | SetBit(7); + regp->CRTC[NV_VGA_CRTCX_HSYNCS] = Set8Bits(horizStart); + regp->CRTC[NV_VGA_CRTCX_HSYNCE] = SetBitField(horizBlankEnd,5:5,7:7) + | SetBitField(horizEnd,4:0,4:0); + regp->CRTC[NV_VGA_CRTCX_VTOTAL] = SetBitField(vertTotal,7:0,7:0); + regp->CRTC[NV_VGA_CRTCX_OVERFLOW] = SetBitField(vertTotal,8:8,0:0) + | SetBitField(vertDisplay,8:8,1:1) + | SetBitField(vertStart,8:8,2:2) + | SetBitField(vertBlankStart,8:8,3:3) + | SetBit(4) + | SetBitField(vertTotal,9:9,5:5) + | SetBitField(vertDisplay,9:9,6:6) + | SetBitField(vertStart,9:9,7:7); + regp->CRTC[NV_VGA_CRTCX_MAXSCLIN] = SetBitField(vertBlankStart,9:9,5:5) + | SetBit(6) + | ((mode->Flags & V_DBLSCAN) ? 0x80 : 0x00); + regp->CRTC[NV_VGA_CRTCX_VSYNCS] = Set8Bits(vertStart); + regp->CRTC[NV_VGA_CRTCX_VSYNCE] = SetBitField(vertEnd,3:0,3:0) | SetBit(5); + regp->CRTC[NV_VGA_CRTCX_VDISPE] = Set8Bits(vertDisplay); + regp->CRTC[NV_VGA_CRTCX_PITCHL] = ((pLayout->displayWidth/8)*(pLayout->bitsPerPixel/8)); + regp->CRTC[NV_VGA_CRTCX_VBLANKS] = Set8Bits(vertBlankStart); + regp->CRTC[NV_VGA_CRTCX_VBLANKE] = Set8Bits(vertBlankEnd); + + regp->Attribute[0x10] = 0x01; + + if(pNv->Television) + regp->Attribute[0x11] = 0x00; + + regp->CRTC[NV_VGA_CRTCX_LSR] = SetBitField(horizBlankEnd,6:6,4:4) + | SetBitField(vertBlankStart,10:10,3:3) + | SetBitField(vertStart,10:10,2:2) + | SetBitField(vertDisplay,10:10,1:1) + | SetBitField(vertTotal,10:10,0:0); + + regp->CRTC[NV_VGA_CRTCX_HEB] = SetBitField(horizTotal,8:8,0:0) + | SetBitField(horizDisplay,8:8,1:1) + | SetBitField(horizBlankStart,8:8,2:2) + | SetBitField(horizStart,8:8,3:3); + + regp->CRTC[NV_VGA_CRTCX_EXTRA] = SetBitField(vertTotal,11:11,0:0) + | SetBitField(vertDisplay,11:11,2:2) + | SetBitField(vertStart,11:11,4:4) + | SetBitField(vertBlankStart,11:11,6:6); + + if(mode->Flags & V_INTERLACE) { + horizTotal = (horizTotal >> 1) & ~1; + regp->CRTC[NV_VGA_CRTCX_INTERLACE] = Set8Bits(horizTotal); + regp->CRTC[NV_VGA_CRTCX_HEB] |= SetBitField(horizTotal,8:8,4:4); + } else { + regp->CRTC[NV_VGA_CRTCX_INTERLACE] = 0xff; /* interlace off */ + } + + regp->CRTC[NV_VGA_CRTCX_BUFFER] = 0xfa; + + if (is_fp) { + regp->CRTC[NV_VGA_CRTCX_LCD] = savep->CRTC[NV_VGA_CRTCX_LCD] | 1; + /* this turns on the DFP on nv28 outputs */ + regp->CRTC[NV_VGA_CRTCX_59] = savep->CRTC[NV_VGA_CRTCX_59] | 1; + } else { + regp->CRTC[NV_VGA_CRTCX_LCD] = savep->CRTC[NV_VGA_CRTCX_LCD] & ~1; + } + + /* + * Initialize DAC palette. + */ + if(pLayout->bitsPerPixel != 8 ) + { + for (i = 0; i < 256; i++) + { + regp->DAC[i*3] = i; + regp->DAC[(i*3)+1] = i; + regp->DAC[(i*3)+2] = i; + } + } + + /* + * Calculate the extended registers. + */ + + if(pLayout->depth < 24) + i = pLayout->depth; + else i = 32; + + if(pNv->Architecture >= NV_ARCH_10) + pNv->CURSOR = (CARD32 *)pNv->Cursor->map; + + ErrorF("crtc %d %d %d\n", nv_crtc->crtc, mode->CrtcHDisplay, pLayout->displayWidth); + nv_crtc_calc_state_ext(crtc, + i, + pLayout->displayWidth, + mode->CrtcHDisplay, + mode->CrtcVDisplay, + mode->Clock, + mode->Flags); + + if (is_fp) + regp->CRTC[NV_VGA_CRTCX_PIXEL] |= (1 << 7); + + regp->CRTC[NV_VGA_CRTCX_FIFO1] = savep->CRTC[NV_VGA_CRTCX_FIFO1] & ~(1<<5); + + if(nv_crtc->crtc) { + if (is_fp) { + regp->head &= ~NV_CRTC_FSEL_FPP2; + regp->head |= NV_CRTC_FSEL_FPP1; + } else { + regp->head &= ~NV_CRTC_FSEL_FPP1; + regp->head |= NV_CRTC_FSEL_FPP2; + } + + regp->crtcOwner = 3; + /* only enable secondary pllsel if CRTC 1 is selected on */ + + } else { + if(pNv->twoHeads) { + regp->head = savep->head | 0x00001000; + if (is_fp) { + regp->head &= ~NV_CRTC_FSEL_FPP2; + regp->head |= NV_CRTC_FSEL_FPP1; + } else { + regp->head &= ~NV_CRTC_FSEL_FPP1; + regp->head |= NV_CRTC_FSEL_FPP2; + } + + regp->crtcOwner = 0; + } + } + + regp->cursorConfig = 0x00000100; + if(mode->Flags & V_DBLSCAN) + regp->cursorConfig |= (1 << 4); + if(pNv->alphaCursor) { + if((pNv->Chipset & 0x0ff0) != CHIPSET_NV11) + regp->cursorConfig |= 0x04011000; + else + regp->cursorConfig |= 0x14011000; + } else + regp->cursorConfig |= 0x02000000; + + regp->CRTC[NV_VGA_CRTCX_FP_HTIMING] = 0; + regp->CRTC[NV_VGA_CRTCX_FP_VTIMING] = 0; + + regp->unk830 = mode->CrtcVDisplay - 3; + regp->unk834 = mode->CrtcVDisplay - 1; +} + +/** + * Sets up registers for the given mode/adjusted_mode pair. + * + * The clocks, CRTCs and outputs attached to this CRTC must be off. + * + * This shouldn't enable any clocks, CRTCs, or outputs, but they should + * be easily turned on/off after this. + */ +static void +nv_crtc_mode_set(xf86CrtcPtr crtc, DisplayModePtr mode, + DisplayModePtr adjusted_mode, + int x, int y) +{ + ScrnInfoPtr pScrn = crtc->scrn; + NVCrtcPrivatePtr nv_crtc = crtc->driver_private; + NVPtr pNv = NVPTR(pScrn); + + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "Mode on CRTC %d\n", nv_crtc->crtc); + xf86PrintModeline(pScrn->scrnIndex, mode); + NVCrtcSetOwner(crtc); + + nv_crtc_mode_set_vga(crtc, mode); + nv_crtc_mode_set_regs(crtc, mode); + + + NVVgaProtect(crtc, TRUE); + nv_crtc_load_state_ext(crtc, &pNv->ModeReg); + nv_crtc_load_state_vga(crtc, &pNv->ModeReg); + nv_crtc_load_state_pll(pNv, &pNv->ModeReg); + + NVVgaProtect(crtc, FALSE); + // NVCrtcLockUnlock(crtc, 1); + + NVCrtcSetBase(crtc, x, y); +#if X_BYTE_ORDER == X_BIG_ENDIAN + /* turn on LFB swapping */ + { + unsigned char tmp; + + tmp = NVReadVgaCrtc(crtc, NV_VGA_CRTCX_SWAPPING); + tmp |= (1 << 7); + NVWriteVgaCrtc(crtc, NV_VGA_CRTCX_SWAPPING, tmp); + } +#endif + +} + +void nv_crtc_save(xf86CrtcPtr crtc) +{ + ScrnInfoPtr pScrn = crtc->scrn; + NVCrtcPrivatePtr nv_crtc = crtc->driver_private; + NVPtr pNv = NVPTR(pScrn); + + NVCrtcSetOwner(crtc); + nv_crtc_save_state_pll(pNv, &pNv->SavedReg); + nv_crtc_save_state_vga(crtc, &pNv->SavedReg); + nv_crtc_save_state_ext(crtc, &pNv->SavedReg); + +} + +void nv_crtc_restore(xf86CrtcPtr crtc) +{ + ScrnInfoPtr pScrn = crtc->scrn; + NVCrtcPrivatePtr nv_crtc = crtc->driver_private; + NVPtr pNv = NVPTR(pScrn); + + NVCrtcSetOwner(crtc); + nv_crtc_load_state_ext(crtc, &pNv->SavedReg); + nv_crtc_load_state_vga(crtc, &pNv->SavedReg); + nv_crtc_load_state_pll(pNv, &pNv->SavedReg); + nvWriteVGA(pNv, NV_VGA_CRTCX_OWNER, pNv->vtOWNER); + +} + +void nv_crtc_prepare(xf86CrtcPtr crtc) +{ + ScrnInfoPtr pScrn = crtc->scrn; + NVPtr pNv = NVPTR(pScrn); + /* Sync the engine before adjust mode */ +if (pNv->AccelInfoRec && pNv->AccelInfoRec->NeedToSync) { + (*pNv->AccelInfoRec->Sync)(pScrn); + pNv->AccelInfoRec->NeedToSync = FALSE; +} + +} + +void nv_crtc_commit(xf86CrtcPtr crtc) +{ + + +} + +static Bool nv_crtc_lock(xf86CrtcPtr crtc) +{ + return FALSE; +} + +static void nv_crtc_unlock(xf86CrtcPtr crtc) +{ + +} + +static const xf86CrtcFuncsRec nv_crtc_funcs = { + .dpms = nv_crtc_dpms, + .save = nv_crtc_save, /* XXX */ + .restore = nv_crtc_restore, /* XXX */ + .mode_fixup = nv_crtc_mode_fixup, + .mode_set = nv_crtc_mode_set, + .prepare = nv_crtc_prepare, + .commit = nv_crtc_commit, + .destroy = NULL, /* XXX */ + .lock = nv_crtc_lock, + .unlock = nv_crtc_unlock, +}; + +void +nv_crtc_init(ScrnInfoPtr pScrn, int crtc_num) +{ + NVPtr pNv = NVPTR(pScrn); + xf86CrtcPtr crtc; + NVCrtcPrivatePtr nv_crtc; + + crtc = xf86CrtcCreate (pScrn, &nv_crtc_funcs); + if (crtc == NULL) + return; + + nv_crtc = xnfcalloc (sizeof (NVCrtcPrivateRec), 1); + nv_crtc->crtc = crtc_num; + + crtc->driver_private = nv_crtc; + + NVCrtcLockUnlock(crtc, 0); + +} + +static void nv_crtc_load_state_vga(xf86CrtcPtr crtc, RIVA_HW_STATE *state) +{ + ScrnInfoPtr pScrn = crtc->scrn; + NVPtr pNv = NVPTR(pScrn); + NVCrtcPrivatePtr nv_crtc = crtc->driver_private; + int i, j; + CARD32 temp; + NVCrtcRegPtr regp; + + regp = &state->crtc_reg[nv_crtc->crtc]; + + NVWriteMiscOut(crtc, regp->MiscOutReg); + + for (i = 1; i < 5; i++) + NVWriteVgaSeq(crtc, i, regp->Sequencer[i]); + + /* Ensure CRTC registers 0-7 are unlocked by clearing bit 7 of CRTC[17] */ + NVWriteVgaCrtc(crtc, 17, regp->CRTC[17] & ~0x80); + + for (i = 0; i < 25; i++) + NVWriteVgaCrtc(crtc, i, regp->CRTC[i]); + + for (i = 0; i < 9; i++) + NVWriteVgaGr(crtc, i, regp->Graphics[i]); + + NVEnablePalette(crtc); + for (i = 0; i < 21; i++) + NVWriteVgaAttr(crtc, i, regp->Attribute[i]); + NVDisablePalette(crtc); + +} + +static void nv_crtc_fix_nv40_hw_cursor(xf86CrtcPtr crtc) +{ + /* TODO - implement this properly */ + ScrnInfoPtr pScrn = crtc->scrn; + NVPtr pNv = NVPTR(pScrn); + + if(pNv->Architecture == NV_ARCH_40) { /* HW bug */ + volatile CARD32 curpos = nvReadCurRAMDAC(pNv, NV_RAMDAC_CURSOR_POS); + nvWriteCurRAMDAC(pNv, NV_RAMDAC_CURSOR_POS, curpos); + } + +} +static void nv_crtc_load_state_ext(xf86CrtcPtr crtc, RIVA_HW_STATE *state) +{ + ScrnInfoPtr pScrn = crtc->scrn; + NVPtr pNv = NVPTR(pScrn); + NVCrtcPrivatePtr nv_crtc = crtc->driver_private; + int i, j; + CARD32 temp; + NVCrtcRegPtr regp; + + regp = &state->crtc_reg[nv_crtc->crtc]; + + if(pNv->Architecture >= NV_ARCH_10) { + if(pNv->twoHeads) { + nvWriteCRTC(pNv, nv_crtc->crtc, NV_CRTC_FSEL, regp->head); + } + nvWriteVIDEO(pNv, NV_PVIDEO_STOP, 1); + nvWriteVIDEO(pNv, NV_PVIDEO_INTR_EN, 0); + nvWriteVIDEO(pNv, NV_PVIDEO_OFFSET_BUFF(0), 0); + nvWriteVIDEO(pNv, NV_PVIDEO_OFFSET_BUFF(1), 0); + nvWriteVIDEO(pNv, NV_PVIDEO_LIMIT(0), pNv->VRAMPhysicalSize - 1); + nvWriteVIDEO(pNv, NV_PVIDEO_LIMIT(1), pNv->VRAMPhysicalSize - 1); + nvWriteMC(pNv, 0x1588, 0); + + NVWriteVgaCrtc(crtc, NV_VGA_CRTCX_BUFFER, 0xff); + NVWriteVgaCrtc(crtc, NV_VGA_CRTCX_BUFFER, regp->CRTC[NV_VGA_CRTCX_BUFFER]); + nvWriteCRTC(pNv, nv_crtc->crtc, NV_CRTC_CURSOR_CONFIG, regp->cursorConfig); + nvWriteCRTC(pNv, nv_crtc->crtc, NV_CRTC_0830, regp->unk830); + nvWriteCRTC(pNv, nv_crtc->crtc, NV_CRTC_0834, regp->unk834); + + NVWriteVgaCrtc(crtc, NV_VGA_CRTCX_FP_HTIMING, regp->CRTC[NV_VGA_CRTCX_FP_HTIMING]); + NVWriteVgaCrtc(crtc, NV_VGA_CRTCX_FP_VTIMING, regp->CRTC[NV_VGA_CRTCX_FP_VTIMING]); + + NVWriteVgaCrtc(crtc, NV_VGA_CRTCX_59, regp->CRTC[NV_VGA_CRTCX_59]); + NVWriteVgaCrtc(crtc, NV_VGA_CRTCX_EXTRA, regp->CRTC[NV_VGA_CRTCX_EXTRA]); + } + + NVWriteVgaCrtc(crtc, NV_VGA_CRTCX_REPAINT0, regp->CRTC[NV_VGA_CRTCX_REPAINT0]); + NVWriteVgaCrtc(crtc, NV_VGA_CRTCX_REPAINT1, regp->CRTC[NV_VGA_CRTCX_REPAINT1]); + NVWriteVgaCrtc(crtc, NV_VGA_CRTCX_LSR, regp->CRTC[NV_VGA_CRTCX_LSR]); + NVWriteVgaCrtc(crtc, NV_VGA_CRTCX_PIXEL, regp->CRTC[NV_VGA_CRTCX_PIXEL]); + NVWriteVgaCrtc(crtc, NV_VGA_CRTCX_LCD, regp->CRTC[NV_VGA_CRTCX_LCD]); + NVWriteVgaCrtc(crtc, NV_VGA_CRTCX_HEB, regp->CRTC[NV_VGA_CRTCX_HEB]); + NVWriteVgaCrtc(crtc, NV_VGA_CRTCX_FIFO1, regp->CRTC[NV_VGA_CRTCX_FIFO1]); + NVWriteVgaCrtc(crtc, NV_VGA_CRTCX_FIFO0, regp->CRTC[NV_VGA_CRTCX_FIFO0]); + NVWriteVgaCrtc(crtc, NV_VGA_CRTCX_FIFO_LWM, regp->CRTC[NV_VGA_CRTCX_FIFO_LWM]); + if(pNv->Architecture >= NV_ARCH_30) { + NVWriteVgaCrtc(crtc, NV_VGA_CRTCX_FIFO_LWM_NV30, regp->CRTC[NV_VGA_CRTCX_FIFO_LWM_NV30]); + } + + NVWriteVgaCrtc(crtc, NV_VGA_CRTCX_CURCTL0, regp->CRTC[NV_VGA_CRTCX_CURCTL0]); + NVWriteVgaCrtc(crtc, NV_VGA_CRTCX_CURCTL1, regp->CRTC[NV_VGA_CRTCX_CURCTL1]); + nv_crtc_fix_nv40_hw_cursor(crtc); + NVWriteVgaCrtc(crtc, NV_VGA_CRTCX_CURCTL2, regp->CRTC[NV_VGA_CRTCX_CURCTL2]); + NVWriteVgaCrtc(crtc, NV_VGA_CRTCX_INTERLACE, regp->CRTC[NV_VGA_CRTCX_INTERLACE]); + + nvWriteCRTC(pNv, nv_crtc->crtc, NV_CRTC_INTR_EN_0, 0); + nvWriteCRTC(pNv, nv_crtc->crtc, NV_CRTC_INTR_0, NV_CRTC_INTR_VBLANK); + + pNv->CurrentState = state; +} + +static void nv_crtc_save_state_vga(xf86CrtcPtr crtc, RIVA_HW_STATE *state) +{ + ScrnInfoPtr pScrn = crtc->scrn; + NVPtr pNv = NVPTR(pScrn); + NVCrtcPrivatePtr nv_crtc = crtc->driver_private; + int i; + NVCrtcRegPtr regp; + + regp = &state->crtc_reg[nv_crtc->crtc]; + + regp->MiscOutReg = NVReadMiscOut(crtc); + + for (i = 0; i < 25; i++) + regp->CRTC[i] = NVReadVgaCrtc(crtc, i); + + NVEnablePalette(crtc); + for (i = 0; i < 21; i++) + regp->Attribute[i] = NVReadVgaAttr(crtc, i); + NVDisablePalette(crtc); + + for (i = 0; i < 9; i++) + regp->Graphics[i] = NVReadVgaGr(crtc, i); + + for (i = 1; i < 5; i++) + regp->Sequencer[i] = NVReadVgaSeq(crtc, i); + +} + +static void nv_crtc_save_state_ext(xf86CrtcPtr crtc, RIVA_HW_STATE *state) +{ + ScrnInfoPtr pScrn = crtc->scrn; + NVPtr pNv = NVPTR(pScrn); + NVCrtcPrivatePtr nv_crtc = crtc->driver_private; + NVCrtcRegPtr regp; + int i; + + regp = &state->crtc_reg[nv_crtc->crtc]; + + regp->CRTC[NV_VGA_CRTCX_59] = NVReadVgaCrtc(crtc, NV_VGA_CRTCX_59); + regp->CRTC[NV_VGA_CRTCX_LCD] = NVReadVgaCrtc(crtc, NV_VGA_CRTCX_LCD); + regp->CRTC[NV_VGA_CRTCX_REPAINT0] = NVReadVgaCrtc(crtc, NV_VGA_CRTCX_REPAINT0); + regp->CRTC[NV_VGA_CRTCX_REPAINT1] = NVReadVgaCrtc(crtc, NV_VGA_CRTCX_REPAINT1); + regp->CRTC[NV_VGA_CRTCX_LSR] = NVReadVgaCrtc(crtc, NV_VGA_CRTCX_LSR); + regp->CRTC[NV_VGA_CRTCX_PIXEL] = NVReadVgaCrtc(crtc, NV_VGA_CRTCX_PIXEL); + regp->CRTC[NV_VGA_CRTCX_HEB] = NVReadVgaCrtc(crtc, NV_VGA_CRTCX_HEB); + regp->CRTC[NV_VGA_CRTCX_FIFO1] = NVReadVgaCrtc(crtc, NV_VGA_CRTCX_FIFO1); + + regp->CRTC[NV_VGA_CRTCX_FIFO0] = NVReadVgaCrtc(crtc, NV_VGA_CRTCX_FIFO0); + regp->CRTC[NV_VGA_CRTCX_FIFO_LWM] = NVReadVgaCrtc(crtc, NV_VGA_CRTCX_FIFO_LWM); + if(pNv->Architecture >= NV_ARCH_30) { + regp->CRTC[NV_VGA_CRTCX_FIFO_LWM_NV30] = NVReadVgaCrtc(crtc, NV_VGA_CRTCX_FIFO_LWM_NV30); + } + regp->CRTC[NV_VGA_CRTCX_CURCTL0] = NVReadVgaCrtc(crtc, NV_VGA_CRTCX_CURCTL0); + regp->CRTC[NV_VGA_CRTCX_CURCTL1] = NVReadVgaCrtc(crtc, NV_VGA_CRTCX_CURCTL1); + regp->CRTC[NV_VGA_CRTCX_CURCTL2] = NVReadVgaCrtc(crtc, NV_VGA_CRTCX_CURCTL2); + regp->CRTC[NV_VGA_CRTCX_INTERLACE] = NVReadVgaCrtc(crtc, NV_VGA_CRTCX_INTERLACE); + + regp->unk830 = nvReadCRTC(pNv, nv_crtc->crtc, NV_CRTC_0830); + regp->unk834 = nvReadCRTC(pNv, nv_crtc->crtc, NV_CRTC_0834); + + if(pNv->Architecture >= NV_ARCH_10) { + if(pNv->twoHeads) { + regp->head = nvReadCRTC(pNv, nv_crtc->crtc, NV_CRTC_FSEL); + regp->crtcOwner = NVReadVgaCrtc(crtc, NV_VGA_CRTCX_OWNER); + } + regp->CRTC[NV_VGA_CRTCX_EXTRA] = NVReadVgaCrtc(crtc, NV_VGA_CRTCX_EXTRA); + + regp->cursorConfig = nvReadCRTC(pNv, nv_crtc->crtc, NV_CRTC_CURSOR_CONFIG); + + regp->CRTC[NV_VGA_CRTCX_BUFFER] = NVReadVgaCrtc(crtc, NV_VGA_CRTCX_BUFFER); + regp->CRTC[NV_VGA_CRTCX_FP_HTIMING] = NVReadVgaCrtc(crtc, NV_VGA_CRTCX_FP_HTIMING); + regp->CRTC[NV_VGA_CRTCX_FP_VTIMING] = NVReadVgaCrtc(crtc, NV_VGA_CRTCX_FP_VTIMING); + } +} + +void +NVCrtcSetBase (xf86CrtcPtr crtc, int x, int y) +{ + ScrnInfoPtr pScrn = crtc->scrn; + NVPtr pNv = NVPTR(pScrn); + NVCrtcPrivatePtr nv_crtc = crtc->driver_private; + NVFBLayout *pLayout = &pNv->CurrentLayout; + CARD32 start = 0; + + start += ((y * pScrn->displayWidth + x) * (pLayout->bitsPerPixel/8)); + start += pNv->FB->offset; + + nvWriteCRTC(pNv, nv_crtc->crtc, NV_CRTC_START, start); + + crtc->x = x; + crtc->y = y; +} + +void NVCrtcSetCursor(xf86CrtcPtr crtc, Bool state) +{ + int current = NVReadVgaCrtc(crtc, NV_VGA_CRTCX_CURCTL1); + + if(state) + current |= 1; + else + current &= ~1; + + NVWriteVgaCrtc(crtc, NV_VGA_CRTCX_CURCTL1, current); +} + +static void NVCrtcWriteDacMask(xf86CrtcPtr crtc, CARD8 value) +{ + ScrnInfoPtr pScrn = crtc->scrn; + NVCrtcPrivatePtr nv_crtc = crtc->driver_private; + NVPtr pNv = NVPTR(pScrn); + volatile CARD8 *pDACReg = nv_crtc->crtc ? pNv->PDIO1 : pNv->PDIO0; + + NV_WR08(pDACReg, VGA_DAC_MASK, value); +} + +static CARD8 NVCrtcReadDacMask(xf86CrtcPtr crtc) +{ + ScrnInfoPtr pScrn = crtc->scrn; + NVCrtcPrivatePtr nv_crtc = crtc->driver_private; + NVPtr pNv = NVPTR(pScrn); + volatile CARD8 *pDACReg = nv_crtc->crtc ? pNv->PDIO1 : pNv->PDIO0; + + return NV_RD08(pDACReg, VGA_DAC_MASK); +} + +static void NVCrtcWriteDacReadAddr(xf86CrtcPtr crtc, CARD8 value) +{ + ScrnInfoPtr pScrn = crtc->scrn; + NVCrtcPrivatePtr nv_crtc = crtc->driver_private; + NVPtr pNv = NVPTR(pScrn); + volatile CARD8 *pDACReg = nv_crtc->crtc ? pNv->PDIO1 : pNv->PDIO0; + + NV_WR08(pDACReg, VGA_DAC_READ_ADDR, value); +} + +static void NVCrtcWriteDacWriteAddr(xf86CrtcPtr crtc, CARD8 value) +{ + ScrnInfoPtr pScrn = crtc->scrn; + NVCrtcPrivatePtr nv_crtc = crtc->driver_private; + NVPtr pNv = NVPTR(pScrn); + volatile CARD8 *pDACReg = nv_crtc->crtc ? pNv->PDIO1 : pNv->PDIO0; + + NV_WR08(pDACReg, VGA_DAC_WRITE_ADDR, value); +} + +static void NVCrtcWriteDacData(xf86CrtcPtr crtc, CARD8 value) +{ + ScrnInfoPtr pScrn = crtc->scrn; + NVCrtcPrivatePtr nv_crtc = crtc->driver_private; + NVPtr pNv = NVPTR(pScrn); + volatile CARD8 *pDACReg = nv_crtc->crtc ? pNv->PDIO1 : pNv->PDIO0; + + NV_WR08(pDACReg, VGA_DAC_DATA, value); +} + +static CARD8 NVCrtcReadDacData(xf86CrtcPtr crtc, CARD8 value) +{ + ScrnInfoPtr pScrn = crtc->scrn; + NVCrtcPrivatePtr nv_crtc = crtc->driver_private; + NVPtr pNv = NVPTR(pScrn); + volatile CARD8 *pDACReg = nv_crtc->crtc ? pNv->PDIO1 : pNv->PDIO0; + + return NV_RD08(pDACReg, VGA_DAC_DATA); +} + +void NVCrtcLoadPalette(xf86CrtcPtr crtc) +{ + int i; + NVCrtcPrivatePtr nv_crtc = crtc->driver_private; + NVCrtcRegPtr regp; + ScrnInfoPtr pScrn = crtc->scrn; + NVPtr pNv = NVPTR(pScrn); + + regp = &pNv->ModeReg.crtc_reg[nv_crtc->crtc]; + + NVWriteVgaCrtc(crtc, NV_VGA_CRTCX_OWNER, nv_crtc->crtc * 0x3); + NVCrtcWriteDacMask(crtc, 0xff); + NVCrtcWriteDacWriteAddr(crtc, 0x00); + + for (i = 0; i<768; i++) { + NVCrtcWriteDacData(crtc, regp->DAC[i]); + } + NVDisablePalette(crtc); +} + +void NVCrtcBlankScreen(xf86CrtcPtr crtc, Bool on) +{ + NVCrtcPrivatePtr nv_crtc = crtc->driver_private; + unsigned char scrn; + + NVWriteVgaCrtc(crtc, NV_VGA_CRTCX_OWNER, nv_crtc->crtc * 0x3); + + scrn = NVReadVgaSeq(crtc, 0x01); + if (on) { + scrn &= ~0x20; + } else { + scrn |= 0x20; + } + + NVVgaSeqReset(crtc, TRUE); + NVWriteVgaSeq(crtc, 0x01, scrn); + NVVgaSeqReset(crtc, FALSE); +} + +/*************************************************************************** \ +|* *| +|* Copyright 1993-2003 NVIDIA, Corporation. All rights reserved. *| +|* *| +|* NOTICE TO USER: The source code is copyrighted under U.S. and *| +|* international laws. Users and possessors of this source code are *| +|* hereby granted a nonexclusive, royalty-free copyright license to *| +|* use this code in individual and commercial software. *| +|* *| +|* Any use of this source code must include, in the user documenta- *| +|* tion and internal comments to the code, notices to the end user *| +|* as follows: *| +|* *| +|* Copyright 1993-1999 NVIDIA, Corporation. All rights reserved. *| +|* *| +|* NVIDIA, CORPORATION MAKES NO REPRESENTATION ABOUT THE SUITABILITY *| +|* OF THIS SOURCE CODE FOR ANY PURPOSE. IT IS PROVIDED "AS IS" *| +|* WITHOUT EXPRESS OR IMPLIED WARRANTY OF ANY KIND. NVIDIA, CORPOR- *| +|* ATION DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOURCE CODE, *| +|* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGE- *| +|* MENT, AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL *| +|* NVIDIA, CORPORATION BE LIABLE FOR ANY SPECIAL, INDIRECT, INCI- *| +|* DENTAL, OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RE- *| +|* SULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION *| +|* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF *| +|* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOURCE CODE. *| +|* *| +|* U.S. Government End Users. This source code is a "commercial *| +|* item," as that term is defined at 48 C.F.R. 2.101 (OCT 1995), *| +|* consisting of "commercial computer software" and "commercial *| +|* computer software documentation," as such terms are used in *| +|* 48 C.F.R. 12.212 (SEPT 1995) and is provided to the U.S. Govern- *| +|* ment only as a commercial end item. Consistent with 48 C.F.R. *| +|* 12.212 and 48 C.F.R. 227.7202-1 through 227.7202-4 (JUNE 1995), *| +|* all U.S. Government End Users acquire the source code with only *| +|* those rights set forth herein. *| +|* *| + \***************************************************************************/ diff --git a/src/nv_cursor.c b/src/nv_cursor.c index 88f1874..4be0b4e 100644 --- a/src/nv_cursor.c +++ b/src/nv_cursor.c @@ -49,6 +49,13 @@ * * \****************************************************************************/ +#define NV_CURSOR_X 64 +#define NV_CURSOR_Y 64 + +#define CURSOR_X_SHIFT 0 +#define CURSOR_Y_SHIFT 16 +#define CURSOR_POS_MASK 0xffff + #define TRANSPARENT_PIXEL 0 #define ConvertToRGB555(c) (((c & 0xf80000) >> 9 ) | /* Blue */ \ @@ -166,12 +173,55 @@ NVLoadCursorImage( ScrnInfoPtr pScrn, unsigned char *src ) TransformCursor(pNv); } + static void NVSetCursorPosition(ScrnInfoPtr pScrn, int x, int y) { + xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn); NVPtr pNv = NVPTR(pScrn); - - nvWriteCurRAMDAC(pNv, NV_RAMDAC_CURSOR_POS, (x & 0xFFFF) | (y << 16)); + xf86CrtcPtr crtc; + NVCrtcPrivatePtr nv_crtc; + DisplayModePtr mode; + int thisx; + int thisy; + int o; + Bool inrange; + CARD32 temp; + + for (o = 0; o < xf86_config->num_output; o++) + { + xf86OutputPtr output = xf86_config->output[o]; + + if (!output->crtc) + continue; + + if (!output->crtc->enabled) + continue; + + crtc = output->crtc; + mode = &crtc->mode; + thisx = x - crtc->x; + thisy = y - crtc->y; + + inrange = TRUE; + if (thisx >= mode->HDisplay || + thisy >= mode->VDisplay || + thisx <= -NV_CURSOR_X || thisy <= -NV_CURSOR_Y) + { + inrange = FALSE; + thisx = 0; + thisy = 0; + } + + temp = 0; + temp |= ((thisx & CURSOR_POS_MASK) << CURSOR_X_SHIFT); + temp |= ((thisy & CURSOR_POS_MASK) << CURSOR_Y_SHIFT); + + nv_crtc = output->crtc->driver_private; + + nvWriteRAMDAC(pNv, nv_crtc->crtc, NV_RAMDAC_CURSOR_POS, temp); + + } } static void @@ -209,20 +259,28 @@ NVSetCursorColors(ScrnInfoPtr pScrn, int bg, int fg) } -static void +static void NVShowCursor(ScrnInfoPtr pScrn) { - NVPtr pNv = NVPTR(pScrn); - /* Enable cursor - X-Windows mode */ - NVShowHideCursor(pNv, 1); + xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn); + NVPtr pNv = NVPTR(pScrn); + int c; + + pNv->cursorOn = TRUE; + for (c= 0; c < xf86_config->num_crtc; c++) + NVCrtcSetCursor (xf86_config->crtc[c], TRUE); } static void NVHideCursor(ScrnInfoPtr pScrn) { - NVPtr pNv = NVPTR(pScrn); - /* Disable cursor */ - NVShowHideCursor(pNv, 0); + xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn); + NVPtr pNv = NVPTR(pScrn); + int c; + + pNv->cursorOn = FALSE; + for (c = 0; c < xf86_config->num_crtc; c++) + NVCrtcSetCursor (xf86_config->crtc[c], TRUE); } static Bool diff --git a/src/nv_dac.c b/src/nv_dac.c deleted file mode 100644 index f6cbd28..0000000 --- a/src/nv_dac.c +++ /dev/null @@ -1,425 +0,0 @@ - /***************************************************************************\ -|* *| -|* Copyright 2003 NVIDIA, Corporation. All rights reserved. *| -|* *| -|* NOTICE TO USER: The source code is copyrighted under U.S. and *| -|* international laws. Users and possessors of this source code are *| -|* hereby granted a nonexclusive, royalty-free copyright license to *| -|* use this code in individual and commercial software. *| -|* *| -|* Any use of this source code must include, in the user documenta- *| -|* tion and internal comments to the code, notices to the end user *| -|* as follows: *| -|* *| -|* Copyright 2003 NVIDIA, Corporation. All rights reserved. *| -|* *| -|* NVIDIA, CORPORATION MAKES NO REPRESENTATION ABOUT THE SUITABILITY *| -|* OF THIS SOURCE CODE FOR ANY PURPOSE. IT IS PROVIDED "AS IS" *| -|* WITHOUT EXPRESS OR IMPLIED WARRANTY OF ANY KIND. NVIDIA, CORPOR- *| -|* ATION DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOURCE CODE, *| -|* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGE- *| -|* MENT, AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL *| -|* NVIDIA, CORPORATION BE LIABLE FOR ANY SPECIAL, INDIRECT, INCI- *| -|* DENTAL, OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RE- *| -|* SULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION *| -|* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF *| -|* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOURCE CODE. *| -|* *| -|* U.S. Government End Users. This source code is a "commercial *| -|* item," as that term is defined at 48 C.F.R. 2.101 (OCT 1995), *| -|* consisting of "commercial computer software" and "commercial *| -|* computer software documentation," as such terms are used in *| -|* 48 C.F.R. 12.212 (SEPT 1995) and is provided to the U.S. Govern- *| -|* ment only as a commercial end item. Consistent with 48 C.F.R. *| -|* 12.212 and 48 C.F.R. 227.7202-1 through 227.7202-4 (JUNE 1995), *| -|* all U.S. Government End Users acquire the source code with only *| -|* those rights set forth herein. *| -|* *| - \***************************************************************************/ - -/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/nv/nv_dac.c,v 1.45 2005/07/09 00:53:00 mvojkovi Exp $ */ - -#include "nv_include.h" - -static int -NVDACPanelTweaks(NVPtr pNv, NVRegPtr state) -{ - int tweak = 0; - - if(pNv->usePanelTweak) { - tweak = pNv->PanelTweak; - } else { - /* begin flat panel hacks */ - /* This is unfortunate, but some chips need this register - tweaked or else you get artifacts where adjacent pixels are - swapped. There are no hard rules for what to set here so all - we can do is experiment and apply hacks. */ - - if(((pNv->Chipset & 0xffff) == 0x0328) && (state->bpp == 32)) { - /* At least one NV34 laptop needs this workaround. */ - tweak = -1; - } - - if((pNv->Chipset & 0xfff0) == CHIPSET_NV31) { - tweak = 1; - } - /* end flat panel hacks */ - } - - return tweak; -} - -Bool -NVDACInit(ScrnInfoPtr pScrn, DisplayModePtr mode) -{ - int i; - int horizDisplay = (mode->CrtcHDisplay/8) - 1; - int horizStart = (mode->CrtcHSyncStart/8) - 1; - int horizEnd = (mode->CrtcHSyncEnd/8) - 1; - int horizTotal = (mode->CrtcHTotal/8) - 5; - int horizBlankStart = (mode->CrtcHDisplay/8) - 1; - int horizBlankEnd = (mode->CrtcHTotal/8) - 1; - int vertDisplay = mode->CrtcVDisplay - 1; - int vertStart = mode->CrtcVSyncStart - 1; - int vertEnd = mode->CrtcVSyncEnd - 1; - int vertTotal = mode->CrtcVTotal - 2; - int vertBlankStart = mode->CrtcVDisplay - 1; - int vertBlankEnd = mode->CrtcVTotal - 1; - - NVPtr pNv = NVPTR(pScrn); - NVRegPtr nvReg = &pNv->ModeReg; - NVFBLayout *pLayout = &pNv->CurrentLayout; - vgaRegPtr pVga; - - /* - * Initialize all of the generic VGA registers. Don't bother with - * VGA_FIX_SYNC_PULSES, given the relevant CRTC settings are overridden - * below. Ditto for the KGA workaround. - */ - if (!vgaHWInit(pScrn, mode)) - return(FALSE); - - pVga = &VGAHWPTR(pScrn)->ModeReg; - - /* - * Set all CRTC values. - */ - - if(mode->Flags & V_INTERLACE) - vertTotal |= 1; - - if(pNv->FlatPanel == 1) { - vertStart = vertTotal - 3; - vertEnd = vertTotal - 2; - vertBlankStart = vertStart; - horizStart = horizTotal - 5; - horizEnd = horizTotal - 2; - horizBlankEnd = horizTotal + 4; - } - - pVga->CRTC[0x0] = Set8Bits(horizTotal); - pVga->CRTC[0x1] = Set8Bits(horizDisplay); - pVga->CRTC[0x2] = Set8Bits(horizBlankStart); - pVga->CRTC[0x3] = SetBitField(horizBlankEnd,4:0,4:0) - | SetBit(7); - pVga->CRTC[0x4] = Set8Bits(horizStart); - pVga->CRTC[0x5] = SetBitField(horizBlankEnd,5:5,7:7) - | SetBitField(horizEnd,4:0,4:0); - pVga->CRTC[0x6] = SetBitField(vertTotal,7:0,7:0); - pVga->CRTC[0x7] = SetBitField(vertTotal,8:8,0:0) - | SetBitField(vertDisplay,8:8,1:1) - | SetBitField(vertStart,8:8,2:2) - | SetBitField(vertBlankStart,8:8,3:3) - | SetBit(4) - | SetBitField(vertTotal,9:9,5:5) - | SetBitField(vertDisplay,9:9,6:6) - | SetBitField(vertStart,9:9,7:7); - pVga->CRTC[0x9] = SetBitField(vertBlankStart,9:9,5:5) - | SetBit(6) - | ((mode->Flags & V_DBLSCAN) ? 0x80 : 0x00); - pVga->CRTC[0x10] = Set8Bits(vertStart); - pVga->CRTC[0x11] = SetBitField(vertEnd,3:0,3:0) | SetBit(5); - pVga->CRTC[0x12] = Set8Bits(vertDisplay); - pVga->CRTC[0x13] = ((pLayout->displayWidth/8)*(pLayout->bitsPerPixel/8)); - pVga->CRTC[0x15] = Set8Bits(vertBlankStart); - pVga->CRTC[0x16] = Set8Bits(vertBlankEnd); - - pVga->Attribute[0x10] = 0x01; - - if(pNv->Television) - pVga->Attribute[0x11] = 0x00; - - nvReg->screen = SetBitField(horizBlankEnd,6:6,4:4) - | SetBitField(vertBlankStart,10:10,3:3) - | SetBitField(vertStart,10:10,2:2) - | SetBitField(vertDisplay,10:10,1:1) - | SetBitField(vertTotal,10:10,0:0); - - nvReg->horiz = SetBitField(horizTotal,8:8,0:0) - | SetBitField(horizDisplay,8:8,1:1) - | SetBitField(horizBlankStart,8:8,2:2) - | SetBitField(horizStart,8:8,3:3); - - nvReg->extra = SetBitField(vertTotal,11:11,0:0) - | SetBitField(vertDisplay,11:11,2:2) - | SetBitField(vertStart,11:11,4:4) - | SetBitField(vertBlankStart,11:11,6:6); - - if(mode->Flags & V_INTERLACE) { - horizTotal = (horizTotal >> 1) & ~1; - nvReg->interlace = Set8Bits(horizTotal); - nvReg->horiz |= SetBitField(horizTotal,8:8,4:4); - } else { - nvReg->interlace = 0xff; /* interlace off */ - } - - - /* - * Initialize DAC palette. - */ - if(pLayout->bitsPerPixel != 8 ) - { - for (i = 0; i < 256; i++) - { - pVga->DAC[i*3] = i; - pVga->DAC[(i*3)+1] = i; - pVga->DAC[(i*3)+2] = i; - } - } - - /* - * Calculate the extended registers. - */ - - if(pLayout->depth < 24) - i = pLayout->depth; - else i = 32; - - if(pNv->Architecture >= NV_ARCH_10) - pNv->CURSOR = (CARD32 *)pNv->Cursor->map; - - NVCalcStateExt(pNv, - nvReg, - i, - pLayout->displayWidth, - mode->CrtcHDisplay, - pScrn->virtualY, - mode->Clock, - mode->Flags); - - nvReg->scale = nvReadCurRAMDAC(pNv, NV_RAMDAC_FP_CONTROL) & 0xfff000ff; - if(pNv->FlatPanel == 1) { - nvReg->pixel |= (1 << 7); - if(!pNv->fpScaler || (pNv->fpWidth <= mode->HDisplay) - || (pNv->fpHeight <= mode->VDisplay)) - { - nvReg->scale |= (1 << 8) ; - } - nvReg->crtcSync = nvReadCurRAMDAC(pNv, NV_RAMDAC_FP_HCRTC); - nvReg->crtcSync += NVDACPanelTweaks(pNv, nvReg); - } - - nvReg->vpll = nvReg->pll; - nvReg->vpll2 = nvReg->pll; - nvReg->vpllB = nvReg->pllB; - nvReg->vpll2B = nvReg->pllB; - - nvReg->fifo = nvReadVGA(pNv, 0x1c) & ~(1<<5); - - if(pNv->CRTCnumber) { - nvReg->head = nvReadCRTC(pNv, 0, NV_CRTC_HEAD_CONFIG) & ~0x00001000; - nvReg->head2 = nvReadCRTC(pNv, 1, NV_CRTC_HEAD_CONFIG) | 0x00001000; - nvReg->crtcOwner = 3; - nvReg->pllsel |= 0x20000800; - nvReg->vpll = nvReadRAMDAC0(pNv, NV_RAMDAC_VPLL); - if(pNv->twoStagePLL) - nvReg->vpllB = nvReadRAMDAC0(pNv, NV_RAMDAC_VPLL_B); - } else - if(pNv->twoHeads) { - nvReg->head = nvReadCRTC(pNv, 0, NV_CRTC_HEAD_CONFIG) | 0x00001000; - nvReg->head2 = nvReadCRTC(pNv, 1, NV_CRTC_HEAD_CONFIG) & ~0x00001000; - nvReg->crtcOwner = 0; - nvReg->vpll2 = nvReadRAMDAC0(pNv, NV_RAMDAC_VPLL2); - if(pNv->twoStagePLL) - nvReg->vpll2B = nvReadRAMDAC0(pNv, NV_RAMDAC_VPLL2_B); - } - - nvReg->cursorConfig = 0x00000100; - if(mode->Flags & V_DBLSCAN) - nvReg->cursorConfig |= (1 << 4); - if(pNv->alphaCursor) { - if((pNv->Chipset & 0x0ff0) != CHIPSET_NV11) - nvReg->cursorConfig |= 0x04011000; - else - nvReg->cursorConfig |= 0x14011000; - nvReg->general |= (1 << 29); - } else - nvReg->cursorConfig |= 0x02000000; - - if(pNv->twoHeads) { - if((pNv->Chipset & 0x0ff0) == CHIPSET_NV11) { - nvReg->dither = nvReadCurRAMDAC(pNv, NV_RAMDAC_DITHER_NV11) & ~0x00010000; - if(pNv->FPDither) - nvReg->dither |= 0x00010000; - } else { - nvReg->dither = nvReadCurRAMDAC(pNv, NV_RAMDAC_FP_DITHER) & ~1; - if(pNv->FPDither) - nvReg->dither |= 1; - } - } - - nvReg->timingH = 0; - nvReg->timingV = 0; - nvReg->displayV = mode->CrtcVDisplay; - - return (TRUE); -} - -void -NVDACRestore(ScrnInfoPtr pScrn, vgaRegPtr vgaReg, NVRegPtr nvReg, - Bool primary) -{ - NVPtr pNv = NVPTR(pScrn); - int restore = VGA_SR_MODE; - - if(primary) restore |= VGA_SR_CMAP | VGA_SR_FONTS; - NVLoadStateExt(pScrn, nvReg); -#if defined(__powerpc__) - restore &= ~VGA_SR_FONTS; -#endif - vgaHWRestore(pScrn, vgaReg, restore); -} - -/* - * NVDACSave - * - * This function saves the video state. - */ -void -NVDACSave(ScrnInfoPtr pScrn, vgaRegPtr vgaReg, NVRegPtr nvReg, - Bool saveFonts) -{ - NVPtr pNv = NVPTR(pScrn); - -#if defined(__powerpc__) - saveFonts = FALSE; -#endif - - vgaHWSave(pScrn, vgaReg, VGA_SR_CMAP | VGA_SR_MODE | - (saveFonts? VGA_SR_FONTS : 0)); - NVUnloadStateExt(pNv, nvReg); - - /* can't read this reliably on NV11 */ - if((pNv->Chipset & 0x0ff0) == CHIPSET_NV11) - nvReg->crtcOwner = pNv->CRTCnumber; -} - -#define DEPTH_SHIFT(val, w) ((val << (8 - w)) | (val >> ((w << 1) - 8))) -#define MAKE_INDEX(in, w) (DEPTH_SHIFT(in, w) * 3) - -void -NVDACLoadPalette(ScrnInfoPtr pScrn, int numColors, int *indices, LOCO *colors, - VisualPtr pVisual ) -{ - int i, index; - NVPtr pNv = NVPTR(pScrn); - vgaRegPtr pVga; - - pVga = &VGAHWPTR(pScrn)->ModeReg; - - switch(pNv->CurrentLayout.depth) { - case 15: - for(i = 0; i < numColors; i++) { - index = indices[i]; - pVga->DAC[MAKE_INDEX(index, 5) + 0] = colors[index].red; - pVga->DAC[MAKE_INDEX(index, 5) + 1] = colors[index].green; - pVga->DAC[MAKE_INDEX(index, 5) + 2] = colors[index].blue; - } - break; - case 16: - for(i = 0; i < numColors; i++) { - index = indices[i]; - pVga->DAC[MAKE_INDEX(index, 6) + 1] = colors[index].green; - if(index < 32) { - pVga->DAC[MAKE_INDEX(index, 5) + 0] = colors[index].red; - pVga->DAC[MAKE_INDEX(index, 5) + 2] = colors[index].blue; - } - } - break; - default: - for(i = 0; i < numColors; i++) { - index = indices[i]; - pVga->DAC[index*3] = colors[index].red; - pVga->DAC[(index*3)+1] = colors[index].green; - pVga->DAC[(index*3)+2] = colors[index].blue; - } - break; - } - vgaHWRestore(pScrn, pVga, VGA_SR_CMAP); -} - -/* - * DDC1 support only requires DDC_SDA_MASK, - * DDC2 support requires DDC_SDA_MASK and DDC_SCL_MASK - */ -#define DDC_SDA_READ_MASK (1 << 3) -#define DDC_SCL_READ_MASK (1 << 2) -#define DDC_SDA_WRITE_MASK (1 << 4) -#define DDC_SCL_WRITE_MASK (1 << 5) - -static void -NV_I2CGetBits(I2CBusPtr b, int *clock, int *data) -{ - NVPtr pNv = NVPTR(xf86Screens[b->scrnIndex]); - unsigned char val; - - /* Get the result. */ - val = nvReadVGA(pNv, pNv->DDCBase); - - *clock = (val & DDC_SCL_READ_MASK) != 0; - *data = (val & DDC_SDA_READ_MASK) != 0; -} - -static void -NV_I2CPutBits(I2CBusPtr b, int clock, int data) -{ - NVPtr pNv = NVPTR(xf86Screens[b->scrnIndex]); - unsigned char val; - - val = nvReadVGA(pNv, pNv->DDCBase + 1) & 0xf0; - if (clock) - val |= DDC_SCL_WRITE_MASK; - else - val &= ~DDC_SCL_WRITE_MASK; - - if (data) - val |= DDC_SDA_WRITE_MASK; - else - val &= ~DDC_SDA_WRITE_MASK; - - nvWriteVGA(pNv, pNv->DDCBase + 1, val | 0x1); -} - -Bool -NVDACi2cInit(ScrnInfoPtr pScrn) -{ - NVPtr pNv = NVPTR(pScrn); - I2CBusPtr I2CPtr; - - I2CPtr = xf86CreateI2CBusRec(); - if(!I2CPtr) return FALSE; - - pNv->I2C = I2CPtr; - - I2CPtr->BusName = "DDC"; - I2CPtr->scrnIndex = pScrn->scrnIndex; - I2CPtr->I2CPutBits = NV_I2CPutBits; - I2CPtr->I2CGetBits = NV_I2CGetBits; - I2CPtr->AcknTimeout = 5; - - if (!xf86I2CBusInit(I2CPtr)) { - return FALSE; - } - return TRUE; -} - diff --git a/src/nv_dma.c b/src/nv_dma.c index 230bdc5..d65f802 100644 --- a/src/nv_dma.c +++ b/src/nv_dma.c @@ -62,6 +62,33 @@ void NVDmaStart(NVPtr pNv, uint32_t object, uint32_t tag, int size) */ #define SKIPS 8 +static void NVDumpLockupInfo(NVPtr pNv) +{ + int i,start; + start=READ_GET(pNv)-20; + if (start<0) start=0; + xf86DrvMsg(0, X_INFO, "Fifo dump (lockup 0x%04x,0x%04x):\n",READ_GET(pNv),pNv->dmaPut); + for(i=start;i<pNv->dmaPut+10;i++) + xf86DrvMsg(0, X_INFO, "[0x%04x] 0x%08x\n", i, pNv->dmaBase[i]); + xf86DrvMsg(0, X_INFO, "End of fifo dump\n"); +} + +static void +NVLockedUp(ScrnInfoPtr pScrn) +{ + NVPtr pNv = NVPTR(pScrn); + + /* avoid re-entering FatalError on shutdown */ + if (pNv->LockedUp) + return; + pNv->LockedUp = TRUE; + + NVDumpLockupInfo(pNv); + + FatalError("DMA queue hang: dmaPut=%x, current=%x, status=%x\n", + pNv->dmaPut, READ_GET(pNv), pNv->PGRAPH[NV_PGRAPH_STATUS/4]); +} + void NVDmaWait (ScrnInfoPtr pScrn, int size) { NVPtr pNv = NVPTR(pScrn); @@ -83,7 +110,7 @@ void NVDmaWait (ScrnInfoPtr pScrn, int size) WRITE_PUT(pNv, SKIPS + 1); do { if (GetTimeInMillis() - t_start > 2000) - NVSync(pScrn); + NVLockedUp(pScrn); dmaGet = READ_GET(pNv); } while(dmaGet <= SKIPS); } @@ -91,45 +118,20 @@ void NVDmaWait (ScrnInfoPtr pScrn, int size) pNv->dmaCurrent = pNv->dmaPut = SKIPS; pNv->dmaFree = dmaGet - (SKIPS + 1); } - } else + } else { pNv->dmaFree = dmaGet - pNv->dmaCurrent - 1; + } if (GetTimeInMillis() - t_start > 2000) - NVSync(pScrn); + NVLockedUp(pScrn); } } -static void NVDumpLockupInfo(NVPtr pNv) -{ - int i,start; - start=READ_GET(pNv)-20; - if (start<0) start=0; - xf86DrvMsg(0, X_INFO, "Fifo dump (lockup 0x%04x,0x%04x):\n",READ_GET(pNv),pNv->dmaPut); - for(i=start;i<pNv->dmaPut+10;i++) - xf86DrvMsg(0, X_INFO, "[0x%04x] 0x%08x\n", i, pNv->dmaBase[i]); - xf86DrvMsg(0, X_INFO, "End of fifo dump\n"); -} - -static void -NVLockedUp(ScrnInfoPtr pScrn) -{ - NVPtr pNv = NVPTR(pScrn); - - /* avoid re-entering FatalError on shutdown */ - if (pNv->LockedUp) - return; - pNv->LockedUp = TRUE; - - NVDumpLockupInfo(pNv); - - FatalError("DMA queue hang: dmaPut=%x, current=%x, status=%x\n", - pNv->dmaPut, READ_GET(pNv), pNv->PGRAPH[NV_PGRAPH_STATUS/4]); -} - void NVSync(ScrnInfoPtr pScrn) { NVPtr pNv = NVPTR(pScrn); int t_start, timeout = 2000; + int grobj; if(pNv->NoAccel) return; @@ -147,10 +149,11 @@ void NVSync(ScrnInfoPtr pScrn) } /* Wait for channel to go completely idle */ + grobj = (pNv->Architecture >= NV_ARCH_50) ? Nv2D : NvImageBlit; NVNotifierReset(pScrn, pNv->Notifier0); - NVDmaStart(pNv, NvImageBlit, 0x104, 1); + NVDmaStart(pNv, grobj, 0x104, 1); NVDmaNext (pNv, 0); - NVDmaStart(pNv, NvImageBlit, 0x100, 1); + NVDmaStart(pNv, grobj, 0x100, 1); NVDmaNext (pNv, 0); NVDmaKickoff(pNv); if (!NVNotifierWaitStatus(pScrn, pNv->Notifier0, 0, timeout)) @@ -167,8 +170,9 @@ void NVResetGraphics(ScrnInfoPtr pScrn) pitch = pNv->CurrentLayout.displayWidth * (pNv->CurrentLayout.bitsPerPixel >> 3); +#if 0 pNv->dmaPut = pNv->dmaCurrent = READ_GET(pNv); - pNv->dmaMax = (pNv->fifo.cmdbuf_size >> 2) - 1; + pNv->dmaMax = (pNv->fifo.cmdbuf_size >> 2) - 2; pNv->dmaFree = pNv->dmaMax - pNv->dmaCurrent; /* assert there's enough room for the skips */ @@ -179,10 +183,14 @@ void NVResetGraphics(ScrnInfoPtr pScrn) pNv->dmaBase[i]=0; } pNv->dmaFree -= SKIPS; +#endif for(i=0;i<8;i++) subchannels[i]=0; + if (pNv->Architecture >= NV_ARCH_50) + return; + NVAccelCommonInit(pScrn); switch(pNv->CurrentLayout.depth) { @@ -284,9 +292,6 @@ Bool NVInitDma(ScrnInfoPtr pScrn) NVInitDmaCB(pScrn); - if (pNv->NoAccel) - return TRUE; - pNv->fifo.fb_ctxdma_handle = NvDmaFB; pNv->fifo.tt_ctxdma_handle = NvDmaTT; ret = drmCommandWriteRead(pNv->drm_fd, DRM_NOUVEAU_CHANNEL_ALLOC, @@ -335,8 +340,8 @@ Bool NVInitDma(ScrnInfoPtr pScrn) xf86DrvMsg(pScrn->scrnIndex, X_INFO, " DMA base PUT : 0x%08x\n", pNv->fifo.put_base); - pNv->dmaPut = pNv->dmaCurrent = READ_GET(pNv); - pNv->dmaMax = (pNv->fifo.cmdbuf_size >> 2) - 1; + pNv->dmaPut = pNv->dmaCurrent = 0; + pNv->dmaMax = (pNv->fifo.cmdbuf_size >> 2) - 2; pNv->dmaFree = pNv->dmaMax - pNv->dmaCurrent; for (i=0; i<SKIPS; i++) diff --git a/src/nv_dma.h b/src/nv_dma.h index f96d5ef..b1f5125 100644 --- a/src/nv_dma.h +++ b/src/nv_dma.h @@ -66,10 +66,10 @@ enum DMAObjects { NvScaledImage = 0x80000017, NvMemFormat = 0x80000018, Nv3D = 0x80000019, + Nv2D = 0x80000020, NvDmaFB = 0xD8000001, NvDmaTT = 0xD8000002, NvDmaNotifier0 = 0xD8000003, - /*XVideo notifiers need to have consecutive handles, be careful when remapping*/ NvDmaXvNotifier0 = 0xE8000000, NvDmaXvNotifier1 = 0xE8000001, diff --git a/src/nv_driver.c b/src/nv_driver.c index b4c6533..b5cb7b3 100644 --- a/src/nv_driver.c +++ b/src/nv_driver.c @@ -42,33 +42,33 @@ Bool RivaGetScrnInfoRec(PciChipsets *chips, int chip);*/ * Forward definitions for the functions that make up the driver. */ /* Mandatory functions */ -static const OptionInfoRec * NVAvailableOptions(int chipid, int busid); -static void NVIdentify(int flags); -static Bool NVProbe(DriverPtr drv, int flags); -static Bool NVPreInit(ScrnInfoPtr pScrn, int flags); -static Bool NVScreenInit(int Index, ScreenPtr pScreen, int argc, - char **argv); -static Bool NVEnterVT(int scrnIndex, int flags); -static void NVLeaveVT(int scrnIndex, int flags); -static Bool NVCloseScreen(int scrnIndex, ScreenPtr pScreen); -static Bool NVSaveScreen(ScreenPtr pScreen, int mode); +static const OptionInfoRec *NVAvailableOptions(int chipid, int busid); +static void NVIdentify(int flags); +static Bool NVProbe(DriverPtr drv, int flags); +static Bool NVPreInit(ScrnInfoPtr pScrn, int flags); +static Bool NVScreenInit(int Index, ScreenPtr pScreen, int argc, + char **argv); +static Bool NVEnterVT(int scrnIndex, int flags); +static void NVLeaveVT(int scrnIndex, int flags); +static Bool NVCloseScreen(int scrnIndex, ScreenPtr pScreen); +static Bool NVSaveScreen(ScreenPtr pScreen, int mode); /* Optional functions */ -static void NVFreeScreen(int scrnIndex, int flags); +static void NVFreeScreen(int scrnIndex, int flags); static ModeStatus NVValidMode(int scrnIndex, DisplayModePtr mode, Bool verbose, int flags); #ifdef RANDR -static Bool NVDriverFunc(ScrnInfoPtr pScrnInfo, xorgDriverFuncOp op, - pointer data); +static Bool NVDriverFunc(ScrnInfoPtr pScrnInfo, xorgDriverFuncOp op, + pointer data); #endif /* Internally used functions */ -static Bool NVMapMem(ScrnInfoPtr pScrn); -static Bool NVUnmapMem(ScrnInfoPtr pScrn); -static void NVSave(ScrnInfoPtr pScrn); -static void NVRestore(ScrnInfoPtr pScrn); -static Bool NVModeInit(ScrnInfoPtr pScrn, DisplayModePtr mode); +static Bool NVMapMem(ScrnInfoPtr pScrn); +static Bool NVUnmapMem(ScrnInfoPtr pScrn); +static void NVSave(ScrnInfoPtr pScrn); +static void NVRestore(ScrnInfoPtr pScrn); +static Bool NVModeInit(ScrnInfoPtr pScrn, DisplayModePtr mode); /* @@ -80,280 +80,277 @@ static Bool NVModeInit(ScrnInfoPtr pScrn, DisplayModePtr mode); */ _X_EXPORT DriverRec NV = { - NV_VERSION, + NV_VERSION, NV_DRIVER_NAME, - NVIdentify, - NVProbe, + NVIdentify, + NVProbe, NVAvailableOptions, - NULL, - 0 + NULL, + 0 }; -struct NvFamily -{ - char *name; - char *chipset; +struct NvFamily { + char *name; + char *chipset; }; -static struct NvFamily NVKnownFamilies[] = -{ - { "RIVA 128", "NV03" }, - { "RIVA TNT", "NV04" }, - { "RIVA TNT2", "NV05" }, - { "GeForce 256", "NV10" }, - { "GeForce 2", "NV11, NV15" }, - { "GeForce 4MX", "NV17, NV18" }, - { "GeForce 3", "NV20" }, - { "GeForce 4Ti", "NV25, NV28" }, - { "GeForce FX", "NV3x" }, - { "GeForce 6", "NV4x" }, - { "GeForce 7", "G7x" }, - { NULL, NULL} +static struct NvFamily NVKnownFamilies[] = { + {"RIVA 128", "NV03"}, + {"RIVA TNT", "NV04"}, + {"RIVA TNT2", "NV05"}, + {"GeForce 256", "NV10"}, + {"GeForce 2", "NV11, NV15"}, + {"GeForce 4MX", "NV17, NV18"}, + {"GeForce 3", "NV20"}, + {"GeForce 4Ti", "NV25, NV28"}, + {"GeForce FX", "NV3x"}, + {"GeForce 6", "NV4x"}, + {"GeForce 7", "G7x"}, + {NULL, NULL} }; /* Known cards as of 2006/06/16 */ -static SymTabRec NVKnownChipsets[] = -{ - { 0x12D20018, "RIVA 128" }, - { 0x12D20019, "RIVA 128ZX" }, - - { 0x10DE0020, "RIVA TNT" }, - - { 0x10DE0028, "RIVA TNT2" }, - { 0x10DE002A, "Unknown TNT2" }, - { 0x10DE002C, "Vanta" }, - { 0x10DE0029, "RIVA TNT2 Ultra" }, - { 0x10DE002D, "RIVA TNT2 Model 64" }, - - { 0x10DE00A0, "Aladdin TNT2" }, - - { 0x10DE0100, "GeForce 256" }, - { 0x10DE0101, "GeForce DDR" }, - { 0x10DE0103, "Quadro" }, - - { 0x10DE0110, "GeForce2 MX/MX 400" }, - { 0x10DE0111, "GeForce2 MX 100/200" }, - { 0x10DE0112, "GeForce2 Go" }, - { 0x10DE0113, "Quadro2 MXR/EX/Go" }, - - { 0x10DE01A0, "GeForce2 Integrated GPU" }, - - { 0x10DE0150, "GeForce2 GTS" }, - { 0x10DE0151, "GeForce2 Ti" }, - { 0x10DE0152, "GeForce2 Ultra" }, - { 0x10DE0153, "Quadro2 Pro" }, - - { 0x10DE0170, "GeForce4 MX 460" }, - { 0x10DE0171, "GeForce4 MX 440" }, - { 0x10DE0172, "GeForce4 MX 420" }, - { 0x10DE0173, "GeForce4 MX 440-SE" }, - { 0x10DE0174, "GeForce4 440 Go" }, - { 0x10DE0175, "GeForce4 420 Go" }, - { 0x10DE0176, "GeForce4 420 Go 32M" }, - { 0x10DE0177, "GeForce4 460 Go" }, - { 0x10DE0178, "Quadro4 550 XGL" }, +static SymTabRec NVKnownChipsets[] = { + {0x12D20018, "RIVA 128"}, + {0x12D20019, "RIVA 128ZX"}, + + {0x10DE0020, "RIVA TNT"}, + + {0x10DE0028, "RIVA TNT2"}, + {0x10DE002A, "Unknown TNT2"}, + {0x10DE002C, "Vanta"}, + {0x10DE0029, "RIVA TNT2 Ultra"}, + {0x10DE002D, "RIVA TNT2 Model 64"}, + + {0x10DE00A0, "Aladdin TNT2"}, + + {0x10DE0100, "GeForce 256"}, + {0x10DE0101, "GeForce DDR"}, + {0x10DE0103, "Quadro"}, + + {0x10DE0110, "GeForce2 MX/MX 400"}, + {0x10DE0111, "GeForce2 MX 100/200"}, + {0x10DE0112, "GeForce2 Go"}, + {0x10DE0113, "Quadro2 MXR/EX/Go"}, + + {0x10DE01A0, "GeForce2 Integrated GPU"}, + + {0x10DE0150, "GeForce2 GTS"}, + {0x10DE0151, "GeForce2 Ti"}, + {0x10DE0152, "GeForce2 Ultra"}, + {0x10DE0153, "Quadro2 Pro"}, + + {0x10DE0170, "GeForce4 MX 460"}, + {0x10DE0171, "GeForce4 MX 440"}, + {0x10DE0172, "GeForce4 MX 420"}, + {0x10DE0173, "GeForce4 MX 440-SE"}, + {0x10DE0174, "GeForce4 440 Go"}, + {0x10DE0175, "GeForce4 420 Go"}, + {0x10DE0176, "GeForce4 420 Go 32M"}, + {0x10DE0177, "GeForce4 460 Go"}, + {0x10DE0178, "Quadro4 550 XGL"}, #if defined(__powerpc__) - { 0x10DE0179, "GeForce4 MX (Mac)" }, + {0x10DE0179, "GeForce4 MX (Mac)"}, #else - { 0x10DE0179, "GeForce4 440 Go 64M" }, + {0x10DE0179, "GeForce4 440 Go 64M"}, #endif - { 0x10DE017A, "Quadro NVS" }, - { 0x10DE017C, "Quadro4 500 GoGL" }, - { 0x10DE017D, "GeForce4 410 Go 16M" }, - - { 0x10DE0181, "GeForce4 MX 440 with AGP8X" }, - { 0x10DE0182, "GeForce4 MX 440SE with AGP8X" }, - { 0x10DE0183, "GeForce4 MX 420 with AGP8X" }, - { 0x10DE0185, "GeForce4 MX 4000" }, - { 0x10DE0186, "GeForce4 448 Go" }, - { 0x10DE0187, "GeForce4 488 Go" }, - { 0x10DE0188, "Quadro4 580 XGL" }, + {0x10DE017A, "Quadro NVS"}, + {0x10DE017C, "Quadro4 500 GoGL"}, + {0x10DE017D, "GeForce4 410 Go 16M"}, + + {0x10DE0181, "GeForce4 MX 440 with AGP8X"}, + {0x10DE0182, "GeForce4 MX 440SE with AGP8X"}, + {0x10DE0183, "GeForce4 MX 420 with AGP8X"}, + {0x10DE0185, "GeForce4 MX 4000"}, + {0x10DE0186, "GeForce4 448 Go"}, + {0x10DE0187, "GeForce4 488 Go"}, + {0x10DE0188, "Quadro4 580 XGL"}, #if defined(__powerpc__) - { 0x10DE0189, "GeForce4 MX with AGP8X (Mac)" }, + {0x10DE0189, "GeForce4 MX with AGP8X (Mac)"}, #endif - { 0x10DE018A, "Quadro4 NVS 280 SD" }, - { 0x10DE018B, "Quadro4 380 XGL" }, - { 0x10DE018C, "Quadro NVS 50 PCI" }, - { 0x10DE018D, "GeForce4 448 Go" }, - - { 0x10DE01F0, "GeForce4 MX Integrated GPU" }, - - { 0x10DE0200, "GeForce3" }, - { 0x10DE0201, "GeForce3 Ti 200" }, - { 0x10DE0202, "GeForce3 Ti 500" }, - { 0x10DE0203, "Quadro DCC" }, - - { 0x10DE0250, "GeForce4 Ti 4600" }, - { 0x10DE0251, "GeForce4 Ti 4400" }, - { 0x10DE0253, "GeForce4 Ti 4200" }, - { 0x10DE0258, "Quadro4 900 XGL" }, - { 0x10DE0259, "Quadro4 750 XGL" }, - { 0x10DE025B, "Quadro4 700 XGL" }, - - { 0x10DE0280, "GeForce4 Ti 4800" }, - { 0x10DE0281, "GeForce4 Ti 4200 with AGP8X" }, - { 0x10DE0282, "GeForce4 Ti 4800 SE" }, - { 0x10DE0286, "GeForce4 4200 Go" }, - { 0x10DE028C, "Quadro4 700 GoGL" }, - { 0x10DE0288, "Quadro4 980 XGL" }, - { 0x10DE0289, "Quadro4 780 XGL" }, - - { 0x10DE0301, "GeForce FX 5800 Ultra" }, - { 0x10DE0302, "GeForce FX 5800" }, - { 0x10DE0308, "Quadro FX 2000" }, - { 0x10DE0309, "Quadro FX 1000" }, - - { 0x10DE0311, "GeForce FX 5600 Ultra" }, - { 0x10DE0312, "GeForce FX 5600" }, - { 0x10DE0314, "GeForce FX 5600XT" }, - { 0x10DE031A, "GeForce FX Go5600" }, - { 0x10DE031B, "GeForce FX Go5650" }, - { 0x10DE031C, "Quadro FX Go700" }, - - { 0x10DE0320, "GeForce FX 5200" }, - { 0x10DE0321, "GeForce FX 5200 Ultra" }, - { 0x10DE0322, "GeForce FX 5200" }, - { 0x10DE0323, "GeForce FX 5200LE" }, - { 0x10DE0324, "GeForce FX Go5200" }, - { 0x10DE0325, "GeForce FX Go5250" }, - { 0x10DE0326, "GeForce FX 5500" }, - { 0x10DE0327, "GeForce FX 5100" }, - { 0x10DE0328, "GeForce FX Go5200 32M/64M" }, + {0x10DE018A, "Quadro4 NVS 280 SD"}, + {0x10DE018B, "Quadro4 380 XGL"}, + {0x10DE018C, "Quadro NVS 50 PCI"}, + {0x10DE018D, "GeForce4 448 Go"}, + + {0x10DE01F0, "GeForce4 MX Integrated GPU"}, + + {0x10DE0200, "GeForce3"}, + {0x10DE0201, "GeForce3 Ti 200"}, + {0x10DE0202, "GeForce3 Ti 500"}, + {0x10DE0203, "Quadro DCC"}, + + {0x10DE0250, "GeForce4 Ti 4600"}, + {0x10DE0251, "GeForce4 Ti 4400"}, + {0x10DE0253, "GeForce4 Ti 4200"}, + {0x10DE0258, "Quadro4 900 XGL"}, + {0x10DE0259, "Quadro4 750 XGL"}, + {0x10DE025B, "Quadro4 700 XGL"}, + + {0x10DE0280, "GeForce4 Ti 4800"}, + {0x10DE0281, "GeForce4 Ti 4200 with AGP8X"}, + {0x10DE0282, "GeForce4 Ti 4800 SE"}, + {0x10DE0286, "GeForce4 4200 Go"}, + {0x10DE028C, "Quadro4 700 GoGL"}, + {0x10DE0288, "Quadro4 980 XGL"}, + {0x10DE0289, "Quadro4 780 XGL"}, + + {0x10DE0301, "GeForce FX 5800 Ultra"}, + {0x10DE0302, "GeForce FX 5800"}, + {0x10DE0308, "Quadro FX 2000"}, + {0x10DE0309, "Quadro FX 1000"}, + + {0x10DE0311, "GeForce FX 5600 Ultra"}, + {0x10DE0312, "GeForce FX 5600"}, + {0x10DE0314, "GeForce FX 5600XT"}, + {0x10DE031A, "GeForce FX Go5600"}, + {0x10DE031B, "GeForce FX Go5650"}, + {0x10DE031C, "Quadro FX Go700"}, + + {0x10DE0320, "GeForce FX 5200"}, + {0x10DE0321, "GeForce FX 5200 Ultra"}, + {0x10DE0322, "GeForce FX 5200"}, + {0x10DE0323, "GeForce FX 5200LE"}, + {0x10DE0324, "GeForce FX Go5200"}, + {0x10DE0325, "GeForce FX Go5250"}, + {0x10DE0326, "GeForce FX 5500"}, + {0x10DE0327, "GeForce FX 5100"}, + {0x10DE0328, "GeForce FX Go5200 32M/64M"}, #if defined(__powerpc__) - { 0x10DE0329, "GeForce FX 5200 (Mac)" }, + {0x10DE0329, "GeForce FX 5200 (Mac)"}, #endif - { 0x10DE032A, "Quadro NVS 55/280 PCI" }, - { 0x10DE032B, "Quadro FX 500/600 PCI" }, - { 0x10DE032C, "GeForce FX Go53xx Series" }, - { 0x10DE032D, "GeForce FX Go5100" }, - - { 0x10DE0330, "GeForce FX 5900 Ultra" }, - { 0x10DE0331, "GeForce FX 5900" }, - { 0x10DE0332, "GeForce FX 5900XT" }, - { 0x10DE0333, "GeForce FX 5950 Ultra" }, - { 0x10DE0334, "GeForce FX 5900ZT" }, - { 0x10DE0338, "Quadro FX 3000" }, - { 0x10DE033F, "Quadro FX 700" }, - - { 0x10DE0341, "GeForce FX 5700 Ultra" }, - { 0x10DE0342, "GeForce FX 5700" }, - { 0x10DE0343, "GeForce FX 5700LE" }, - { 0x10DE0344, "GeForce FX 5700VE" }, - { 0x10DE0347, "GeForce FX Go5700" }, - { 0x10DE0348, "GeForce FX Go5700" }, - { 0x10DE034C, "Quadro FX Go1000" }, - { 0x10DE034E, "Quadro FX 1100" }, - - { 0x10DE0040, "GeForce 6800 Ultra" }, - { 0x10DE0041, "GeForce 6800" }, - { 0x10DE0042, "GeForce 6800 LE" }, - { 0x10DE0043, "GeForce 6800 XE" }, - { 0x10DE0044, "GeForce 6800 XT" }, - { 0x10DE0045, "GeForce 6800 GT" }, - { 0x10DE0046, "GeForce 6800 GT" }, - { 0x10DE0047, "GeForce 6800 GS" }, - { 0x10DE0048, "GeForce 6800 XT" }, - { 0x10DE004E, "Quadro FX 4000" }, - - { 0x10DE00C0, "GeForce 6800 GS" }, - { 0x10DE00C1, "GeForce 6800" }, - { 0x10DE00C2, "GeForce 6800 LE" }, - { 0x10DE00C3, "GeForce 6800 XT" }, - { 0x10DE00C8, "GeForce Go 6800" }, - { 0x10DE00C9, "GeForce Go 6800 Ultra" }, - { 0x10DE00CC, "Quadro FX Go1400" }, - { 0x10DE00CD, "Quadro FX 3450/4000 SDI" }, - { 0x10DE00CE, "Quadro FX 1400" }, - - { 0x10DE0140, "GeForce 6600 GT" }, - { 0x10DE0141, "GeForce 6600" }, - { 0x10DE0142, "GeForce 6600 LE" }, - { 0x10DE0143, "GeForce 6600 VE" }, - { 0x10DE0144, "GeForce Go 6600" }, - { 0x10DE0145, "GeForce 6610 XL" }, - { 0x10DE0146, "GeForce Go 6600 TE/6200 TE" }, - { 0x10DE0147, "GeForce 6700 XL" }, - { 0x10DE0148, "GeForce Go 6600" }, - { 0x10DE0149, "GeForce Go 6600 GT" }, - { 0x10DE014C, "Quadro FX 550" }, - { 0x10DE014D, "Quadro FX 550" }, - { 0x10DE014E, "Quadro FX 540" }, - { 0x10DE014F, "GeForce 6200" }, - - { 0x10DE0160, "GeForce 6500" }, - { 0x10DE0161, "GeForce 6200 TurboCache(TM)" }, - { 0x10DE0162, "GeForce 6200SE TurboCache(TM)" }, - { 0x10DE0163, "GeForce 6200 LE" }, - { 0x10DE0164, "GeForce Go 6200" }, - { 0x10DE0165, "Quadro NVS 285" }, - { 0x10DE0166, "GeForce Go 6400" }, - { 0x10DE0167, "GeForce Go 6200" }, - { 0x10DE0168, "GeForce Go 6400" }, - { 0x10DE0169, "GeForce 6250" }, - - { 0x10DE0211, "GeForce 6800" }, - { 0x10DE0212, "GeForce 6800 LE" }, - { 0x10DE0215, "GeForce 6800 GT" }, - { 0x10DE0218, "GeForce 6800 XT" }, - - { 0x10DE0221, "GeForce 6200" }, - { 0x10DE0222, "GeForce 6200 A-LE" }, - - { 0x10DE0090, "GeForce 7800 GTX" }, - { 0x10DE0091, "GeForce 7800 GTX" }, - { 0x10DE0092, "GeForce 7800 GT" }, - { 0x10DE0093, "GeForce 7800 GS" }, - { 0x10DE0095, "GeForce 7800 SLI" }, - { 0x10DE0098, "GeForce Go 7800" }, - { 0x10DE0099, "GeForce Go 7800 GTX" }, - { 0x10DE009D, "Quadro FX 4500" }, - - { 0x10DE01D1, "GeForce 7300 LE" }, - { 0x10DE01D3, "GeForce 7300 SE" }, - { 0x10DE01D6, "GeForce Go 7200" }, - { 0x10DE01D7, "GeForce Go 7300" }, - { 0x10DE01D8, "GeForce Go 7400" }, - { 0x10DE01D9, "GeForce Go 7400 GS" }, - { 0x10DE01DA, "Quadro NVS 110M" }, - { 0x10DE01DB, "Quadro NVS 120M" }, - { 0x10DE01DC, "Quadro FX 350M" }, - { 0x10DE01DD, "GeForce 7500 LE" }, - { 0x10DE01DE, "Quadro FX 350" }, - { 0x10DE01DF, "GeForce 7300 GS" }, - - { 0x10DE0391, "GeForce 7600 GT" }, - { 0x10DE0392, "GeForce 7600 GS" }, - { 0x10DE0393, "GeForce 7300 GT" }, - { 0x10DE0394, "GeForce 7600 LE" }, - { 0x10DE0395, "GeForce 7300 GT" }, - { 0x10DE0397, "GeForce Go 7700" }, - { 0x10DE0398, "GeForce Go 7600" }, - { 0x10DE0399, "GeForce Go 7600 GT"}, - { 0x10DE039A, "Quadro NVS 300M" }, - { 0x10DE039B, "GeForce Go 7900 SE" }, - { 0x10DE039C, "Quadro FX 550M" }, - { 0x10DE039E, "Quadro FX 560" }, - - { 0x10DE0290, "GeForce 7900 GTX" }, - { 0x10DE0291, "GeForce 7900 GT" }, - { 0x10DE0292, "GeForce 7900 GS" }, - { 0x10DE0298, "GeForce Go 7900 GS" }, - { 0x10DE0299, "GeForce Go 7900 GTX" }, - { 0x10DE029A, "Quadro FX 2500M" }, - { 0x10DE029B, "Quadro FX 1500M" }, - { 0x10DE029C, "Quadro FX 5500" }, - { 0x10DE029D, "Quadro FX 3500" }, - { 0x10DE029E, "Quadro FX 1500" }, - { 0x10DE029F, "Quadro FX 4500 X2" }, - - { 0x10DE0240, "GeForce 6150" }, - { 0x10DE0241, "GeForce 6150 LE" }, - { 0x10DE0242, "GeForce 6100" }, - { 0x10DE0244, "GeForce Go 6150" }, - { 0x10DE0247, "GeForce Go 6100" }, - - {-1, NULL} + {0x10DE032A, "Quadro NVS 55/280 PCI"}, + {0x10DE032B, "Quadro FX 500/600 PCI"}, + {0x10DE032C, "GeForce FX Go53xx Series"}, + {0x10DE032D, "GeForce FX Go5100"}, + + {0x10DE0330, "GeForce FX 5900 Ultra"}, + {0x10DE0331, "GeForce FX 5900"}, + {0x10DE0332, "GeForce FX 5900XT"}, + {0x10DE0333, "GeForce FX 5950 Ultra"}, + {0x10DE0334, "GeForce FX 5900ZT"}, + {0x10DE0338, "Quadro FX 3000"}, + {0x10DE033F, "Quadro FX 700"}, + + {0x10DE0341, "GeForce FX 5700 Ultra"}, + {0x10DE0342, "GeForce FX 5700"}, + {0x10DE0343, "GeForce FX 5700LE"}, + {0x10DE0344, "GeForce FX 5700VE"}, + {0x10DE0347, "GeForce FX Go5700"}, + {0x10DE0348, "GeForce FX Go5700"}, + {0x10DE034C, "Quadro FX Go1000"}, + {0x10DE034E, "Quadro FX 1100"}, + + {0x10DE0040, "GeForce 6800 Ultra"}, + {0x10DE0041, "GeForce 6800"}, + {0x10DE0042, "GeForce 6800 LE"}, + {0x10DE0043, "GeForce 6800 XE"}, + {0x10DE0044, "GeForce 6800 XT"}, + {0x10DE0045, "GeForce 6800 GT"}, + {0x10DE0046, "GeForce 6800 GT"}, + {0x10DE0047, "GeForce 6800 GS"}, + {0x10DE0048, "GeForce 6800 XT"}, + {0x10DE004E, "Quadro FX 4000"}, + + {0x10DE00C0, "GeForce 6800 GS"}, + {0x10DE00C1, "GeForce 6800"}, + {0x10DE00C2, "GeForce 6800 LE"}, + {0x10DE00C3, "GeForce 6800 XT"}, + {0x10DE00C8, "GeForce Go 6800"}, + {0x10DE00C9, "GeForce Go 6800 Ultra"}, + {0x10DE00CC, "Quadro FX Go1400"}, + {0x10DE00CD, "Quadro FX 3450/4000 SDI"}, + {0x10DE00CE, "Quadro FX 1400"}, + + {0x10DE0140, "GeForce 6600 GT"}, + {0x10DE0141, "GeForce 6600"}, + {0x10DE0142, "GeForce 6600 LE"}, + {0x10DE0143, "GeForce 6600 VE"}, + {0x10DE0144, "GeForce Go 6600"}, + {0x10DE0145, "GeForce 6610 XL"}, + {0x10DE0146, "GeForce Go 6600 TE/6200 TE"}, + {0x10DE0147, "GeForce 6700 XL"}, + {0x10DE0148, "GeForce Go 6600"}, + {0x10DE0149, "GeForce Go 6600 GT"}, + {0x10DE014C, "Quadro FX 550"}, + {0x10DE014D, "Quadro FX 550"}, + {0x10DE014E, "Quadro FX 540"}, + {0x10DE014F, "GeForce 6200"}, + + {0x10DE0160, "GeForce 6500"}, + {0x10DE0161, "GeForce 6200 TurboCache(TM)"}, + {0x10DE0162, "GeForce 6200SE TurboCache(TM)"}, + {0x10DE0163, "GeForce 6200 LE"}, + {0x10DE0164, "GeForce Go 6200"}, + {0x10DE0165, "Quadro NVS 285"}, + {0x10DE0166, "GeForce Go 6400"}, + {0x10DE0167, "GeForce Go 6200"}, + {0x10DE0168, "GeForce Go 6400"}, + {0x10DE0169, "GeForce 6250"}, + + {0x10DE0211, "GeForce 6800"}, + {0x10DE0212, "GeForce 6800 LE"}, + {0x10DE0215, "GeForce 6800 GT"}, + {0x10DE0218, "GeForce 6800 XT"}, + + {0x10DE0221, "GeForce 6200"}, + {0x10DE0222, "GeForce 6200 A-LE"}, + + {0x10DE0090, "GeForce 7800 GTX"}, + {0x10DE0091, "GeForce 7800 GTX"}, + {0x10DE0092, "GeForce 7800 GT"}, + {0x10DE0093, "GeForce 7800 GS"}, + {0x10DE0095, "GeForce 7800 SLI"}, + {0x10DE0098, "GeForce Go 7800"}, + {0x10DE0099, "GeForce Go 7800 GTX"}, + {0x10DE009D, "Quadro FX 4500"}, + + {0x10DE01D1, "GeForce 7300 LE"}, + {0x10DE01D3, "GeForce 7300 SE"}, + {0x10DE01D6, "GeForce Go 7200"}, + {0x10DE01D7, "GeForce Go 7300"}, + {0x10DE01D8, "GeForce Go 7400"}, + {0x10DE01D9, "GeForce Go 7400 GS"}, + {0x10DE01DA, "Quadro NVS 110M"}, + {0x10DE01DB, "Quadro NVS 120M"}, + {0x10DE01DC, "Quadro FX 350M"}, + {0x10DE01DD, "GeForce 7500 LE"}, + {0x10DE01DE, "Quadro FX 350"}, + {0x10DE01DF, "GeForce 7300 GS"}, + + {0x10DE0391, "GeForce 7600 GT"}, + {0x10DE0392, "GeForce 7600 GS"}, + {0x10DE0393, "GeForce 7300 GT"}, + {0x10DE0394, "GeForce 7600 LE"}, + {0x10DE0395, "GeForce 7300 GT"}, + {0x10DE0397, "GeForce Go 7700"}, + {0x10DE0398, "GeForce Go 7600"}, + {0x10DE0399, "GeForce Go 7600 GT"}, + {0x10DE039A, "Quadro NVS 300M"}, + {0x10DE039B, "GeForce Go 7900 SE"}, + {0x10DE039C, "Quadro FX 550M"}, + {0x10DE039E, "Quadro FX 560"}, + + {0x10DE0290, "GeForce 7900 GTX"}, + {0x10DE0291, "GeForce 7900 GT"}, + {0x10DE0292, "GeForce 7900 GS"}, + {0x10DE0298, "GeForce Go 7900 GS"}, + {0x10DE0299, "GeForce Go 7900 GTX"}, + {0x10DE029A, "Quadro FX 2500M"}, + {0x10DE029B, "Quadro FX 1500M"}, + {0x10DE029C, "Quadro FX 5500"}, + {0x10DE029D, "Quadro FX 3500"}, + {0x10DE029E, "Quadro FX 1500"}, + {0x10DE029F, "Quadro FX 4500 X2"}, + + {0x10DE0240, "GeForce 6150"}, + {0x10DE0241, "GeForce 6150 LE"}, + {0x10DE0242, "GeForce 6100"}, + {0x10DE0244, "GeForce Go 6150"}, + {0x10DE0247, "GeForce Go 6100"}, + + {-1, NULL} }; @@ -367,147 +364,147 @@ static SymTabRec NVKnownChipsets[] = */ static const char *vgahwSymbols[] = { - "vgaHWUnmapMem", - "vgaHWDPMSSet", - "vgaHWFreeHWRec", - "vgaHWGetHWRec", - "vgaHWGetIndex", - "vgaHWInit", - "vgaHWMapMem", - "vgaHWProtect", - "vgaHWRestore", - "vgaHWSave", - "vgaHWSaveScreen", - NULL + "vgaHWUnmapMem", + "vgaHWDPMSSet", + "vgaHWFreeHWRec", + "vgaHWGetHWRec", + "vgaHWGetIndex", + "vgaHWInit", + "vgaHWMapMem", + "vgaHWProtect", + "vgaHWRestore", + "vgaHWSave", + "vgaHWSaveScreen", + NULL }; static const char *fbSymbols[] = { - "fbPictureInit", - "fbScreenInit", - NULL + "fbPictureInit", + "fbScreenInit", + NULL }; static const char *xaaSymbols[] = { - "XAACopyROP", - "XAACreateInfoRec", - "XAADestroyInfoRec", - "XAAFallbackOps", - "XAAInit", - "XAAPatternROP", - NULL + "XAACopyROP", + "XAACreateInfoRec", + "XAADestroyInfoRec", + "XAAFallbackOps", + "XAAInit", + "XAAPatternROP", + NULL }; static const char *exaSymbols[] = { - "exaDriverInit", - "exaOffscreenInit", - NULL + "exaDriverInit", + "exaOffscreenInit", + NULL }; static const char *ramdacSymbols[] = { - "xf86CreateCursorInfoRec", - "xf86DestroyCursorInfoRec", - "xf86InitCursor", - NULL + "xf86CreateCursorInfoRec", + "xf86DestroyCursorInfoRec", + "xf86InitCursor", + NULL }; static const char *ddcSymbols[] = { - "xf86PrintEDID", - "xf86DoEDID_DDC2", - "xf86SetDDCproperties", - NULL + "xf86PrintEDID", + "xf86DoEDID_DDC2", + "xf86SetDDCproperties", + NULL }; static const char *vbeSymbols[] = { - "VBEInit", - "vbeFree", - "vbeDoEDID", - NULL + "VBEInit", + "vbeFree", + "vbeDoEDID", + NULL }; static const char *i2cSymbols[] = { - "xf86CreateI2CBusRec", - "xf86I2CBusInit", - NULL + "xf86CreateI2CBusRec", + "xf86I2CBusInit", + NULL }; static const char *shadowSymbols[] = { - "ShadowFBInit", - NULL + "ShadowFBInit", + NULL }; static const char *int10Symbols[] = { - "xf86FreeInt10", - "xf86InitInt10", - NULL + "xf86FreeInt10", + "xf86InitInt10", + NULL }; static const char *rivaSymbols[] = { - "RivaGetScrnInfoRec", - "RivaAvailableOptions", - NULL + "RivaGetScrnInfoRec", + "RivaAvailableOptions", + NULL }; const char *drmSymbols[] = { - "drmOpen", - "drmAddBufs", - "drmAddMap", - "drmAgpAcquire", - "drmAgpVersionMajor", - "drmAgpVersionMinor", - "drmAgpAlloc", - "drmAgpBind", - "drmAgpEnable", - "drmAgpFree", - "drmAgpRelease", - "drmAgpUnbind", - "drmAuthMagic", - "drmCommandNone", - "drmCommandWrite", - "drmCommandWriteRead", - "drmCreateContext", - "drmCtlInstHandler", - "drmCtlUninstHandler", - "drmDestroyContext", - "drmFreeVersion", - "drmGetInterruptFromBusID", - "drmGetLibVersion", - "drmGetVersion", - NULL + "drmOpen", + "drmAddBufs", + "drmAddMap", + "drmAgpAcquire", + "drmAgpVersionMajor", + "drmAgpVersionMinor", + "drmAgpAlloc", + "drmAgpBind", + "drmAgpEnable", + "drmAgpFree", + "drmAgpRelease", + "drmAgpUnbind", + "drmAuthMagic", + "drmCommandNone", + "drmCommandWrite", + "drmCommandWriteRead", + "drmCreateContext", + "drmCtlInstHandler", + "drmCtlUninstHandler", + "drmDestroyContext", + "drmFreeVersion", + "drmGetInterruptFromBusID", + "drmGetLibVersion", + "drmGetVersion", + NULL }; const char *driSymbols[] = { - "DRICloseScreen", - "DRICreateInfoRec", - "DRIDestroyInfoRec", - "DRIFinishScreenInit", - "DRIGetSAREAPrivate", - "DRILock", - "DRIQueryVersion", - "DRIScreenInit", - "DRIUnlock", - "GlxSetVisualConfigs", - "DRICreatePCIBusID", - NULL + "DRICloseScreen", + "DRICreateInfoRec", + "DRIDestroyInfoRec", + "DRIFinishScreenInit", + "DRIGetSAREAPrivate", + "DRILock", + "DRIQueryVersion", + "DRIScreenInit", + "DRIUnlock", + "GlxSetVisualConfigs", + "DRICreatePCIBusID", + NULL }; static MODULESETUPPROTO(nouveauSetup); -static XF86ModuleVersionInfo nouveauVersRec = -{ - "nouveau", - MODULEVENDORSTRING, - MODINFOSTRING1, - MODINFOSTRING2, - XORG_VERSION_CURRENT, - NV_MAJOR_VERSION, NV_MINOR_VERSION, NV_PATCHLEVEL, - ABI_CLASS_VIDEODRV, /* This is a video driver */ - ABI_VIDEODRV_VERSION, - MOD_CLASS_VIDEODRV, - {0,0,0,0} +static XF86ModuleVersionInfo nouveauVersRec = { + "nouveau", + MODULEVENDORSTRING, + MODINFOSTRING1, + MODINFOSTRING2, + XORG_VERSION_CURRENT, + NV_MAJOR_VERSION, NV_MINOR_VERSION, NV_PATCHLEVEL, + ABI_CLASS_VIDEODRV, /* This is a video driver */ + ABI_VIDEODRV_VERSION, + MOD_CLASS_VIDEODRV, + {0, 0, 0, 0} }; -_X_EXPORT XF86ModuleData nouveauModuleData = { &nouveauVersRec, nouveauSetup, NULL }; +_X_EXPORT XF86ModuleData nouveauModuleData = + { &nouveauVersRec, nouveauSetup, NULL }; /* @@ -519,66 +516,67 @@ static int pix24bpp = 0; static Bool NVGetRec(ScrnInfoPtr pScrn) { - /* - * Allocate an NVRec, and hook it into pScrn->driverPrivate. - * pScrn->driverPrivate is initialised to NULL, so we can check if - * the allocation has already been done. - */ - if (pScrn->driverPrivate != NULL) - return TRUE; - - pScrn->driverPrivate = xnfcalloc(sizeof(NVRec), 1); - /* Initialise it */ - - return TRUE; + /* + * Allocate an NVRec, and hook it into pScrn->driverPrivate. + * pScrn->driverPrivate is initialised to NULL, so we can check if + * the allocation has already been done. + */ + if (pScrn->driverPrivate != NULL) + return TRUE; + + pScrn->driverPrivate = xnfcalloc(sizeof(NVRec), 1); + /* Initialise it */ + + return TRUE; } static void NVFreeRec(ScrnInfoPtr pScrn) { - if (pScrn->driverPrivate == NULL) - return; - xfree(pScrn->driverPrivate); - pScrn->driverPrivate = NULL; + if (pScrn->driverPrivate == NULL) + return; + xfree(pScrn->driverPrivate); + pScrn->driverPrivate = NULL; } - static pointer nouveauSetup(pointer module, pointer opts, int *errmaj, int *errmin) { - static Bool setupDone = FALSE; - - /* This module should be loaded only once, but check to be sure. */ - - if (!setupDone) { - setupDone = TRUE; - xf86AddDriver(&NV, module, 0); - - /* - * Modules that this driver always requires may be loaded here - * by calling LoadSubModule(). - */ - /* - * Tell the loader about symbols from other modules that this module - * might refer to. - */ - LoaderRefSymLists(vgahwSymbols, xaaSymbols, exaSymbols, fbSymbols, + static Bool setupDone = FALSE; + + /* This module should be loaded only once, but check to be sure. */ + + if (!setupDone) { + setupDone = TRUE; + xf86AddDriver(&NV, module, 0); + + /* + * Modules that this driver always requires may be loaded here + * by calling LoadSubModule(). + */ + /* + * Tell the loader about symbols from other modules that this module + * might refer to. + */ + LoaderRefSymLists(vgahwSymbols, xaaSymbols, exaSymbols, + fbSymbols, #ifdef XF86DRI - drmSymbols, + drmSymbols, #endif - ramdacSymbols, shadowSymbols, rivaSymbols, - i2cSymbols, ddcSymbols, vbeSymbols, - int10Symbols, NULL); - - /* - * The return value must be non-NULL on success even though there - * is no TearDownProc. - */ - return (pointer)1; - } else { - if (errmaj) *errmaj = LDR_ONCEONLY; - return NULL; - } + ramdacSymbols, shadowSymbols, + rivaSymbols, i2cSymbols, ddcSymbols, + vbeSymbols, int10Symbols, NULL); + + /* + * The return value must be non-NULL on success even though there + * is no TearDownProc. + */ + return (pointer) 1; + } else { + if (errmaj) + *errmaj = LDR_ONCEONLY; + return NULL; + } } static const OptionInfoRec * @@ -590,102 +588,101 @@ NVAvailableOptions(int chipid, int busid) } else return RivaAvailableOptions(chipid, busid); }*/ - - return NVOptions; + + return NVOptions; } /* Mandatory */ static void NVIdentify(int flags) { - struct NvFamily *family; - size_t maxLen=0; - - xf86DrvMsg(0, X_INFO, NV_NAME " driver " NV_DRIVER_DATE "\n"); - xf86DrvMsg(0, X_INFO, NV_NAME " driver for NVIDIA chipset families :\n"); - - /* maximum length for alignment */ - family = NVKnownFamilies; - while(family->name && family->chipset) - { - maxLen = max(maxLen, strlen(family->name)); - family++; - } - - /* display */ - family = NVKnownFamilies; - while(family->name && family->chipset) - { - size_t len = strlen(family->name); - xf86ErrorF("\t%s", family->name); - while(len<maxLen+1) - { - xf86ErrorF(" "); - len++; - } - xf86ErrorF("(%s)\n", family->chipset); - family++; - } + struct NvFamily *family; + size_t maxLen = 0; + + xf86DrvMsg(0, X_INFO, NV_NAME " driver " NV_DRIVER_DATE "\n"); + xf86DrvMsg(0, X_INFO, + NV_NAME " driver for NVIDIA chipset families :\n"); + + /* maximum length for alignment */ + family = NVKnownFamilies; + while (family->name && family->chipset) { + maxLen = max(maxLen, strlen(family->name)); + family++; + } + + /* display */ + family = NVKnownFamilies; + while (family->name && family->chipset) { + size_t len = strlen(family->name); + xf86ErrorF("\t%s", family->name); + while (len < maxLen + 1) { + xf86ErrorF(" "); + len++; + } + xf86ErrorF("(%s)\n", family->chipset); + family++; + } } static Bool -NVGetScrnInfoRec(PciChipsets *chips, int chip) +NVGetScrnInfoRec(PciChipsets * chips, int chip) { - ScrnInfoPtr pScrn; + ScrnInfoPtr pScrn; - pScrn = xf86ConfigPciEntity(NULL, 0, chip, - chips, NULL, NULL, NULL, - NULL, NULL); + pScrn = xf86ConfigPciEntity(NULL, 0, chip, + chips, NULL, NULL, NULL, NULL, NULL); - if(!pScrn) return FALSE; + if (!pScrn) + return FALSE; - pScrn->driverVersion = NV_VERSION; - pScrn->driverName = NV_DRIVER_NAME; - pScrn->name = NV_NAME; + pScrn->driverVersion = NV_VERSION; + pScrn->driverName = NV_DRIVER_NAME; + pScrn->name = NV_NAME; - pScrn->Probe = NVProbe; - pScrn->PreInit = NVPreInit; - pScrn->ScreenInit = NVScreenInit; - pScrn->SwitchMode = NVSwitchMode; - pScrn->AdjustFrame = NVAdjustFrame; - pScrn->EnterVT = NVEnterVT; - pScrn->LeaveVT = NVLeaveVT; - pScrn->FreeScreen = NVFreeScreen; - pScrn->ValidMode = NVValidMode; + pScrn->Probe = NVProbe; + pScrn->PreInit = NVPreInit; + pScrn->ScreenInit = NVScreenInit; + pScrn->SwitchMode = NVSwitchMode; + pScrn->AdjustFrame = NVAdjustFrame; + pScrn->EnterVT = NVEnterVT; + pScrn->LeaveVT = NVLeaveVT; + pScrn->FreeScreen = NVFreeScreen; + pScrn->ValidMode = NVValidMode; - return TRUE; + return TRUE; } #define MAX_CHIPS MAXSCREENS -static CARD32 -NVGetPCIXpressChip (pciVideoPtr pVideo) +static CARD32 +NVGetPCIXpressChip(pciVideoPtr pVideo) { - volatile CARD32 *regs; - CARD32 pciid, pcicmd; - PCITAG Tag = ((pciConfigPtr)(pVideo->thisCard))->tag; + volatile CARD32 *regs; + CARD32 pciid, pcicmd; + PCITAG Tag = ((pciConfigPtr) (pVideo->thisCard))->tag; - pcicmd = pciReadLong(Tag, PCI_CMD_STAT_REG); - pciWriteLong(Tag, PCI_CMD_STAT_REG, pcicmd | PCI_CMD_MEM_ENABLE); - - regs = xf86MapPciMem(-1, VIDMEM_MMIO, Tag, pVideo->memBase[0], 0x2000); + pcicmd = pciReadLong(Tag, PCI_CMD_STAT_REG); + pciWriteLong(Tag, PCI_CMD_STAT_REG, pcicmd | PCI_CMD_MEM_ENABLE); - pciid = regs[0x1800/4]; + regs = + xf86MapPciMem(-1, VIDMEM_MMIO, Tag, pVideo->memBase[0], + 0x2000); - xf86UnMapVidMem(-1, (pointer)regs, 0x2000); + pciid = regs[0x1800 / 4]; - pciWriteLong(Tag, PCI_CMD_STAT_REG, pcicmd); + xf86UnMapVidMem(-1, (pointer) regs, 0x2000); - if((pciid & 0x0000ffff) == 0x000010DE) - pciid = 0x10DE0000 | (pciid >> 16); - else - if((pciid & 0xffff0000) == 0xDE100000) /* wrong endian */ - pciid = 0x10DE0000 | ((pciid << 8) & 0x0000ff00) | - ((pciid >> 8) & 0x000000ff); + pciWriteLong(Tag, PCI_CMD_STAT_REG, pcicmd); - return pciid; + if ((pciid & 0x0000ffff) == 0x000010DE) + pciid = 0x10DE0000 | (pciid >> 16); + else if ((pciid & 0xffff0000) == 0xDE100000) /* wrong endian */ + pciid = 0x10DE0000 | ((pciid << 8) & 0x0000ff00) | + ((pciid >> 8) & 0x000000ff); + + return pciid; } @@ -693,129 +690,152 @@ NVGetPCIXpressChip (pciVideoPtr pVideo) static Bool NVProbe(DriverPtr drv, int flags) { - int i; - GDevPtr *devSections; - int *usedChips; - SymTabRec NVChipsets[MAX_CHIPS + 1]; - PciChipsets NVPciChipsets[MAX_CHIPS + 1]; - pciVideoPtr *ppPci; - int numDevSections; - int numUsed; - Bool foundScreen = FALSE; - - - if ((numDevSections = xf86MatchDevice(NV_DRIVER_NAME, &devSections)) <= 0) - return FALSE; /* no matching device section */ - - if (!(ppPci = xf86GetPciVideoInfo())) - return FALSE; /* no PCI cards found */ - - numUsed = 0; - - /* Create the NVChipsets and NVPciChipsets from found devices */ - while (*ppPci && (numUsed < MAX_CHIPS)) { - if(((*ppPci)->vendor == PCI_VENDOR_NVIDIA_SGS) || - ((*ppPci)->vendor == PCI_VENDOR_NVIDIA)) - { - SymTabRec *nvchips = NVKnownChipsets; - int pciid = ((*ppPci)->vendor << 16) | (*ppPci)->chipType; - int token = pciid; - - if(((token & 0xfff0) == CHIPSET_MISC_BRIDGED) || - ((token & 0xfff0) == CHIPSET_G73_BRIDGED)) - { - token = NVGetPCIXpressChip(*ppPci); - } - - while(nvchips->name) { - if(token == nvchips->token) - break; - nvchips++; - } - - if(nvchips->name) { /* found one */ - NVChipsets[numUsed].token = pciid; - NVChipsets[numUsed].name = nvchips->name; - NVPciChipsets[numUsed].numChipset = pciid; - NVPciChipsets[numUsed].PCIid = pciid; - NVPciChipsets[numUsed].resList = RES_SHARED_VGA; - numUsed++; - } else if ((*ppPci)->vendor == PCI_VENDOR_NVIDIA) { - /* look for a compatible devices which may be newer than - the NVKnownChipsets list above. */ - switch(token & 0xfff0) { - case CHIPSET_NV17: - case CHIPSET_NV18: - case CHIPSET_NV25: - case CHIPSET_NV28: - case CHIPSET_NV30: - case CHIPSET_NV31: - case CHIPSET_NV34: - case CHIPSET_NV35: - case CHIPSET_NV36: - case CHIPSET_NV40: - case CHIPSET_NV41: - case 0x0120: - case CHIPSET_NV43: - case CHIPSET_NV44: - case 0x0130: - case CHIPSET_G72: - case CHIPSET_G70: - case CHIPSET_NV45: - case CHIPSET_NV44A: - case 0x0230: - case CHIPSET_G71: - case CHIPSET_G73: - case CHIPSET_C512: - NVChipsets[numUsed].token = pciid; - NVChipsets[numUsed].name = "Unknown NVIDIA chip"; - NVPciChipsets[numUsed].numChipset = pciid; - NVPciChipsets[numUsed].PCIid = pciid; - NVPciChipsets[numUsed].resList = RES_SHARED_VGA; - numUsed++; - break; - default: break; /* we don't recognize it */ - } - } - } - ppPci++; - } - - /* terminate the list */ - NVChipsets[numUsed].token = -1; - NVChipsets[numUsed].name = NULL; - NVPciChipsets[numUsed].numChipset = -1; - NVPciChipsets[numUsed].PCIid = -1; - NVPciChipsets[numUsed].resList = RES_UNDEFINED; - - numUsed = xf86MatchPciInstances(NV_NAME, 0, NVChipsets, NVPciChipsets, - devSections, numDevSections, drv, - &usedChips); - - if (numUsed <= 0) - return FALSE; - - if (flags & PROBE_DETECT) - foundScreen = TRUE; - else for (i = 0; i < numUsed; i++) { - pciVideoPtr pPci; - - pPci = xf86GetPciInfoForEntity(usedChips[i]); - if(NVGetScrnInfoRec(NVPciChipsets, usedChips[i])) - foundScreen = TRUE; - } - - xfree(devSections); - xfree(usedChips); - - return foundScreen; + int i; + GDevPtr *devSections; + int *usedChips; + SymTabRec NVChipsets[MAX_CHIPS + 1]; + PciChipsets NVPciChipsets[MAX_CHIPS + 1]; + pciVideoPtr *ppPci; + int numDevSections; + int numUsed; + Bool foundScreen = FALSE; + + + if ((numDevSections = + xf86MatchDevice(NV_DRIVER_NAME, &devSections)) <= 0) + return FALSE; /* no matching device section */ + + if (!(ppPci = xf86GetPciVideoInfo())) + return FALSE; /* no PCI cards found */ + + numUsed = 0; + + /* Create the NVChipsets and NVPciChipsets from found devices */ + while (*ppPci && (numUsed < MAX_CHIPS)) { + if (((*ppPci)->vendor == PCI_VENDOR_NVIDIA_SGS) || + ((*ppPci)->vendor == PCI_VENDOR_NVIDIA)) { + SymTabRec *nvchips = NVKnownChipsets; + int pciid = + ((*ppPci)->vendor << 16) | (*ppPci)->chipType; + int token = pciid; + + if (((token & 0xfff0) == CHIPSET_MISC_BRIDGED) || + ((token & 0xfff0) == CHIPSET_G73_BRIDGED)) { + token = NVGetPCIXpressChip(*ppPci); + } + + while (nvchips->name) { + if (token == nvchips->token) + break; + nvchips++; + } + + if (nvchips->name) { /* found one */ + NVChipsets[numUsed].token = pciid; + NVChipsets[numUsed].name = nvchips->name; + NVPciChipsets[numUsed].numChipset = pciid; + NVPciChipsets[numUsed].PCIid = pciid; + NVPciChipsets[numUsed].resList = + RES_SHARED_VGA; + numUsed++; + } else if ((*ppPci)->vendor == PCI_VENDOR_NVIDIA) { + /* look for a compatible devices which may be newer than + the NVKnownChipsets list above. */ + switch (token & 0xfff0) { + case CHIPSET_NV17: + case CHIPSET_NV18: + case CHIPSET_NV25: + case CHIPSET_NV28: + case CHIPSET_NV30: + case CHIPSET_NV31: + case CHIPSET_NV34: + case CHIPSET_NV35: + case CHIPSET_NV36: + case CHIPSET_NV40: + case CHIPSET_NV41: + case 0x0120: + case CHIPSET_NV43: + case CHIPSET_NV44: + case 0x0130: + case CHIPSET_G72: + case CHIPSET_G70: + case CHIPSET_NV45: + case CHIPSET_NV44A: + case 0x0230: + case CHIPSET_NV50: + case CHIPSET_NV84: + case CHIPSET_G71: + case CHIPSET_G73: + case CHIPSET_C512: + NVChipsets[numUsed].token = pciid; + NVChipsets[numUsed].name = + "Unknown NVIDIA chip"; + NVPciChipsets[numUsed].numChipset = + pciid; + NVPciChipsets[numUsed].PCIid = + pciid; + NVPciChipsets[numUsed].resList = + RES_SHARED_VGA; + numUsed++; + break; + default: + break; /* we don't recognize it */ + } + } + } + ppPci++; + } + + /* terminate the list */ + NVChipsets[numUsed].token = -1; + NVChipsets[numUsed].name = NULL; + NVPciChipsets[numUsed].numChipset = -1; + NVPciChipsets[numUsed].PCIid = -1; + NVPciChipsets[numUsed].resList = RES_UNDEFINED; + + numUsed = + xf86MatchPciInstances(NV_NAME, 0, NVChipsets, NVPciChipsets, + devSections, numDevSections, drv, + &usedChips); + + if (numUsed <= 0) + return FALSE; + + if (flags & PROBE_DETECT) + foundScreen = TRUE; + else + for (i = 0; i < numUsed; i++) { + pciVideoPtr pPci; + + pPci = xf86GetPciInfoForEntity(usedChips[i]); + if (NVGetScrnInfoRec(NVPciChipsets, usedChips[i])) + foundScreen = TRUE; + } + + xfree(devSections); + xfree(usedChips); + + return foundScreen; } /* Usually mandatory */ Bool NVSwitchMode(int scrnIndex, DisplayModePtr mode, int flags) { - return NVModeInit(xf86Screens[scrnIndex], mode); + ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; + NVPtr pNv = NVPTR(pScrn); + Bool ret = TRUE; + + NVFBLayout *pLayout = &pNv->CurrentLayout; + + if (pLayout->mode != mode) { + if (!NVSetMode(pScrn, mode, RR_Rotate_0)) + ret = FALSE; + } + + pLayout->mode = mode; + + return ret; } /* @@ -823,19 +843,64 @@ NVSwitchMode(int scrnIndex, DisplayModePtr mode, int flags) * displayed location in the video memory. */ /* Usually mandatory */ -void +void NVAdjustFrame(int scrnIndex, int x, int y, int flags) { - ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; - int startAddr; - NVPtr pNv = NVPTR(pScrn); - NVFBLayout *pLayout = &pNv->CurrentLayout; - - startAddr = (((y*pLayout->displayWidth)+x)*(pLayout->bitsPerPixel/8)); - startAddr += pNv->FB->offset; - NVSetStartAddress(pNv, startAddr); + ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; + xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn); + int startAddr; + NVPtr pNv = NVPTR(pScrn); + NVFBLayout *pLayout = &pNv->CurrentLayout; + xf86CrtcPtr crtc = config->output[config->compat_output]->crtc; + + if (crtc && crtc->enabled) { + NVCrtcSetBase(crtc, x, y); + } +} + +void +NVResetCrtcConfig(ScrnInfoPtr pScrn, int set) +{ + xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn); + NVPtr pNv = NVPTR(pScrn); + int i; + CARD32 val = 0; + + for (i = 0; i < config->num_crtc; i++) { + xf86CrtcPtr crtc = config->crtc[i]; + NVCrtcPrivatePtr nv_crtc = crtc->driver_private; + + if (set) { + NVCrtcRegPtr regp; + + regp = &pNv->ModeReg.crtc_reg[nv_crtc->crtc]; + val = regp->head; + } + + nvWriteCRTC(pNv, nv_crtc->crtc, NV_CRTC_FSEL, val); + } +} + +static Bool +NV50AcquireDisplay(ScrnInfoPtr pScrn) +{ + if (!NV50DispInit(pScrn)) + return FALSE; + if (!NV50CursorAcquire(pScrn)) + return FALSE; + xf86SetDesiredModes(pScrn); + + return TRUE; } +static Bool +NV50ReleaseDisplay(ScrnInfoPtr pScrn) +{ + NV50CursorRelease(pScrn); + NV50DispShutdown(pScrn); + + return TRUE; +} /* * This is called when VT switching back to the X server. Its job is @@ -848,16 +913,34 @@ NVAdjustFrame(int scrnIndex, int x, int y, int flags) static Bool NVEnterVT(int scrnIndex, int flags) { - ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; - NVPtr pNv = NVPTR(pScrn); + ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; + xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn); + NVPtr pNv = NVPTR(pScrn); + int i; + + pScrn->vtSema = TRUE; + + if (pNv->Architecture == NV_ARCH_50) { + if (!NV50AcquireDisplay(pScrn)) + return FALSE; + return TRUE; + } + + /* Save the current state */ + if (pNv->SaveGeneration != serverGeneration) { + pNv->SaveGeneration = serverGeneration; + NVSave(pScrn); + } - if (!NVModeInit(pScrn, pScrn->currentMode)) - return FALSE; - NVAdjustFrame(scrnIndex, pScrn->frameX0, pScrn->frameY0, 0); + NVResetCrtcConfig(pScrn, 0); + if (!xf86SetDesiredModes(pScrn)) + return FALSE; + NVResetCrtcConfig(pScrn, 1); + pScrn->AdjustFrame(scrnIndex, pScrn->frameX0, pScrn->frameY0, 0); - if(pNv->overlayAdaptor) - NVResetVideo(pScrn); - return TRUE; + if (pNv->overlayAdaptor) + NVResetVideo(pScrn); + return TRUE; } /* @@ -871,37 +954,38 @@ NVEnterVT(int scrnIndex, int flags) static void NVLeaveVT(int scrnIndex, int flags) { - ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; - NVPtr pNv = NVPTR(pScrn); + ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; + NVPtr pNv = NVPTR(pScrn); - NVSync(pScrn); - NVRestore(pScrn); - NVLockUnlock(pNv, 1); + if (pNv->Architecture == NV_ARCH_50) { + NV50ReleaseDisplay(pScrn); + return; + } + + NVSync(pScrn); + NVRestore(pScrn); } -static void -NVBlockHandler ( - int i, - pointer blockData, - pointer pTimeout, - pointer pReadmask -) +static void +NVBlockHandler(int i, + pointer blockData, pointer pTimeout, pointer pReadmask) { - ScreenPtr pScreen = screenInfo.screens[i]; - ScrnInfoPtr pScrnInfo = xf86Screens[i]; - NVPtr pNv = NVPTR(pScrnInfo); + ScreenPtr pScreen = screenInfo.screens[i]; + ScrnInfoPtr pScrnInfo = xf86Screens[i]; + NVPtr pNv = NVPTR(pScrnInfo); - if (pNv->DMAKickoffCallback) - (*pNv->DMAKickoffCallback)(pNv); - - pScreen->BlockHandler = pNv->BlockHandler; - (*pScreen->BlockHandler) (i, blockData, pTimeout, pReadmask); - pScreen->BlockHandler = NVBlockHandler; + if (pNv->DMAKickoffCallback) + (*pNv->DMAKickoffCallback) (pNv); - if (pNv->VideoTimerCallback) - (*pNv->VideoTimerCallback)(pScrnInfo, currentTime.milliseconds); + pScreen->BlockHandler = pNv->BlockHandler; + (*pScreen->BlockHandler) (i, blockData, pTimeout, pReadmask); + pScreen->BlockHandler = NVBlockHandler; + + if (pNv->VideoTimerCallback) + (*pNv->VideoTimerCallback) (pScrnInfo, + currentTime.milliseconds); } @@ -914,35 +998,38 @@ NVBlockHandler ( */ /* Mandatory */ -static Bool +static Bool NVCloseScreen(int scrnIndex, ScreenPtr pScreen) { - ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; - NVPtr pNv = NVPTR(pScrn); - - if (pScrn->vtSema) { - pScrn->vtSema = FALSE; - NVSync(pScrn); - NVRestore(pScrn); - NVLockUnlock(pNv, 1); - } - - NVUnmapMem(pScrn); - vgaHWUnmapMem(pScrn); - if (pNv->AccelInfoRec) - XAADestroyInfoRec(pNv->AccelInfoRec); - if (pNv->CursorInfoRec) - xf86DestroyCursorInfoRec(pNv->CursorInfoRec); - if (pNv->ShadowPtr) - xfree(pNv->ShadowPtr); - if (pNv->overlayAdaptor) - xfree(pNv->overlayAdaptor); - if (pNv->blitAdaptor) - xfree(pNv->blitAdaptor); - - pScreen->CloseScreen = pNv->CloseScreen; - pScreen->BlockHandler = pNv->BlockHandler; - return (*pScreen->CloseScreen)(scrnIndex, pScreen); + ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; + NVPtr pNv = NVPTR(pScrn); + + if (pScrn->vtSema) { + if (pNv->Architecture == NV_ARCH_50) { + NV50ReleaseDisplay(pScrn); + } else { + NVSync(pScrn); + NVRestore(pScrn); + } + } + + NVUnmapMem(pScrn); + vgaHWUnmapMem(pScrn); + if (pNv->AccelInfoRec) + XAADestroyInfoRec(pNv->AccelInfoRec); + if (pNv->CursorInfoRec) + xf86DestroyCursorInfoRec(pNv->CursorInfoRec); + if (pNv->ShadowPtr) + xfree(pNv->ShadowPtr); + if (pNv->overlayAdaptor) + xfree(pNv->overlayAdaptor); + if (pNv->blitAdaptor) + xfree(pNv->blitAdaptor); + + pScrn->vtSema = FALSE; + pScreen->CloseScreen = pNv->CloseScreen; + pScreen->BlockHandler = pNv->BlockHandler; + return (*pScreen->CloseScreen) (scrnIndex, pScreen); } /* Free up any persistent data structures */ @@ -951,13 +1038,13 @@ NVCloseScreen(int scrnIndex, ScreenPtr pScreen) static void NVFreeScreen(int scrnIndex, int flags) { - /* - * This only gets called when a screen is being deleted. It does not - * get called routinely at the end of a server generation. - */ - if (xf86LoaderCheckSymbol("vgaHWFreeHWRec")) - vgaHWFreeHWRec(xf86Screens[scrnIndex]); - NVFreeRec(xf86Screens[scrnIndex]); + /* + * This only gets called when a screen is being deleted. It does not + * get called routinely at the end of a server generation. + */ + if (xf86LoaderCheckSymbol("vgaHWFreeHWRec")) + vgaHWFreeHWRec(xf86Screens[scrnIndex]); + NVFreeRec(xf86Screens[scrnIndex]); } @@ -967,739 +1054,740 @@ NVFreeScreen(int scrnIndex, int flags) static ModeStatus NVValidMode(int scrnIndex, DisplayModePtr mode, Bool verbose, int flags) { - NVPtr pNv = NVPTR(xf86Screens[scrnIndex]); + NVPtr pNv = NVPTR(xf86Screens[scrnIndex]); - if(pNv->fpWidth && pNv->fpHeight) - if((pNv->fpWidth < mode->HDisplay) || (pNv->fpHeight < mode->VDisplay)) - return (MODE_PANEL); + if (pNv->fpWidth && pNv->fpHeight) + if ((pNv->fpWidth < mode->HDisplay) + || (pNv->fpHeight < mode->VDisplay)) + return (MODE_PANEL); - return (MODE_OK); + return (MODE_OK); } static void nvProbeDDC(ScrnInfoPtr pScrn, int index) { - vbeInfoPtr pVbe; + vbeInfoPtr pVbe; - if (xf86LoadSubModule(pScrn, "vbe")) { - pVbe = VBEInit(NULL,index); - ConfiguredMonitor = vbeDoEDID(pVbe, NULL); - vbeFree(pVbe); - } + if (xf86LoadSubModule(pScrn, "vbe")) { + pVbe = VBEInit(NULL, index); + ConfiguredMonitor = vbeDoEDID(pVbe, NULL); + vbeFree(pVbe); + } } -Bool NVI2CInit(ScrnInfoPtr pScrn) +Bool +NVI2CInit(ScrnInfoPtr pScrn) { - char *mod = "i2c"; + char *mod = "i2c"; - if (xf86LoadSubModule(pScrn, mod)) { - xf86LoaderReqSymLists(i2cSymbols,NULL); + if (xf86LoadSubModule(pScrn, mod)) { + xf86LoaderReqSymLists(i2cSymbols, NULL); - mod = "ddc"; - if(xf86LoadSubModule(pScrn, mod)) { - xf86LoaderReqSymLists(ddcSymbols, NULL); - return NVDACi2cInit(pScrn); - } - } + mod = "ddc"; + if (xf86LoadSubModule(pScrn, mod)) { + xf86LoaderReqSymLists(ddcSymbols, NULL); + return TRUE; + } + } - xf86DrvMsg(pScrn->scrnIndex, X_WARNING, - "Couldn't load %s module. DDC probing can't be done\n", mod); + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, + "Couldn't load %s module. DDC probing can't be done\n", + mod); - return FALSE; + return FALSE; } -static Bool NVPreInitDRI(ScrnInfoPtr pScrn) +static Bool +NVPreInitDRI(ScrnInfoPtr pScrn) { NVPtr pNv = NVPTR(pScrn); - if (!NVDRIGetVersion(pScrn)) + if (!NVDRIGetVersion(pScrn)) return FALSE; - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "[dri] Found DRI library version %d.%d.%d and kernel" - " module version %d.%d.%d\n", - pNv->pLibDRMVersion->version_major, - pNv->pLibDRMVersion->version_minor, - pNv->pLibDRMVersion->version_patchlevel, - pNv->pKernelDRMVersion->version_major, - pNv->pKernelDRMVersion->version_minor, - pNv->pKernelDRMVersion->version_patchlevel); + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "[dri] Found DRI library version %d.%d.%d and kernel" + " module version %d.%d.%d\n", + pNv->pLibDRMVersion->version_major, + pNv->pLibDRMVersion->version_minor, + pNv->pLibDRMVersion->version_patchlevel, + pNv->pKernelDRMVersion->version_major, + pNv->pKernelDRMVersion->version_minor, + pNv->pKernelDRMVersion->version_patchlevel); + + return TRUE; +} + +static Bool +nv_xf86crtc_resize(ScrnInfoPtr scrn, int width, int height) +{ + scrn->virtualX = width; + scrn->virtualY = height; + return TRUE; +} + +static const xf86CrtcConfigFuncsRec nv_xf86crtc_config_funcs = { + nv_xf86crtc_resize +}; + +static Bool +NVDetermineChipsetArch(ScrnInfoPtr pScrn) +{ + NVPtr pNv = NVPTR(pScrn); + + switch (pNv->Chipset & 0x0ff0) { + case CHIPSET_NV03: /* Riva128 */ + pNv->Architecture = NV_ARCH_03; + break; + case CHIPSET_NV04: /* TNT/TNT2 */ + pNv->Architecture = NV_ARCH_04; + break; + case CHIPSET_NV10: /* GeForce 256 */ + case CHIPSET_NV11: /* GeForce2 MX */ + case CHIPSET_NV15: /* GeForce2 */ + case CHIPSET_NV17: /* GeForce4 MX */ + case CHIPSET_NV18: /* GeForce4 MX (8x AGP) */ + case CHIPSET_NFORCE: /* nForce */ + case CHIPSET_NFORCE2: /* nForce2 */ + pNv->Architecture = NV_ARCH_10; + break; + case CHIPSET_NV20: /* GeForce3 */ + case CHIPSET_NV25: /* GeForce4 Ti */ + case CHIPSET_NV28: /* GeForce4 Ti (8x AGP) */ + pNv->Architecture = NV_ARCH_20; + break; + case CHIPSET_NV30: /* GeForceFX 5800 */ + case CHIPSET_NV31: /* GeForceFX 5600 */ + case CHIPSET_NV34: /* GeForceFX 5200 */ + case CHIPSET_NV35: /* GeForceFX 5900 */ + case CHIPSET_NV36: /* GeForceFX 5700 */ + pNv->Architecture = NV_ARCH_30; + break; + case CHIPSET_NV40: /* GeForce 6800 */ + case CHIPSET_NV41: /* GeForce 6800 */ + case 0x0120: /* GeForce 6800 */ + case CHIPSET_NV43: /* GeForce 6600 */ + case CHIPSET_NV44: /* GeForce 6200 */ + case CHIPSET_G72: /* GeForce 7200, 7300, 7400 */ + case CHIPSET_G70: /* GeForce 7800 */ + case CHIPSET_NV45: /* GeForce 6800 */ + case CHIPSET_NV44A: /* GeForce 6200 */ + case CHIPSET_G71: /* GeForce 7900 */ + case CHIPSET_G73: /* GeForce 7600 */ + case CHIPSET_C51: /* GeForce 6100 */ + case CHIPSET_C512: /* Geforce 6100 (nForce 4xx) */ + pNv->Architecture = NV_ARCH_40; + break; + case CHIPSET_NV50: + case CHIPSET_NV84: + pNv->Architecture = NV_ARCH_50; + break; + default: /* Unknown, probably >=NV40 */ + pNv->Architecture = NV_ARCH_40; + break; + } return TRUE; } +#define NVPreInitFail(fmt, args...) do { \ + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "%d: "fmt, __LINE__, ##args); \ + if (pNv->pInt10) \ + xf86FreeInt10(pNv->pInt10); \ + NVFreeRec(pScrn); \ + return FALSE; \ +} while(0) + /* Mandatory */ Bool NVPreInit(ScrnInfoPtr pScrn, int flags) { - NVPtr pNv; - MessageType from; - int i, max_width, max_height; - ClockRangePtr clockRanges; - const char *s; - int config_mon_rates; - - if (flags & PROBE_DETECT) { - EntityInfoPtr pEnt = xf86GetEntityInfo(pScrn->entityList[0]); - - if (!pEnt) - return FALSE; - - i = pEnt->index; - xfree(pEnt); - - nvProbeDDC(pScrn, i); - return TRUE; - } - - /* - * Note: This function is only called once at server startup, and - * not at the start of each server generation. This means that - * only things that are persistent across server generations can - * be initialised here. xf86Screens[] is (pScrn is a pointer to one - * of these). Privates allocated using xf86AllocateScrnInfoPrivateIndex() - * are too, and should be used for data that must persist across - * server generations. - * - * Per-generation data should be allocated with - * AllocateScreenPrivateIndex() from the ScreenInit() function. - */ - - /* Check the number of entities, and fail if it isn't one. */ - if (pScrn->numEntities != 1) - return FALSE; + xf86CrtcConfigPtr xf86_config; + NVPtr pNv; + MessageType from; + int i, max_width, max_height; + ClockRangePtr clockRanges; + const char *s; + int num_crtc; + + if (flags & PROBE_DETECT) { + EntityInfoPtr pEnt = + xf86GetEntityInfo(pScrn->entityList[0]); + + if (!pEnt) + return FALSE; + + i = pEnt->index; + xfree(pEnt); + + nvProbeDDC(pScrn, i); + return TRUE; + } - /* Allocate the NVRec driverPrivate */ - if (!NVGetRec(pScrn)) { - return FALSE; - } - pNv = NVPTR(pScrn); + /* + * Note: This function is only called once at server startup, and + * not at the start of each server generation. This means that + * only things that are persistent across server generations can + * be initialised here. xf86Screens[] is (pScrn is a pointer to one + * of these). Privates allocated using xf86AllocateScrnInfoPrivateIndex() + * are too, and should be used for data that must persist across + * server generations. + * + * Per-generation data should be allocated with + * AllocateScreenPrivateIndex() from the ScreenInit() function. + */ - /* Get the entity, and make sure it is PCI. */ - pNv->pEnt = xf86GetEntityInfo(pScrn->entityList[0]); - if (pNv->pEnt->location.type != BUS_PCI) - return FALSE; - - /* Find the PCI info for this screen */ - pNv->PciInfo = xf86GetPciInfoForEntity(pNv->pEnt->index); - pNv->PciTag = pciTag(pNv->PciInfo->bus, pNv->PciInfo->device, - pNv->PciInfo->func); + /* Check the number of entities, and fail if it isn't one. */ + if (pScrn->numEntities != 1) + return FALSE; + + /* Allocate the NVRec driverPrivate */ + if (!NVGetRec(pScrn)) { + return FALSE; + } + pNv = NVPTR(pScrn); + + /* Get the entity, and make sure it is PCI. */ + pNv->pEnt = xf86GetEntityInfo(pScrn->entityList[0]); + if (pNv->pEnt->location.type != BUS_PCI) + return FALSE; - pNv->Primary = xf86IsPrimaryPci(pNv->PciInfo); + /* Find the PCI info for this screen */ + pNv->PciInfo = xf86GetPciInfoForEntity(pNv->pEnt->index); + pNv->PciTag = pciTag(pNv->PciInfo->bus, pNv->PciInfo->device, + pNv->PciInfo->func); - /* Initialize the card through int10 interface if needed */ - if (xf86LoadSubModule(pScrn, "int10")) { - xf86LoaderReqSymLists(int10Symbols, NULL); + pNv->Primary = xf86IsPrimaryPci(pNv->PciInfo); + + /* Initialize the card through int10 interface if needed */ + if (xf86LoadSubModule(pScrn, "int10")) { + xf86LoaderReqSymLists(int10Symbols, NULL); #if !defined(__alpha__) && !defined(__powerpc__) - xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Initializing int10\n"); - pNv->pInt = xf86InitInt10(pNv->pEnt->index); + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "Initializing int10\n"); + pNv->pInt10 = xf86InitInt10(pNv->pEnt->index); #endif - } - - xf86SetOperatingState(resVgaIo, pNv->pEnt->index, ResUnusedOpr); - xf86SetOperatingState(resVgaMem, pNv->pEnt->index, ResDisableOpr); - - /* Set pScrn->monitor */ - pScrn->monitor = pScrn->confScreen->monitor; - - /* - * Set the Chipset and ChipRev, allowing config file entries to - * override. - */ - if (pNv->pEnt->device->chipset && *pNv->pEnt->device->chipset) { - pScrn->chipset = pNv->pEnt->device->chipset; - pNv->Chipset = xf86StringToToken(NVKnownChipsets, pScrn->chipset); - from = X_CONFIG; - } else if (pNv->pEnt->device->chipID >= 0) { - pNv->Chipset = pNv->pEnt->device->chipID; - pScrn->chipset = (char *)xf86TokenToString(NVKnownChipsets, - pNv->Chipset); - from = X_CONFIG; - xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "ChipID override: 0x%04X\n", - pNv->Chipset); - } else { - from = X_PROBED; - pNv->Chipset = (pNv->PciInfo->vendor << 16) | pNv->PciInfo->chipType; - - if(((pNv->Chipset & 0xfff0) == CHIPSET_MISC_BRIDGED) || - ((pNv->Chipset & 0xfff0) == CHIPSET_G73_BRIDGED)) - { - pNv->Chipset = NVGetPCIXpressChip(pNv->PciInfo); - } - - pScrn->chipset = (char *)xf86TokenToString(NVKnownChipsets, - pNv->Chipset); - if(!pScrn->chipset) - pScrn->chipset = "Unknown NVIDIA chipset"; - } - - if (pNv->pEnt->device->chipRev >= 0) { - pNv->ChipRev = pNv->pEnt->device->chipRev; - xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "ChipRev override: %d\n", - pNv->ChipRev); - } else { - pNv->ChipRev = pNv->PciInfo->chipRev; - } - - /* - * This shouldn't happen because such problems should be caught in - * NVProbe(), but check it just in case. - */ - if (pScrn->chipset == NULL) { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, - "ChipID 0x%04X is not recognised\n", pNv->Chipset); - xf86FreeInt10(pNv->pInt); - return FALSE; - } - if (pNv->Chipset < 0) { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, - "Chipset \"%s\" is not recognised\n", pScrn->chipset); - xf86FreeInt10(pNv->pInt); - return FALSE; - } + } - xf86DrvMsg(pScrn->scrnIndex, from, "Chipset: \"%s\"\n", pScrn->chipset); + xf86SetOperatingState(resVgaIo, pNv->pEnt->index, ResUnusedOpr); + xf86SetOperatingState(resVgaMem, pNv->pEnt->index, ResDisableOpr); + /* Set pScrn->monitor */ + pScrn->monitor = pScrn->confScreen->monitor; - /* - * The first thing we should figure out is the depth, bpp, etc. - */ + /* + * Set the Chipset and ChipRev, allowing config file entries to + * override. + */ + if (pNv->pEnt->device->chipset && *pNv->pEnt->device->chipset) { + pScrn->chipset = pNv->pEnt->device->chipset; + pNv->Chipset = + xf86StringToToken(NVKnownChipsets, pScrn->chipset); + from = X_CONFIG; + } else if (pNv->pEnt->device->chipID >= 0) { + pNv->Chipset = pNv->pEnt->device->chipID; + pScrn->chipset = + (char *) xf86TokenToString(NVKnownChipsets, + pNv->Chipset); + from = X_CONFIG; + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, + "ChipID override: 0x%04X\n", pNv->Chipset); + } else { + from = X_PROBED; + pNv->Chipset = + (pNv->PciInfo->vendor << 16) | pNv->PciInfo->chipType; + + if (((pNv->Chipset & 0xfff0) == CHIPSET_MISC_BRIDGED) || + ((pNv->Chipset & 0xfff0) == CHIPSET_G73_BRIDGED)) { + pNv->Chipset = NVGetPCIXpressChip(pNv->PciInfo); + } + + pScrn->chipset = + (char *) xf86TokenToString(NVKnownChipsets, + pNv->Chipset); + if (!pScrn->chipset) + pScrn->chipset = "Unknown NVIDIA chipset"; + } + + if (pNv->pEnt->device->chipRev >= 0) { + pNv->ChipRev = pNv->pEnt->device->chipRev; + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, + "ChipRev override: %d\n", pNv->ChipRev); + } else { + pNv->ChipRev = pNv->PciInfo->chipRev; + } + + /* + * This shouldn't happen because such problems should be caught in + * NVProbe(), but check it just in case. + */ + if (pScrn->chipset == NULL) + NVPreInitFail("ChipID 0x%04X is not recognised\n", + pNv->Chipset); + + if (pNv->Chipset < 0) + NVPreInitFail("Chipset \"%s\" is not recognised\n", + pScrn->chipset); + + xf86DrvMsg(pScrn->scrnIndex, from, "Chipset: \"%s\"\n", + pScrn->chipset); + NVDetermineChipsetArch(pScrn); + + /* + * The first thing we should figure out is the depth, bpp, etc. + */ + + if (!xf86SetDepthBpp(pScrn, 0, 0, 0, Support32bppFb)) + NVPreInitFail("\n"); - if (!xf86SetDepthBpp(pScrn, 0, 0, 0, Support32bppFb)) { - xf86FreeInt10(pNv->pInt); - return FALSE; - } else { /* Check that the returned depth is one we support */ switch (pScrn->depth) { - case 8: - case 15: - case 16: - case 24: - /* OK */ - break; - default: - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, - "Given depth (%d) is not supported by this driver\n", - pScrn->depth); - xf86FreeInt10(pNv->pInt); - return FALSE; - } - } - xf86PrintDepthBpp(pScrn); - - /* Get the depth24 pixmap format */ - if (pScrn->depth == 24 && pix24bpp == 0) - pix24bpp = xf86GetBppFromDepth(pScrn, 24); - - /* - * This must happen after pScrn->display has been set because - * xf86SetWeight references it. - */ - if (pScrn->depth > 8) { - /* The defaults are OK for us */ - rgb zeros = {0, 0, 0}; - - if (!xf86SetWeight(pScrn, zeros, zeros)) { - xf86FreeInt10(pNv->pInt); - return FALSE; - } - } - - if (!xf86SetDefaultVisual(pScrn, -1)) { - xf86FreeInt10(pNv->pInt); - return FALSE; - } else { + case 8: + case 15: + case 16: + case 24: + /* OK */ + break; + default: + NVPreInitFail("Given depth" + " (%d) is not supported by this driver\n", + pScrn->depth); + break; + } + xf86PrintDepthBpp(pScrn); + + /* Get the depth24 pixmap format */ + if (pScrn->depth == 24 && pix24bpp == 0) + pix24bpp = xf86GetBppFromDepth(pScrn, 24); + + /* + * This must happen after pScrn->display has been set because + * xf86SetWeight references it. + */ + if (pScrn->depth > 8) { + /* The defaults are OK for us */ + rgb zeros = { 0, 0, 0 }; + + if (!xf86SetWeight(pScrn, zeros, zeros)) + NVPreInitFail("\n"); + } + + if (!xf86SetDefaultVisual(pScrn, -1)) + NVPreInitFail("\n"); + /* We don't currently support DirectColor at > 8bpp */ - if (pScrn->depth > 8 && (pScrn->defaultVisual != TrueColor)) { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Given default visual" - " (%s) is not supported at depth %d\n", - xf86GetVisualName(pScrn->defaultVisual), pScrn->depth); - xf86FreeInt10(pNv->pInt); - return FALSE; - } - } - - /* The vgahw module should be loaded here when needed */ - if (!xf86LoadSubModule(pScrn, "vgahw")) { - xf86FreeInt10(pNv->pInt); - return FALSE; - } - - xf86LoaderReqSymLists(vgahwSymbols, NULL); - - /* - * Allocate a vgaHWRec - */ - if (!vgaHWGetHWRec(pScrn)) { - xf86FreeInt10(pNv->pInt); - return FALSE; - } - - /* We use a programmable clock */ - pScrn->progClock = TRUE; + if (pScrn->depth > 8 && (pScrn->defaultVisual != TrueColor)) + NVPreInitFail("Given default visual" + " (%s) is not supported at depth %d\n", + xf86GetVisualName(pScrn->defaultVisual), + pScrn->depth); + + /* The vgahw module should be loaded here when needed */ + if (!xf86LoadSubModule(pScrn, "vgahw")) + NVPreInitFail("\n"); + xf86LoaderReqSymLists(vgahwSymbols, NULL); + + /* + * Allocate a vgaHWRec + */ + if (!vgaHWGetHWRec(pScrn)) + NVPreInitFail("\n"); + + /* We use a programmable clock */ + pScrn->progClock = TRUE; + + /* Collect all of the relevant option flags (fill in pScrn->options) */ + xf86CollectOptions(pScrn, NULL); + + /* Process the options */ + if (!(pNv->Options = xalloc(sizeof(NVOptions)))) + NVPreInitFail("\n"); + memcpy(pNv->Options, NVOptions, sizeof(NVOptions)); + xf86ProcessOptions(pScrn->scrnIndex, pScrn->options, pNv->Options); + + /* Set the bits per RGB for 8bpp mode */ + if (pScrn->depth == 8) + pScrn->rgbBits = 8; + + from = X_DEFAULT; + pNv->HWCursor = TRUE; + /* + * The preferred method is to use the "hw cursor" option as a tri-state + * option, with the default set above. + */ + if (xf86GetOptValBool + (pNv->Options, OPTION_HW_CURSOR, &pNv->HWCursor)) { + from = X_CONFIG; + } + /* For compatibility, accept this too (as an override) */ + if (xf86ReturnOptValBool(pNv->Options, OPTION_SW_CURSOR, FALSE)) { + from = X_CONFIG; + pNv->HWCursor = FALSE; + } + xf86DrvMsg(pScrn->scrnIndex, from, "Using %s cursor\n", + pNv->HWCursor ? "HW" : "SW"); + + pNv->FpScale = TRUE; + if (xf86GetOptValBool + (pNv->Options, OPTION_FP_SCALE, &pNv->FpScale)) { + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, + "Flat panel scaling %s\n", + pNv->FpScale ? "on" : "off"); + } + if (xf86ReturnOptValBool(pNv->Options, OPTION_NOACCEL, FALSE)) { + pNv->NoAccel = TRUE; + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, + "Acceleration disabled\n"); + } - /* Collect all of the relevant option flags (fill in pScrn->options) */ - xf86CollectOptions(pScrn, NULL); + if (xf86ReturnOptValBool(pNv->Options, OPTION_SHADOW_FB, FALSE)) { + pNv->ShadowFB = TRUE; + pNv->NoAccel = TRUE; + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, + "Using \"Shadow Framebuffer\" - acceleration disabled\n"); + } + if (!pNv->NoAccel) { + from = X_DEFAULT; + pNv->useEXA = TRUE; + if ((s = + (char *) xf86GetOptValString(pNv->Options, + OPTION_ACCELMETHOD))) { + if (!xf86NameCmp(s, "XAA")) { + from = X_CONFIG; + pNv->useEXA = FALSE; + } else if (!xf86NameCmp(s, "EXA")) { + from = X_CONFIG; + pNv->useEXA = TRUE; + } + } + xf86DrvMsg(pScrn->scrnIndex, from, + "Using %s acceleration method\n", + pNv->useEXA ? "EXA" : "XAA"); + } else { + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, + "Acceleration disabled\n"); + } - /* Process the options */ - if (!(pNv->Options = xalloc(sizeof(NVOptions)))) - return FALSE; - memcpy(pNv->Options, NVOptions, sizeof(NVOptions)); - xf86ProcessOptions(pScrn->scrnIndex, pScrn->options, pNv->Options); - - /* Set the bits per RGB for 8bpp mode */ - if (pScrn->depth == 8) - pScrn->rgbBits = 8; - - from = X_DEFAULT; - pNv->HWCursor = TRUE; - /* - * The preferred method is to use the "hw cursor" option as a tri-state - * option, with the default set above. - */ - if (xf86GetOptValBool(pNv->Options, OPTION_HW_CURSOR, &pNv->HWCursor)) { - from = X_CONFIG; - } - /* For compatibility, accept this too (as an override) */ - if (xf86ReturnOptValBool(pNv->Options, OPTION_SW_CURSOR, FALSE)) { - from = X_CONFIG; - pNv->HWCursor = FALSE; - } - xf86DrvMsg(pScrn->scrnIndex, from, "Using %s cursor\n", - pNv->HWCursor ? "HW" : "SW"); - - pNv->FpScale = TRUE; - if (xf86GetOptValBool(pNv->Options, OPTION_FP_SCALE, &pNv->FpScale)) { - xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Flat panel scaling %s\n", - pNv->FpScale ? "on" : "off"); - } - if (xf86ReturnOptValBool(pNv->Options, OPTION_NOACCEL, FALSE)) { - pNv->NoAccel = TRUE; - xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Acceleration disabled\n"); - } - if (xf86ReturnOptValBool(pNv->Options, OPTION_SHADOW_FB, FALSE)) { - pNv->ShadowFB = TRUE; - pNv->NoAccel = TRUE; - xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, - "Using \"Shadow Framebuffer\" - acceleration disabled\n"); - } - if (!pNv->NoAccel) { - from = X_DEFAULT; - pNv->useEXA = TRUE; - if((s = (char *)xf86GetOptValString(pNv->Options, OPTION_ACCELMETHOD))) { - if(!xf86NameCmp(s,"XAA")) { - from = X_CONFIG; - pNv->useEXA = FALSE; - } else if(!xf86NameCmp(s,"EXA")) { - from = X_CONFIG; - pNv->useEXA = TRUE; - } - } - xf86DrvMsg(pScrn->scrnIndex, from, "Using %s acceleration method\n", pNv->useEXA ? "EXA" : "XAA"); - } else { - xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Acceleration disabled\n"); - } - - pNv->Rotate = 0; - pNv->RandRRotation = FALSE; - if ((s = xf86GetOptValString(pNv->Options, OPTION_ROTATE))) { - if(!xf86NameCmp(s, "CW")) { - pNv->ShadowFB = TRUE; - pNv->NoAccel = TRUE; - pNv->HWCursor = FALSE; - pNv->Rotate = 1; - xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, - "Rotating screen clockwise - acceleration disabled\n"); - } else - if(!xf86NameCmp(s, "CCW")) { - pNv->ShadowFB = TRUE; - pNv->NoAccel = TRUE; - pNv->HWCursor = FALSE; - pNv->Rotate = -1; - xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, - "Rotating screen counter clockwise - acceleration disabled\n"); - } else - if(!xf86NameCmp(s, "RandR")) { + pNv->Rotate = 0; + pNv->RandRRotation = FALSE; + if ((s = xf86GetOptValString(pNv->Options, OPTION_ROTATE))) { + if (!xf86NameCmp(s, "CW")) { + pNv->ShadowFB = TRUE; + pNv->NoAccel = TRUE; + pNv->HWCursor = FALSE; + pNv->Rotate = 1; + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, + "Rotating screen clockwise - acceleration disabled\n"); + } else if (!xf86NameCmp(s, "CCW")) { + pNv->ShadowFB = TRUE; + pNv->NoAccel = TRUE; + pNv->HWCursor = FALSE; + pNv->Rotate = -1; + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, + "Rotating screen counter clockwise - acceleration disabled\n"); + } else if (!xf86NameCmp(s, "RandR")) { #ifdef RANDR - pNv->ShadowFB = TRUE; - pNv->NoAccel = TRUE; - pNv->HWCursor = FALSE; - pNv->RandRRotation = TRUE; - xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, - "Using RandR rotation - acceleration disabled\n"); + pNv->ShadowFB = TRUE; + pNv->NoAccel = TRUE; + pNv->HWCursor = FALSE; + pNv->RandRRotation = TRUE; + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, + "Using RandR rotation - acceleration disabled\n"); #else - xf86DrvMsg(pScrn->scrnIndex, X_WARNING, - "This driver was not compiled with support for the Resize and " - "Rotate extension. Cannot honor 'Option \"Rotate\" " - "\"RandR\"'.\n"); + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, + "This driver was not compiled with support for the Resize and " + "Rotate extension. Cannot honor 'Option \"Rotate\" " + "\"RandR\"'.\n"); #endif - } else { - xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, - "\"%s\" is not a valid value for Option \"Rotate\"\n", s); - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "Valid options are \"CW\", \"CCW\", and \"RandR\"\n"); - } - } - - if(xf86GetOptValInteger(pNv->Options, OPTION_VIDEO_KEY, &(pNv->videoKey))) { - xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "video key set to 0x%x\n", - pNv->videoKey); - } else { - pNv->videoKey = (1 << pScrn->offset.red) | - (1 << pScrn->offset.green) | - (((pScrn->mask.blue >> pScrn->offset.blue) - 1) << pScrn->offset.blue); - } - - if (xf86GetOptValBool(pNv->Options, OPTION_FLAT_PANEL, &(pNv->FlatPanel))) { - xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "forcing %s usage\n", - pNv->FlatPanel ? "DFP" : "CRTC"); - } else { - pNv->FlatPanel = -1; /* autodetect later */ - } - - pNv->FPDither = FALSE; - if (xf86GetOptValBool(pNv->Options, OPTION_FP_DITHER, &(pNv->FPDither))) - xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "enabling flat panel dither\n"); - - if (xf86GetOptValInteger(pNv->Options, OPTION_CRTC_NUMBER, - &pNv->CRTCnumber)) - { - if((pNv->CRTCnumber < 0) || (pNv->CRTCnumber > 1)) { - pNv->CRTCnumber = -1; - xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, - "Invalid CRTC number. Must be 0 or 1\n"); - } - } else { - pNv->CRTCnumber = -1; /* autodetect later */ - } - - - if (xf86GetOptValInteger(pNv->Options, OPTION_FP_TWEAK, - &pNv->PanelTweak)) - { - pNv->usePanelTweak = TRUE; - } else { - pNv->usePanelTweak = FALSE; - } - - if (pNv->pEnt->device->MemBase != 0) { - /* Require that the config file value matches one of the PCI values. */ - if (!xf86CheckPciMemBase(pNv->PciInfo, pNv->pEnt->device->MemBase)) { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, - "MemBase 0x%08lX doesn't match any PCI base register.\n", - pNv->pEnt->device->MemBase); - xf86FreeInt10(pNv->pInt); - NVFreeRec(pScrn); - return FALSE; - } - pNv->VRAMPhysical = pNv->pEnt->device->MemBase; - from = X_CONFIG; - } else { - if (pNv->PciInfo->memBase[1] != 0) { - pNv->VRAMPhysical = pNv->PciInfo->memBase[1] & 0xff800000; - from = X_PROBED; + } else { + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, + "\"%s\" is not a valid value for Option \"Rotate\"\n", + s); + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "Valid options are \"CW\", \"CCW\", and \"RandR\"\n"); + } + } + + if (xf86GetOptValInteger + (pNv->Options, OPTION_VIDEO_KEY, &(pNv->videoKey))) { + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, + "video key set to 0x%x\n", pNv->videoKey); + } else { + pNv->videoKey = (1 << pScrn->offset.red) | + (1 << pScrn->offset.green) | + (((pScrn->mask.blue >> pScrn->offset.blue) - + 1) << pScrn->offset.blue); + } + + if (xf86GetOptValBool + (pNv->Options, OPTION_FLAT_PANEL, &(pNv->FlatPanel))) { + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, + "forcing %s usage\n", + pNv->FlatPanel ? "DFP" : "CRTC"); } else { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, - "No valid FB address in PCI config space\n"); - xf86FreeInt10(pNv->pInt); - NVFreeRec(pScrn); - return FALSE; - } - } - xf86DrvMsg(pScrn->scrnIndex, from, "Linear framebuffer at 0x%lX\n", - (unsigned long)pNv->VRAMPhysical); - - if (pNv->pEnt->device->IOBase != 0) { - /* Require that the config file value matches one of the PCI values. */ - if (!xf86CheckPciMemBase(pNv->PciInfo, pNv->pEnt->device->IOBase)) { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, - "IOBase 0x%08lX doesn't match any PCI base register.\n", - pNv->pEnt->device->IOBase); - xf86FreeInt10(pNv->pInt); - NVFreeRec(pScrn); - return FALSE; - } - pNv->IOAddress = pNv->pEnt->device->IOBase; - from = X_CONFIG; - } else { - if (pNv->PciInfo->memBase[0] != 0) { - pNv->IOAddress = pNv->PciInfo->memBase[0] & 0xffffc000; - from = X_PROBED; + pNv->FlatPanel = -1; /* autodetect later */ + } + + pNv->FPDither = FALSE; + if (xf86GetOptValBool + (pNv->Options, OPTION_FP_DITHER, &(pNv->FPDither))) + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, + "enabling flat panel dither\n"); + + if (xf86GetOptValInteger(pNv->Options, OPTION_CRTC_NUMBER, + &pNv->CRTCnumber)) { + if ((pNv->CRTCnumber < 0) || (pNv->CRTCnumber > 1)) { + pNv->CRTCnumber = -1; + xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, + "Invalid CRTC number. Must be 0 or 1\n"); + } } else { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, - "No valid MMIO address in PCI config space\n"); - xf86FreeInt10(pNv->pInt); - NVFreeRec(pScrn); - return FALSE; - } - } - xf86DrvMsg(pScrn->scrnIndex, from, "MMIO registers at 0x%lX\n", - (unsigned long)pNv->IOAddress); - - if (xf86RegisterResources(pNv->pEnt->index, NULL, ResExclusive)) { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, - "xf86RegisterResources() found resource conflicts\n"); - xf86FreeInt10(pNv->pInt); - NVFreeRec(pScrn); - return FALSE; - } - - switch (pNv->Chipset & 0x0ff0) { - case CHIPSET_NV03: /* Riva128 */ - pNv->Architecture = NV_ARCH_03; - break; - case CHIPSET_NV04: /* TNT/TNT2 */ - pNv->Architecture = NV_ARCH_04; - break; - case CHIPSET_NV10: /* GeForce 256 */ - case CHIPSET_NV11: /* GeForce2 MX */ - case CHIPSET_NV15: /* GeForce2 */ - case CHIPSET_NV17: /* GeForce4 MX */ - case CHIPSET_NV18: /* GeForce4 MX (8x AGP) */ - case CHIPSET_NFORCE: /* nForce */ - case CHIPSET_NFORCE2:/* nForce2 */ - pNv->Architecture = NV_ARCH_10; - break; - case CHIPSET_NV20: /* GeForce3 */ - case CHIPSET_NV25: /* GeForce4 Ti */ - case CHIPSET_NV28: /* GeForce4 Ti (8x AGP) */ - pNv->Architecture = NV_ARCH_20; - break; - case CHIPSET_NV30: /* GeForceFX 5800 */ - case CHIPSET_NV31: /* GeForceFX 5600 */ - case CHIPSET_NV34: /* GeForceFX 5200 */ - case CHIPSET_NV35: /* GeForceFX 5900 */ - case CHIPSET_NV36: /* GeForceFX 5700 */ - pNv->Architecture = NV_ARCH_30; - break; - case CHIPSET_NV40: /* GeForce 6800 */ - case CHIPSET_NV41: /* GeForce 6800 */ - case 0x0120: /* GeForce 6800 */ - case CHIPSET_NV43: /* GeForce 6600 */ - case CHIPSET_NV44: /* GeForce 6200 */ - case CHIPSET_G72: /* GeForce 7200, 7300, 7400 */ - case CHIPSET_G70: /* GeForce 7800 */ - case CHIPSET_NV45: /* GeForce 6800 */ - case CHIPSET_NV44A: /* GeForce 6200 */ - case CHIPSET_G71: /* GeForce 7900 */ - case CHIPSET_G73: /* GeForce 7600 */ - case CHIPSET_C51: /* GeForce 6100 */ - case CHIPSET_C512: /* Geforce 6100 (nForce 4xx) */ - pNv->Architecture = NV_ARCH_40; - break; - default: /* Unknown, probably >=NV40 */ - pNv->Architecture = NV_ARCH_40; - break; - } - - pNv->alphaCursor = (pNv->Architecture >= NV_ARCH_10) && - ((pNv->Chipset & 0x0ff0) != CHIPSET_NV10); - - if (NVPreInitDRI(pScrn) == FALSE) { - xf86FreeInt10(pNv->pInt); - return FALSE; - } - - if ((pScrn->monitor->nHsync == 0) && - (pScrn->monitor->nVrefresh == 0)) - config_mon_rates = FALSE; - else - config_mon_rates = TRUE; - - NVCommonSetup(pScrn); - - pScrn->videoRam = pNv->RamAmountKBytes; - xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "VideoRAM: %d kBytes\n", - pScrn->videoRam); - + pNv->CRTCnumber = -1; /* autodetect later */ + } + + + if (xf86GetOptValInteger(pNv->Options, OPTION_FP_TWEAK, + &pNv->PanelTweak)) { + pNv->usePanelTweak = TRUE; + } else { + pNv->usePanelTweak = FALSE; + } + + if (pNv->pEnt->device->MemBase != 0) { + /* Require that the config file value matches one of the PCI values. */ + if (!xf86CheckPciMemBase + (pNv->PciInfo, pNv->pEnt->device->MemBase)) + NVPreInitFail("MemBase 0x%08lX doesn't match any" + " PCI base register.\n", + pNv->pEnt->device->MemBase); + pNv->VRAMPhysical = pNv->pEnt->device->MemBase; + from = X_CONFIG; + } else { + if (pNv->PciInfo->memBase[1] == 0) + NVPreInitFail("No valid FB address in PCI" + " config space\n"); + + pNv->VRAMPhysical = pNv->PciInfo->memBase[1] & 0xff800000; + from = X_PROBED; + } + xf86DrvMsg(pScrn->scrnIndex, from, "Linear framebuffer at 0x%lX\n", + (unsigned long) pNv->VRAMPhysical); + + if (pNv->pEnt->device->IOBase != 0) { + /* Require that the config file value matches one of the PCI values. */ + if (!xf86CheckPciMemBase + (pNv->PciInfo, pNv->pEnt->device->IOBase)) + NVPreInitFail("IOBase 0x%08lX doesn't match any" + " PCI base register.\n", + pNv->pEnt->device->IOBase); + pNv->IOAddress = pNv->pEnt->device->IOBase; + from = X_CONFIG; + } else { + if (pNv->PciInfo->memBase[0] == 0) + NVPreInitFail("No valid MMIO address in" + " PCI config space\n"); + + pNv->IOAddress = pNv->PciInfo->memBase[0] & 0xffffc000; + from = X_PROBED; + } + xf86DrvMsg(pScrn->scrnIndex, from, "MMIO registers at 0x%lX\n", + (unsigned long) pNv->IOAddress); + + if (xf86RegisterResources(pNv->pEnt->index, NULL, ResExclusive)) + NVPreInitFail("xf86RegisterResources() found" + " resource conflicts\n"); + + pNv->alphaCursor = (pNv->Architecture >= NV_ARCH_10) && + ((pNv->Chipset & 0x0ff0) != CHIPSET_NV10); + + + /* Allocate an xf86CrtcConfig */ + xf86CrtcConfigInit(pScrn, &nv_xf86crtc_config_funcs); + xf86_config = XF86_CRTC_CONFIG_PTR(pScrn); + + max_width = 16384; + xf86CrtcSetSizeRange(pScrn, 320, 200, max_width, 2048); + + if (!NVPreInitDRI(pScrn)) + NVPreInitFail("\n"); + + NVCommonSetup(pScrn); + + if (pNv->Architecture < NV_ARCH_50) { + NVI2CInit(pScrn); + + num_crtc = pNv->twoHeads ? 2 : 1; + for (i = 0; i < num_crtc; i++) { + nv_crtc_init(pScrn, i); + } + + NvSetupOutputs(pScrn); + } else { + if (!NV50DispPreInit(pScrn)) + NVPreInitFail("\n"); + if (!NV50CreateOutputs(pScrn)) + NVPreInitFail("\n"); + NV50DispCreateCrtcs(pScrn); + } + + +#if 0 + /* Do an initial detection of the outputs while none are configured on yet. + * This will give us some likely legitimate response for later if both + * pipes are already allocated and we're asked to do a detect. + */ + for (i = 0; i < xf86_config->num_output; i++) { + xf86OutputPtr output = xf86_config->output[i]; + + output->status = (*output->funcs->detect) (output); + } +#endif + + if (!xf86InitialConfiguration(pScrn, FALSE)) + NVPreInitFail("No valid modes.\n"); + + pScrn->videoRam = pNv->RamAmountKBytes; + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "VideoRAM: %d kBytes\n", + pScrn->videoRam); + pNv->VRAMPhysicalSize = pScrn->videoRam * 1024; - /* - * If the driver can do gamma correction, it should call xf86SetGamma() - * here. - */ - - { - Gamma zeros = {0.0, 0.0, 0.0}; - - if (!xf86SetGamma(pScrn, zeros)) { - xf86FreeInt10(pNv->pInt); - return FALSE; - } - } - - /* - * Setup the ClockRanges, which describe what clock ranges are available, - * and what sort of modes they can be used for. - */ - - clockRanges = xnfcalloc(sizeof(ClockRange), 1); - clockRanges->next = NULL; - clockRanges->minClock = pNv->MinVClockFreqKHz; - clockRanges->maxClock = pNv->MaxVClockFreqKHz; - clockRanges->clockIndex = -1; /* programmable */ - clockRanges->doubleScanAllowed = TRUE; - if((pNv->Architecture == NV_ARCH_20) || - ((pNv->Architecture == NV_ARCH_10) && - ((pNv->Chipset & 0x0ff0) != CHIPSET_NV10) && - ((pNv->Chipset & 0x0ff0) != CHIPSET_NV15))) - { - /* HW is broken */ - clockRanges->interlaceAllowed = FALSE; - } else { - clockRanges->interlaceAllowed = TRUE; - } - - if(pNv->FlatPanel == 1) { - clockRanges->interlaceAllowed = FALSE; - clockRanges->doubleScanAllowed = FALSE; - } - - if(pNv->Architecture < NV_ARCH_10) { - max_width = (pScrn->bitsPerPixel > 16) ? 2032 : 2048; - max_height = 2048; - } else { - max_width = (pScrn->bitsPerPixel > 16) ? 4080 : 4096; - max_height = 4096; - } - - /* If DFP, add a modeline corresponding to its panel size */ - if (pNv->FlatPanel && !pNv->Television && pNv->fpWidth && pNv->fpHeight) { - DisplayModePtr Mode; - - Mode = xnfcalloc(1, sizeof(DisplayModeRec)); - Mode = xf86CVTMode(pNv->fpWidth, pNv->fpHeight, 60.00, TRUE, FALSE); - Mode->type = M_T_DRIVER; - pScrn->monitor->Modes = xf86ModesAdd(pScrn->monitor->Modes, Mode); - - if (!config_mon_rates) { - if (!Mode->HSync) - Mode->HSync = ((float) Mode->Clock ) / ((float) Mode->HTotal); - if (!Mode->VRefresh) - Mode->VRefresh = (1000.0 * ((float) Mode->Clock)) / - ((float) (Mode->HTotal * Mode->VTotal)); - - if (Mode->HSync < pScrn->monitor->hsync[0].lo) - pScrn->monitor->hsync[0].lo = Mode->HSync; - if (Mode->HSync > pScrn->monitor->hsync[0].hi) - pScrn->monitor->hsync[0].hi = Mode->HSync; - if (Mode->VRefresh < pScrn->monitor->vrefresh[0].lo) - pScrn->monitor->vrefresh[0].lo = Mode->VRefresh; - if (Mode->VRefresh > pScrn->monitor->vrefresh[0].hi) - pScrn->monitor->vrefresh[0].hi = Mode->VRefresh; - - pScrn->monitor->nHsync = 1; - pScrn->monitor->nVrefresh = 1; - } - } - - /* - * xf86ValidateModes will check that the mode HTotal and VTotal values - * don't exceed the chipset's limit if pScrn->maxHValue and - * pScrn->maxVValue are set. Since our NVValidMode() already takes - * care of this, we don't worry about setting them here. - */ - i = xf86ValidateModes(pScrn, pScrn->monitor->Modes, - pScrn->display->modes, clockRanges, - NULL, 256, max_width, - 512, 128, max_height, - pScrn->display->virtualX, - pScrn->display->virtualY, - pNv->VRAMPhysicalSize / 2, - LOOKUP_BEST_REFRESH); - - if (i == -1) { - xf86FreeInt10(pNv->pInt); - NVFreeRec(pScrn); - return FALSE; - } + /* + * If the driver can do gamma correction, it should call xf86SetGamma() + * here. + */ - /* Prune the modes marked as invalid */ - xf86PruneDriverModes(pScrn); + { + Gamma zeros = { 0.0, 0.0, 0.0 }; - if (i == 0 || pScrn->modes == NULL) { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "No valid modes found\n"); - xf86FreeInt10(pNv->pInt); - NVFreeRec(pScrn); - return FALSE; - } + if (!xf86SetGamma(pScrn, zeros)) + NVPreInitFail("\n"); + } - /* - * Set the CRTC parameters for all of the modes based on the type - * of mode, and the chipset's interlace requirements. - * - * Calling this is required if the mode->Crtc* values are used by the - * driver and if the driver doesn't provide code to set them. They - * are not pre-initialised at all. - */ - xf86SetCrtcForModes(pScrn, 0); + /* + * Setup the ClockRanges, which describe what clock ranges are available, + * and what sort of modes they can be used for. + */ - /* Set the current mode to the first in the list */ - pScrn->currentMode = pScrn->modes; + clockRanges = xnfcalloc(sizeof(ClockRange), 1); + clockRanges->next = NULL; + clockRanges->minClock = pNv->MinVClockFreqKHz; + clockRanges->maxClock = pNv->MaxVClockFreqKHz; + clockRanges->clockIndex = -1; /* programmable */ + clockRanges->doubleScanAllowed = TRUE; + if ((pNv->Architecture == NV_ARCH_20) || + ((pNv->Architecture == NV_ARCH_10) && + ((pNv->Chipset & 0x0ff0) != CHIPSET_NV10) && + ((pNv->Chipset & 0x0ff0) != CHIPSET_NV15))) { + /* HW is broken */ + clockRanges->interlaceAllowed = FALSE; + } else { + clockRanges->interlaceAllowed = TRUE; + } - /* Print the list of modes being used */ - xf86PrintModes(pScrn); + if (pNv->FlatPanel == 1) { + clockRanges->interlaceAllowed = FALSE; + clockRanges->doubleScanAllowed = FALSE; + } - /* Set display resolution */ - xf86SetDpi(pScrn, 0, 0); + if (pNv->Architecture < NV_ARCH_10) { + max_width = (pScrn->bitsPerPixel > 16) ? 2032 : 2048; + max_height = 2048; + } else { + max_width = (pScrn->bitsPerPixel > 16) ? 4080 : 4096; + max_height = 4096; + } + /* + * xf86ValidateModes will check that the mode HTotal and VTotal values + * don't exceed the chipset's limit if pScrn->maxHValue and + * pScrn->maxVValue are set. Since our NVValidMode() already takes + * care of this, we don't worry about setting them here. + */ + i = xf86ValidateModes(pScrn, pScrn->monitor->Modes, + pScrn->display->modes, clockRanges, + NULL, 256, max_width, + 512, 128, max_height, + pScrn->display->virtualX, + pScrn->display->virtualY, + pNv->VRAMPhysicalSize / 2, + LOOKUP_BEST_REFRESH); + + if (i == -1) + NVPreInitFail("\n"); + + /* Prune the modes marked as invalid */ + xf86PruneDriverModes(pScrn); + + if (i == 0 || pScrn->modes == NULL) + NVPreInitFail("No valid modes found.\n"); + + /* + * Set the CRTC parameters for all of the modes based on the type + * of mode, and the chipset's interlace requirements. + * + * Calling this is required if the mode->Crtc* values are used by the + * driver and if the driver doesn't provide code to set them. They + * are not pre-initialised at all. + */ + xf86SetCrtcForModes(pScrn, 0); - /* - * XXX This should be taken into account in some way in the mode valdation - * section. - */ + /* Set the current mode to the first in the list */ + pScrn->currentMode = pScrn->modes; - if (xf86LoadSubModule(pScrn, "fb") == NULL) { - xf86FreeInt10(pNv->pInt); - NVFreeRec(pScrn); - return FALSE; - } - - xf86LoaderReqSymLists(fbSymbols, NULL); - - /* Load XAA if needed */ - if (!pNv->NoAccel) { - if (!xf86LoadSubModule(pScrn, pNv->useEXA ? "exa" : "xaa")) { - xf86FreeInt10(pNv->pInt); - NVFreeRec(pScrn); - return FALSE; - } - xf86LoaderReqSymLists(xaaSymbols, NULL); - } - - /* Load ramdac if needed */ - if (pNv->HWCursor) { - if (!xf86LoadSubModule(pScrn, "ramdac")) { - xf86FreeInt10(pNv->pInt); - NVFreeRec(pScrn); - return FALSE; - } - xf86LoaderReqSymLists(ramdacSymbols, NULL); - } - - /* Load shadowfb if needed */ - if (pNv->ShadowFB) { - if (!xf86LoadSubModule(pScrn, "shadowfb")) { - xf86FreeInt10(pNv->pInt); - NVFreeRec(pScrn); - return FALSE; - } - xf86LoaderReqSymLists(shadowSymbols, NULL); - } - - pNv->CurrentLayout.bitsPerPixel = pScrn->bitsPerPixel; - pNv->CurrentLayout.depth = pScrn->depth; - pNv->CurrentLayout.displayWidth = pScrn->displayWidth; - pNv->CurrentLayout.weight.red = pScrn->weight.red; - pNv->CurrentLayout.weight.green = pScrn->weight.green; - pNv->CurrentLayout.weight.blue = pScrn->weight.blue; - pNv->CurrentLayout.mode = pScrn->currentMode; - - xf86FreeInt10(pNv->pInt); - - pNv->pInt = NULL; - return TRUE; + /* Print the list of modes being used */ + xf86PrintModes(pScrn); + + /* Set display resolution */ + xf86SetDpi(pScrn, 0, 0); + + + /* + * XXX This should be taken into account in some way in the mode valdation + * section. + */ + + if (xf86LoadSubModule(pScrn, "fb") == NULL) + NVPreInitFail("\n"); + xf86LoaderReqSymLists(fbSymbols, NULL); + + /* Load XAA if needed */ + if (!pNv->NoAccel) { + if (!xf86LoadSubModule(pScrn, pNv->useEXA ? "exa" : "xaa")) + NVPreInitFail("\n"); + xf86LoaderReqSymLists(xaaSymbols, NULL); + } + + /* Load ramdac if needed */ + if (pNv->HWCursor) { + if (!xf86LoadSubModule(pScrn, "ramdac")) + NVPreInitFail("\n"); + xf86LoaderReqSymLists(ramdacSymbols, NULL); + } + + /* Load shadowfb if needed */ + if (pNv->ShadowFB) { + if (!xf86LoadSubModule(pScrn, "shadowfb")) + NVPreInitFail("\n"); + xf86LoaderReqSymLists(shadowSymbols, NULL); + } + + pNv->CurrentLayout.bitsPerPixel = pScrn->bitsPerPixel; + pNv->CurrentLayout.depth = pScrn->depth; + pNv->CurrentLayout.displayWidth = pScrn->displayWidth; + pNv->CurrentLayout.weight.red = pScrn->weight.red; + pNv->CurrentLayout.weight.green = pScrn->weight.green; + pNv->CurrentLayout.weight.blue = pScrn->weight.blue; + pNv->CurrentLayout.mode = pScrn->currentMode; + + if (pScrn->modes == NULL) + NVPreInitFail("No modes.\n"); + + pScrn->currentMode = pScrn->modes; + + return TRUE; } @@ -1712,7 +1800,9 @@ NVMapMem(ScrnInfoPtr pScrn) { NVPtr pNv = NVPTR(pScrn); - pNv->FB = NVAllocateMemory(pNv, NOUVEAU_MEM_FB, pNv->VRAMPhysicalSize/2); + pNv->FB = + NVAllocateMemory(pNv, NOUVEAU_MEM_FB, + pNv->VRAMPhysicalSize / 2); if (!pNv->FB) { ErrorF("Failed to allocate memory for framebuffer!\n"); return FALSE; @@ -1739,8 +1829,8 @@ NVMapMem(ScrnInfoPtr pScrn) "AGPGART: %dMiB available\n", (unsigned int)(pNv->AGPSize >> 20)); - if (pNv->AGPSize > (16*1024*1024)) - gart_scratch_size = 16*1024*1024; + if (pNv->AGPSize > (16 * 1024 * 1024)) + gart_scratch_size = 16 * 1024 * 1024; else gart_scratch_size = pNv->AGPSize; @@ -1772,15 +1862,28 @@ NVMapMem(ScrnInfoPtr pScrn) ErrorF("Failed to allocate memory for hardware cursor\n"); return FALSE; } + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "Allocated %dKiB VRAM for cursor\n", + pNv->Cursor->size >> 10); + + if (pNv->Architecture == NV_ARCH_50) { + pNv->CLUT = NVAllocateMemory(pNv, NOUVEAU_MEM_FB, 0x1000); + if (!pNv->CLUT) { + ErrorF("Failed to allocate memory for CLUT\n"); + return FALSE; + } + } else + pNv->CLUT = NULL; pNv->ScratchBuffer = NVAllocateMemory(pNv, NOUVEAU_MEM_FB, - pNv->Architecture <NV_ARCH_10 ? 8192 : 16384); + pNv->Architecture < + NV_ARCH_10 ? 8192 : 16384); if (!pNv->ScratchBuffer) { ErrorF("Failed to allocate memory for scratch buffer\n"); return FALSE; } - return TRUE; + return TRUE; } /* @@ -1796,7 +1899,7 @@ NVUnmapMem(ScrnInfoPtr pScrn) NVFreeMemory(pNv, pNv->ScratchBuffer); NVFreeMemory(pNv, pNv->Cursor); - return TRUE; + return TRUE; } @@ -1804,178 +1907,156 @@ NVUnmapMem(ScrnInfoPtr pScrn) * Initialise a new mode. */ -static Bool -NVModeInit(ScrnInfoPtr pScrn, DisplayModePtr mode) +/* + * Restore the initial (text) mode. + */ +static void +NVRestore(ScrnInfoPtr pScrn) { - vgaHWPtr hwp = VGAHWPTR(pScrn); - vgaRegPtr vgaReg; - NVPtr pNv = NVPTR(pScrn); - NVRegPtr nvReg; - - /* Initialise the ModeReg values */ - if (!vgaHWInit(pScrn, mode)) - return FALSE; - pScrn->vtSema = TRUE; - - vgaReg = &hwp->ModeReg; - nvReg = &pNv->ModeReg; - - if(!NVDACInit(pScrn, mode)) - return FALSE; + vgaHWPtr hwp = VGAHWPTR(pScrn); + vgaRegPtr vgaReg = &hwp->SavedReg; + NVPtr pNv = NVPTR(pScrn); + xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn); + NVRegPtr nvReg = &pNv->SavedReg; + int i; + int vgaflags = VGA_SR_CMAP | VGA_SR_MODE; - NVLockUnlock(pNv, 0); - if(pNv->twoHeads) { - nvWriteVGA(pNv, NV_VGA_CRTCX_OWNER, nvReg->crtcOwner); - NVLockUnlock(pNv, 0); - } + NVCrtcLockUnlock(xf86_config->crtc[0], 0); + NVCrtcLockUnlock(xf86_config->crtc[1], 0); - /* Program the registers */ - vgaHWProtect(pScrn, TRUE); + for (i = 0; i < xf86_config->num_crtc; i++) { + xf86_config->crtc[i]->funcs->restore(xf86_config->crtc[i]); + } - NVDACRestore(pScrn, vgaReg, nvReg, FALSE); + for (i = 0; i < xf86_config->num_output; i++) { + xf86_config->output[i]->funcs->restore(xf86_config-> + output[i]); + } -#if X_BYTE_ORDER == X_BIG_ENDIAN - /* turn on LFB swapping */ - { - unsigned char tmp; - tmp = nvReadVGA(pNv, NV_VGA_CRTCX_SWAPPING); - tmp |= (1 << 7); - nvWriteVGA(pNv, NV_VGA_CRTCX_SWAPPING, tmp); - } +#ifndef __powerpc__ + vgaflags |= VGA_SR_FONTS; #endif + vgaHWRestore(pScrn, vgaReg, vgaflags); - NVResetGraphics(pScrn); - - vgaHWProtect(pScrn, FALSE); + vgaHWLock(hwp); + NVCrtcLockUnlock(xf86_config->crtc[0], 1); + NVCrtcLockUnlock(xf86_config->crtc[1], 1); - pNv->CurrentLayout.mode = mode; - return TRUE; } -/* - * Restore the initial (text) mode. - */ -static void -NVRestore(ScrnInfoPtr pScrn) -{ - vgaHWPtr hwp = VGAHWPTR(pScrn); - vgaRegPtr vgaReg = &hwp->SavedReg; - NVPtr pNv = NVPTR(pScrn); - NVRegPtr nvReg = &pNv->SavedReg; - - NVLockUnlock(pNv, 0); - - if(pNv->twoHeads) { - nvWriteVGA(pNv, NV_VGA_CRTCX_OWNER, pNv->CRTCnumber * 0x3); - NVLockUnlock(pNv, 0); - } - - /* Only restore text mode fonts/text for the primary card */ - vgaHWProtect(pScrn, TRUE); - NVDACRestore(pScrn, vgaReg, nvReg, pNv->Primary); - if(pNv->twoHeads) { - nvWriteVGA(pNv, NV_VGA_CRTCX_OWNER, pNv->vtOWNER); - } - vgaHWProtect(pScrn, FALSE); -} +#define DEPTH_SHIFT(val, w) ((val << (8 - w)) | (val >> ((w << 1) - 8))) +#define MAKE_INDEX(in, w) (DEPTH_SHIFT(in, w) * 3) -static void NVBacklightEnable(NVPtr pNv, Bool on) +static void +NVLoadPalette(ScrnInfoPtr pScrn, int numColors, int *indices, + LOCO * colors, VisualPtr pVisual) { - /* This is done differently on each laptop. Here we - define the ones we know for sure. */ + xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn); + int c; + NVPtr pNv = NVPTR(pScrn); + int i, index; + + for (c = 0; c < xf86_config->num_crtc; c++) { + xf86CrtcPtr crtc = xf86_config->crtc[c]; + NVCrtcPrivatePtr nv_crtc = crtc->driver_private; + NVCrtcRegPtr regp; + + regp = &pNv->ModeReg.crtc_reg[nv_crtc->crtc]; + + if (crtc->enabled == 0) + continue; + + switch (pNv->CurrentLayout.depth) { + case 15: + for (i = 0; i < numColors; i++) { + index = indices[i]; + regp->DAC[MAKE_INDEX(index, 5) + 0] = + colors[index].red; + regp->DAC[MAKE_INDEX(index, 5) + 1] = + colors[index].green; + regp->DAC[MAKE_INDEX(index, 5) + 2] = + colors[index].blue; + } + break; + case 16: + for (i = 0; i < numColors; i++) { + index = indices[i]; + regp->DAC[MAKE_INDEX(index, 6) + 1] = + colors[index].green; + if (index < 32) { + regp->DAC[MAKE_INDEX(index, 5) + + 0] = colors[index].red; + regp->DAC[MAKE_INDEX(index, 5) + + 2] = colors[index].blue; + } + } + break; + default: + for (i = 0; i < numColors; i++) { + index = indices[i]; + regp->DAC[index * 3] = colors[index].red; + regp->DAC[(index * 3) + 1] = + colors[index].green; + regp->DAC[(index * 3) + 2] = + colors[index].blue; + } + break; + } -#if defined(__powerpc__) - if((pNv->Chipset == 0x10DE0179) || - (pNv->Chipset == 0x10DE0189) || - (pNv->Chipset == 0x10DE0329)) - { - /* NV17,18,34 Apple iMac, iBook, PowerBook */ - CARD32 tmp_pmc, tmp_pcrt; - tmp_pmc = nvReadMC(pNv, 0x10F0) & 0x7FFFFFFF; - tmp_pcrt = nvReadCRTC0(pNv, NV_CRTC_081C) & 0xFFFFFFFC; - if(on) { - tmp_pmc |= (1 << 31); - tmp_pcrt |= 0x1; - } - nvWriteMC(pNv, 0x10F0, tmp_pmc); - nvWriteCRTC0(pNv, NV_CRTC_081C, tmp_pcrt); - } -#endif - - if(pNv->LVDS) { - if(pNv->twoHeads && ((pNv->Chipset & 0x0ff0) != CHIPSET_NV11)) { - nvWriteMC(pNv, 0x130C, on ? 3 : 7); - } - } else { - CARD32 fpcontrol; - - fpcontrol = nvReadCurRAMDAC(pNv, 0x848) & 0xCfffffCC; - - /* cut the TMDS output */ - if(on) fpcontrol |= pNv->fpSyncs; - else fpcontrol |= 0x20000022; - - nvWriteCurRAMDAC(pNv, 0x0848, fpcontrol); - } + NVCrtcLoadPalette(crtc); + } } +//#define DEPTH_SHIFT(val, w) ((val << (8 - w)) | (val >> ((w << 1) - 8))) +#define COLOR(c) (unsigned int)(0x3fff * ((c)/255.0)) static void -NVDPMSSetLCD(ScrnInfoPtr pScrn, int PowerManagementMode, int flags) +NV50LoadPalette(ScrnInfoPtr pScrn, int numColors, int *indices, + LOCO * colors, VisualPtr pVisual) { - NVPtr pNv = NVPTR(pScrn); - - if (!pScrn->vtSema) return; - - vgaHWDPMSSet(pScrn, PowerManagementMode, flags); - - switch (PowerManagementMode) { - case DPMSModeStandby: /* HSync: Off, VSync: On */ - case DPMSModeSuspend: /* HSync: On, VSync: Off */ - case DPMSModeOff: /* HSync: Off, VSync: Off */ - NVBacklightEnable(pNv, 0); - break; - case DPMSModeOn: /* HSync: On, VSync: On */ - NVBacklightEnable(pNv, 1); - default: - break; - } -} - + NVPtr pNv = NVPTR(pScrn); + int i, index; + volatile struct { + unsigned short red, green, blue, unused; + } *lut = (void *) pNv->CLUT->map; -static void -NVDPMSSet(ScrnInfoPtr pScrn, int PowerManagementMode, int flags) -{ - unsigned char crtc1A; - vgaHWPtr hwp = VGAHWPTR(pScrn); - - if (!pScrn->vtSema) return; - - crtc1A = hwp->readCrtc(hwp, 0x1A) & ~0xC0; - - switch (PowerManagementMode) { - case DPMSModeStandby: /* HSync: Off, VSync: On */ - crtc1A |= 0x80; - break; - case DPMSModeSuspend: /* HSync: On, VSync: Off */ - crtc1A |= 0x40; - break; - case DPMSModeOff: /* HSync: Off, VSync: Off */ - crtc1A |= 0xC0; - break; - case DPMSModeOn: /* HSync: On, VSync: On */ - default: - break; - } - - /* vgaHWDPMSSet will merely cut the dac output */ - vgaHWDPMSSet(pScrn, PowerManagementMode, flags); - - hwp->writeCrtc(hwp, 0x1A, crtc1A); + switch (pScrn->depth) { + case 15: + for (i = 0; i < numColors; i++) { + index = indices[i]; + lut[DEPTH_SHIFT(index, 5)].red = + COLOR(colors[index].red); + lut[DEPTH_SHIFT(index, 5)].green = + COLOR(colors[index].green); + lut[DEPTH_SHIFT(index, 5)].blue = + COLOR(colors[index].blue); + } + break; + case 16: + for (i = 0; i < numColors; i++) { + index = indices[i]; + lut[DEPTH_SHIFT(index, 6)].green = + COLOR(colors[index].green); + if (index < 32) { + lut[DEPTH_SHIFT(index, 5)].red = + COLOR(colors[index].red); + lut[DEPTH_SHIFT(index, 5)].blue = + COLOR(colors[index].blue); + } + } + break; + default: + for (i = 0; i < numColors; i++) { + index = indices[i]; + lut[index].red = COLOR(colors[index].red); + lut[index].green = COLOR(colors[index].green); + lut[index].blue = COLOR(colors[index].blue); + } + break; + } } - /* Mandatory */ /* This gets called at the start of each server generation */ @@ -1983,29 +2064,29 @@ NVDPMSSet(ScrnInfoPtr pScrn, int PowerManagementMode, int flags) static Bool NVScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) { - ScrnInfoPtr pScrn; - vgaHWPtr hwp; - NVPtr pNv; - int ret; - VisualPtr visual; - unsigned char *FBStart; - int width, height, displayWidth, offscreenHeight, shadowHeight; - BoxRec AvailFBArea; - - /* - * First get the ScrnInfoRec - */ - pScrn = xf86Screens[pScreen->myNum]; - - hwp = VGAHWPTR(pScrn); - pNv = NVPTR(pScrn); - - /* Map the VGA memory when the primary video */ - if (pNv->Primary) { - hwp->MapSize = 0x10000; - if (!vgaHWMapMem(pScrn)) - return FALSE; - } + ScrnInfoPtr pScrn; + vgaHWPtr hwp; + NVPtr pNv; + int ret; + VisualPtr visual; + unsigned char *FBStart; + int width, height, displayWidth, offscreenHeight, shadowHeight; + BoxRec AvailFBArea; + + /* + * First get the ScrnInfoRec + */ + pScrn = xf86Screens[pScreen->myNum]; + + hwp = VGAHWPTR(pScrn); + pNv = NVPTR(pScrn); + + /* Map the VGA memory when the primary video */ + if (pNv->Primary) { + hwp->MapSize = 0x10000; + if (!vgaHWMapMem(pScrn)) + return FALSE; + } /* First init DRI/DRM */ if (!NVDRIScreenInit(pScrn)) @@ -2023,309 +2104,369 @@ NVScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) if (!NVMapMem(pScrn)) return FALSE; - /* Init DRM - Alloc FIFO */ - if (!NVInitDma(pScrn)) + if (!pNv->NoAccel) { + /* Init DRM - Alloc FIFO */ + if (!NVInitDma(pScrn)) + return FALSE; + + /* setup graphics objects */ + if (!NVAccelCommonInit(pScrn)) + return FALSE; + } + + pScrn->memPhysBase = pNv->VRAMPhysical; + pScrn->fbOffset = 0; + + if (!NVEnterVT(scrnIndex, 0)) return FALSE; - /* setup graphics objects */ - if (!NVAccelCommonInit(pScrn)) + /* Darken the screen for aesthetic reasons and set the viewport */ + // NVSaveScreen(pScreen, SCREEN_SAVER_ON); + // pScrn->AdjustFrame(scrnIndex, pScrn->frameX0, pScrn->frameY0, 0); + + /* + * The next step is to setup the screen's visuals, and initialise the + * framebuffer code. In cases where the framebuffer's default + * choices for things like visual layouts and bits per RGB are OK, + * this may be as simple as calling the framebuffer's ScreenInit() + * function. If not, the visuals will need to be setup before calling + * a fb ScreenInit() function and fixed up after. + * + * For most PC hardware at depths >= 8, the defaults that fb uses + * are not appropriate. In this driver, we fixup the visuals after. + */ + + /* + * Reset the visual list. + */ + miClearVisualTypes(); + + /* Setup the visuals we support. */ + + if (!miSetVisualTypes(pScrn->depth, + miGetDefaultVisualMask(pScrn->depth), 8, + pScrn->defaultVisual)) + return FALSE; + if (!miSetPixmapDepths()) return FALSE; - /* Save the current state */ - NVSave(pScrn); - /* Initialise the first mode */ - if (!NVModeInit(pScrn, pScrn->currentMode)) { - return FALSE; - } - - /* Darken the screen for aesthetic reasons and set the viewport */ - NVSaveScreen(pScreen, SCREEN_SAVER_ON); - pScrn->AdjustFrame(scrnIndex, pScrn->frameX0, pScrn->frameY0, 0); - - /* - * The next step is to setup the screen's visuals, and initialise the - * framebuffer code. In cases where the framebuffer's default - * choices for things like visual layouts and bits per RGB are OK, - * this may be as simple as calling the framebuffer's ScreenInit() - * function. If not, the visuals will need to be setup before calling - * a fb ScreenInit() function and fixed up after. - * - * For most PC hardware at depths >= 8, the defaults that fb uses - * are not appropriate. In this driver, we fixup the visuals after. - */ - - /* - * Reset the visual list. - */ - miClearVisualTypes(); - - /* Setup the visuals we support. */ - - if (!miSetVisualTypes(pScrn->depth, - miGetDefaultVisualMask(pScrn->depth), 8, - pScrn->defaultVisual)) - return FALSE; - if (!miSetPixmapDepths ()) return FALSE; - - /* - * Call the framebuffer layer's ScreenInit function, and fill in other - * pScreen fields. - */ - - width = pScrn->virtualX; - height = pScrn->virtualY; - displayWidth = pScrn->displayWidth; - - - if(pNv->Rotate) { - height = pScrn->virtualX; - width = pScrn->virtualY; - } - - /* If RandR rotation is enabled, leave enough space in the - * framebuffer for us to rotate the screen dimensions without - * changing the pitch. - */ - if(pNv->RandRRotation) - shadowHeight = max(width, height); - else - shadowHeight = height; - - if(pNv->ShadowFB) { - pNv->ShadowPitch = BitmapBytePad(pScrn->bitsPerPixel * width); - pNv->ShadowPtr = xalloc(pNv->ShadowPitch * shadowHeight); - displayWidth = pNv->ShadowPitch / (pScrn->bitsPerPixel >> 3); - FBStart = pNv->ShadowPtr; - } else { - pNv->ShadowPtr = NULL; - FBStart = pNv->FB->map; - } - - switch (pScrn->bitsPerPixel) { - case 8: - case 16: - case 32: - ret = fbScreenInit(pScreen, FBStart, width, height, - pScrn->xDpi, pScrn->yDpi, - displayWidth, pScrn->bitsPerPixel); - break; - default: - xf86DrvMsg(scrnIndex, X_ERROR, - "Internal error: invalid bpp (%d) in NVScreenInit\n", - pScrn->bitsPerPixel); - ret = FALSE; - break; - } - if (!ret) - return FALSE; + /* + * Call the framebuffer layer's ScreenInit function, and fill in other + * pScreen fields. + */ - if (pScrn->bitsPerPixel > 8) { - /* Fixup RGB ordering */ - visual = pScreen->visuals + pScreen->numVisuals; - while (--visual >= pScreen->visuals) { - if ((visual->class | DynamicClass) == DirectColor) { - visual->offsetRed = pScrn->offset.red; - visual->offsetGreen = pScrn->offset.green; - visual->offsetBlue = pScrn->offset.blue; - visual->redMask = pScrn->mask.red; - visual->greenMask = pScrn->mask.green; - visual->blueMask = pScrn->mask.blue; - } - } - } - - fbPictureInit (pScreen, 0, 0); - - xf86SetBlackWhitePixels(pScreen); - - offscreenHeight = pNv->FB->size / - (pScrn->displayWidth * pScrn->bitsPerPixel >> 3); - if(offscreenHeight > 32767) - offscreenHeight = 32767; - - if (!pNv->useEXA) { - AvailFBArea.x1 = 0; - AvailFBArea.y1 = 0; - AvailFBArea.x2 = pScrn->displayWidth; - AvailFBArea.y2 = offscreenHeight; - xf86InitFBManager(pScreen, &AvailFBArea); - } - - if (!pNv->NoAccel) { - if (pNv->useEXA) - NVExaInit(pScreen); - else /* XAA */ - NVXaaInit(pScreen); - } - NVResetGraphics(pScrn); - - miInitializeBackingStore(pScreen); - xf86SetBackingStore(pScreen); - xf86SetSilkenMouse(pScreen); - - /* Finish DRI init */ - NVDRIFinishScreenInit(pScrn); - - /* Initialize software cursor. - Must precede creation of the default colormap */ - miDCInitialize(pScreen, xf86GetPointerScreenFuncs()); - - /* Initialize HW cursor layer. - Must follow software cursor initialization*/ - if (pNv->HWCursor) { - if(!NVCursorInit(pScreen)) - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, - "Hardware cursor initialization failed\n"); - } - - /* Initialise default colourmap */ - if (!miCreateDefColormap(pScreen)) - return FALSE; + width = pScrn->virtualX; + height = pScrn->virtualY; + displayWidth = pScrn->displayWidth; - /* Initialize colormap layer. - Must follow initialization of the default colormap */ - if(!xf86HandleColormaps(pScreen, 256, 8, NVDACLoadPalette, - NULL, CMAP_RELOAD_ON_MODE_SWITCH | CMAP_PALETTED_TRUECOLOR)) - return FALSE; - if(pNv->ShadowFB) { - RefreshAreaFuncPtr refreshArea = NVRefreshArea; + if (pNv->Rotate) { + height = pScrn->virtualX; + width = pScrn->virtualY; + } + + /* If RandR rotation is enabled, leave enough space in the + * framebuffer for us to rotate the screen dimensions without + * changing the pitch. + */ + if (pNv->RandRRotation) + shadowHeight = max(width, height); + else + shadowHeight = height; + + if (pNv->ShadowFB) { + pNv->ShadowPitch = + BitmapBytePad(pScrn->bitsPerPixel * width); + pNv->ShadowPtr = xalloc(pNv->ShadowPitch * shadowHeight); + displayWidth = + pNv->ShadowPitch / (pScrn->bitsPerPixel >> 3); + FBStart = pNv->ShadowPtr; + } else { + pNv->ShadowPtr = NULL; + FBStart = pNv->FB->map; + } - if(pNv->Rotate || pNv->RandRRotation) { - pNv->PointerMoved = pScrn->PointerMoved; - if(pNv->Rotate) - pScrn->PointerMoved = NVPointerMoved; + switch (pScrn->bitsPerPixel) { + case 8: + case 16: + case 32: + ret = fbScreenInit(pScreen, FBStart, width, height, + pScrn->xDpi, pScrn->yDpi, + displayWidth, pScrn->bitsPerPixel); + break; + default: + xf86DrvMsg(scrnIndex, X_ERROR, + "Internal error: invalid bpp (%d) in NVScreenInit\n", + pScrn->bitsPerPixel); + ret = FALSE; + break; + } + if (!ret) + return FALSE; - switch(pScrn->bitsPerPixel) { - case 8: refreshArea = NVRefreshArea8; break; - case 16: refreshArea = NVRefreshArea16; break; - case 32: refreshArea = NVRefreshArea32; break; - } - if(!pNv->RandRRotation) { - xf86DisableRandR(); - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "Driver rotation enabled, RandR disabled\n"); - } + if (pScrn->bitsPerPixel > 8) { + /* Fixup RGB ordering */ + visual = pScreen->visuals + pScreen->numVisuals; + while (--visual >= pScreen->visuals) { + if ((visual->class | DynamicClass) == DirectColor) { + visual->offsetRed = pScrn->offset.red; + visual->offsetGreen = pScrn->offset.green; + visual->offsetBlue = pScrn->offset.blue; + visual->redMask = pScrn->mask.red; + visual->greenMask = pScrn->mask.green; + visual->blueMask = pScrn->mask.blue; + } + } } - ShadowFBInit(pScreen, refreshArea); - } + fbPictureInit(pScreen, 0, 0); - if(pNv->FlatPanel) - xf86DPMSInit(pScreen, NVDPMSSetLCD, 0); - else - xf86DPMSInit(pScreen, NVDPMSSet, 0); - - pScrn->memPhysBase = pNv->VRAMPhysical; - pScrn->fbOffset = 0; + xf86SetBlackWhitePixels(pScreen); - if(pNv->Rotate == 0 && !pNv->RandRRotation) - NVInitVideo(pScreen); + offscreenHeight = pNv->FB->size / + (pScrn->displayWidth * pScrn->bitsPerPixel >> 3); + if (offscreenHeight > 32767) + offscreenHeight = 32767; - pScreen->SaveScreen = NVSaveScreen; + if (!pNv->useEXA) { + AvailFBArea.x1 = 0; + AvailFBArea.y1 = 0; + AvailFBArea.x2 = pScrn->displayWidth; + AvailFBArea.y2 = offscreenHeight; + xf86InitFBManager(pScreen, &AvailFBArea); + } - /* Wrap the current CloseScreen function */ - pNv->CloseScreen = pScreen->CloseScreen; - pScreen->CloseScreen = NVCloseScreen; + if (!pNv->NoAccel) { + if (pNv->useEXA) + NVExaInit(pScreen); + else /* XAA */ + NVXaaInit(pScreen); + } + NVResetGraphics(pScrn); - pNv->BlockHandler = pScreen->BlockHandler; - pScreen->BlockHandler = NVBlockHandler; + miInitializeBackingStore(pScreen); + xf86SetBackingStore(pScreen); + xf86SetSilkenMouse(pScreen); -#ifdef RANDR - /* Install our DriverFunc. We have to do it this way instead of using the - * HaveDriverFuncs argument to xf86AddDriver, because InitOutput clobbers - * pScrn->DriverFunc */ - pScrn->DriverFunc = NVDriverFunc; + /* Finish DRI init */ + NVDRIFinishScreenInit(pScrn); + + /* Initialize software cursor. + Must precede creation of the default colormap */ + miDCInitialize(pScreen, xf86GetPointerScreenFuncs()); + + /* Initialize HW cursor layer. + Must follow software cursor initialization */ + if (pNv->HWCursor) { + if (pNv->Architecture < NV_ARCH_50) + ret = NVCursorInit(pScreen); + else + ret = NV50CursorInit(pScreen); + if (ret != TRUE) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "Hardware cursor initialization failed\n"); + pNv->HWCursor = FALSE; + } + } + + /* Initialise default colourmap */ + if (!miCreateDefColormap(pScreen)) + return FALSE; + + /* Initialize colormap layer. + Must follow initialization of the default colormap */ + if (pNv->Architecture < NV_ARCH_50) { + if (!xf86HandleColormaps(pScreen, 256, 8, NVLoadPalette, + NULL, + CMAP_RELOAD_ON_MODE_SWITCH | + CMAP_PALETTED_TRUECOLOR)) + return FALSE; + } else { + if (!xf86HandleColormaps(pScreen, 256, 8, NV50LoadPalette, + NULL, CMAP_PALETTED_TRUECOLOR)) + return FALSE; + } + + + xf86DPMSInit(pScreen, xf86DPMSSet, 0); + + if (!xf86CrtcScreenInit(pScreen)) + return FALSE; + + pNv->PointerMoved = pScrn->PointerMoved; + pScrn->PointerMoved = NVPointerMoved; + + if (pNv->ShadowFB) { + RefreshAreaFuncPtr refreshArea = NVRefreshArea; + + if (pNv->Rotate || pNv->RandRRotation) { + pNv->PointerMoved = pScrn->PointerMoved; + if (pNv->Rotate) + pScrn->PointerMoved = NVPointerMoved; + + switch (pScrn->bitsPerPixel) { + case 8: + refreshArea = NVRefreshArea8; + break; + case 16: + refreshArea = NVRefreshArea16; + break; + case 32: + refreshArea = NVRefreshArea32; + break; + } + if (!pNv->RandRRotation) { + xf86DisableRandR(); + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "Driver rotation enabled, RandR disabled\n"); + } + } + + ShadowFBInit(pScreen, refreshArea); + } + + pScrn->memPhysBase = pNv->VRAMPhysical; + pScrn->fbOffset = 0; + + if (pNv->Rotate == 0 && !pNv->RandRRotation) + NVInitVideo(pScreen); + + if (pNv->Architecture == NV_ARCH_50 && !NV50AcquireDisplay(pScrn)) + return FALSE; + + pScreen->SaveScreen = NVSaveScreen; + + /* Wrap the current CloseScreen function */ + pNv->CloseScreen = pScreen->CloseScreen; + pScreen->CloseScreen = NVCloseScreen; + + pNv->BlockHandler = pScreen->BlockHandler; + pScreen->BlockHandler = NVBlockHandler; + +#if 0 //def RANDR + /* Install our DriverFunc. We have to do it this way instead of using the + * HaveDriverFuncs argument to xf86AddDriver, because InitOutput clobbers + * pScrn->DriverFunc */ + pScrn->DriverFunc = NVDriverFunc; #endif - /* Report any unused options (only for the first generation) */ - if (serverGeneration == 1) { - xf86ShowUnusedOptions(pScrn->scrnIndex, pScrn->options); - } - return TRUE; + /* Report any unused options (only for the first generation) */ + if (serverGeneration == 1) { + xf86ShowUnusedOptions(pScrn->scrnIndex, pScrn->options); + } + return TRUE; } static Bool NVSaveScreen(ScreenPtr pScreen, int mode) { - return vgaHWSaveScreen(pScreen, mode); + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn); + NVPtr pNv = NVPTR(pScrn); + int i; + Bool on = xf86IsUnblank(mode); + + if (pScrn->vtSema) { + for (i = 0; i < xf86_config->num_crtc; i++) { + + if (xf86_config->crtc[i]->enabled) { + NVCrtcBlankScreen(xf86_config->crtc[i], + on); + } + } + + } + return TRUE; + } static void NVSave(ScrnInfoPtr pScrn) { - NVPtr pNv = NVPTR(pScrn); - NVRegPtr nvReg = &pNv->SavedReg; - vgaHWPtr pVga = VGAHWPTR(pScrn); - vgaRegPtr vgaReg = &pVga->SavedReg; - - NVLockUnlock(pNv, 0); - if(pNv->twoHeads) { - nvWriteVGA(pNv, NV_VGA_CRTCX_OWNER, pNv->CRTCnumber * 0x3); - NVLockUnlock(pNv, 0); - } - - NVDACSave(pScrn, vgaReg, nvReg, pNv->Primary); + NVPtr pNv = NVPTR(pScrn); + NVRegPtr nvReg = &pNv->SavedReg; + vgaHWPtr pVga = VGAHWPTR(pScrn); + vgaRegPtr vgaReg = &pVga->SavedReg; + xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn); + int i; + int vgaflags = VGA_SR_CMAP | VGA_SR_MODE; + + for (i = 0; i < xf86_config->num_crtc; i++) { + xf86_config->crtc[i]->funcs->save(xf86_config->crtc[i]); + } + + + for (i = 0; i < xf86_config->num_output; i++) { + xf86_config->output[i]->funcs->save(xf86_config-> + output[i]); + } + + vgaHWUnlock(pVga); +#ifndef __powerpc__ + vgaflags |= VGA_SR_FONTS; +#endif + vgaHWSave(pScrn, vgaReg, vgaflags); } #ifdef RANDR static Bool -NVRandRGetInfo(ScrnInfoPtr pScrn, Rotation *rotations) +NVRandRGetInfo(ScrnInfoPtr pScrn, Rotation * rotations) { - NVPtr pNv = NVPTR(pScrn); + NVPtr pNv = NVPTR(pScrn); - if(pNv->RandRRotation) - *rotations = RR_Rotate_0 | RR_Rotate_90 | RR_Rotate_270; - else - *rotations = RR_Rotate_0; + if (pNv->RandRRotation) + *rotations = RR_Rotate_0 | RR_Rotate_90 | RR_Rotate_270; + else + *rotations = RR_Rotate_0; - return TRUE; + return TRUE; } static Bool -NVRandRSetConfig(ScrnInfoPtr pScrn, xorgRRConfig *config) +NVRandRSetConfig(ScrnInfoPtr pScrn, xorgRRConfig * config) { - NVPtr pNv = NVPTR(pScrn); - - switch(config->rotation) { - case RR_Rotate_0: - pNv->Rotate = 0; - pScrn->PointerMoved = pNv->PointerMoved; - break; - - case RR_Rotate_90: - pNv->Rotate = -1; - pScrn->PointerMoved = NVPointerMoved; - break; - - case RR_Rotate_270: - pNv->Rotate = 1; - pScrn->PointerMoved = NVPointerMoved; - break; - - default: - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, - "Unexpected rotation in NVRandRSetConfig!\n"); - pNv->Rotate = 0; - pScrn->PointerMoved = pNv->PointerMoved; - return FALSE; - } - - return TRUE; + NVPtr pNv = NVPTR(pScrn); + + switch (config->rotation) { + case RR_Rotate_0: + pNv->Rotate = 0; + pScrn->PointerMoved = pNv->PointerMoved; + break; + + case RR_Rotate_90: + pNv->Rotate = -1; + pScrn->PointerMoved = NVPointerMoved; + break; + + case RR_Rotate_270: + pNv->Rotate = 1; + pScrn->PointerMoved = NVPointerMoved; + break; + + default: + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "Unexpected rotation in NVRandRSetConfig!\n"); + pNv->Rotate = 0; + pScrn->PointerMoved = pNv->PointerMoved; + return FALSE; + } + + return TRUE; } static Bool NVDriverFunc(ScrnInfoPtr pScrn, xorgDriverFuncOp op, pointer data) { - switch(op) { - case RR_GET_INFO: - return NVRandRGetInfo(pScrn, (Rotation*)data); - case RR_SET_CONFIG: - return NVRandRSetConfig(pScrn, (xorgRRConfig*)data); - default: - return FALSE; - } - - return FALSE; + switch (op) { + case RR_GET_INFO: + return NVRandRGetInfo(pScrn, (Rotation *) data); + case RR_SET_CONFIG: + return NVRandRSetConfig(pScrn, (xorgRRConfig *) data); + default: + return FALSE; + } + + return FALSE; } #endif + diff --git a/src/nv_exa.c b/src/nv_exa.c index d501c44..adf159f 100644 --- a/src/nv_exa.c +++ b/src/nv_exa.c @@ -302,6 +302,17 @@ NVAccelDownloadM2MF(ScrnInfoPtr pScrn, char *dst, uint64_t src_offset, if (lc > 2047) lc = 2047; + if (pNv->Architecture >= NV_ARCH_50) { + NVDmaStart(pNv, NvMemFormat, 0x200, 1); + NVDmaNext (pNv, 1); + NVDmaStart(pNv, NvMemFormat, 0x21c, 1); + NVDmaNext (pNv, 1); + /* probably high-order bits of address */ + NVDmaStart(pNv, NvMemFormat, 0x238, 2); + NVDmaNext (pNv, 0); + NVDmaNext (pNv, 0); + } + NVDmaStart(pNv, NvMemFormat, NV_MEMORY_TO_MEMORY_FORMAT_OFFSET_IN, 8); NVDmaNext (pNv, (uint32_t)src_offset); @@ -408,6 +419,17 @@ NVAccelUploadM2MF(ScrnInfoPtr pScrn, uint64_t dst_offset, const char *src, } } + if (pNv->Architecture >= NV_ARCH_50) { + NVDmaStart(pNv, NvMemFormat, 0x200, 1); + NVDmaNext (pNv, 1); + NVDmaStart(pNv, NvMemFormat, 0x21c, 1); + NVDmaNext (pNv, 1); + /* probably high-order bits of address */ + NVDmaStart(pNv, NvMemFormat, 0x238, 2); + NVDmaNext (pNv, 0); + NVDmaNext (pNv, 0); + } + /* DMA to VRAM */ NVDmaStart(pNv, NvMemFormat, NV_MEMORY_TO_MEMORY_FORMAT_OFFSET_IN, 8); @@ -619,13 +641,23 @@ Bool NVExaInit(ScreenPtr pScreen) pNv->EXADriverPtr->DownloadFromScreen = NVDownloadFromScreen; pNv->EXADriverPtr->UploadToScreen = NVUploadToScreen; - pNv->EXADriverPtr->PrepareCopy = NVExaPrepareCopy; - pNv->EXADriverPtr->Copy = NVExaCopy; - pNv->EXADriverPtr->DoneCopy = NVExaDoneCopy; + if (pNv->Architecture < NV_ARCH_50) { + pNv->EXADriverPtr->PrepareCopy = NVExaPrepareCopy; + pNv->EXADriverPtr->Copy = NVExaCopy; + pNv->EXADriverPtr->DoneCopy = NVExaDoneCopy; - pNv->EXADriverPtr->PrepareSolid = NVExaPrepareSolid; - pNv->EXADriverPtr->Solid = NVExaSolid; - pNv->EXADriverPtr->DoneSolid = NVExaDoneSolid; + pNv->EXADriverPtr->PrepareSolid = NVExaPrepareSolid; + pNv->EXADriverPtr->Solid = NVExaSolid; + pNv->EXADriverPtr->DoneSolid = NVExaDoneSolid; + } else { + pNv->EXADriverPtr->PrepareCopy = NV50EXAPrepareCopy; + pNv->EXADriverPtr->Copy = NV50EXACopy; + pNv->EXADriverPtr->DoneCopy = NV50EXADoneCopy; + + pNv->EXADriverPtr->PrepareSolid = NV50EXAPrepareSolid; + pNv->EXADriverPtr->Solid = NV50EXASolid; + pNv->EXADriverPtr->DoneSolid = NV50EXADoneSolid; + } switch (pNv->Architecture) { #if X_BYTE_ORDER == X_LITTLE_ENDIAN @@ -636,6 +668,8 @@ Bool NVExaInit(ScreenPtr pScreen) pNv->EXADriverPtr->DoneComposite = NV30EXADoneComposite; break; #endif + case NV_ARCH_50: + break; default: if (!pNv->BlendingPossible) break; diff --git a/src/nv_hw.c b/src/nv_hw.c index 0dc78a1..c2a5061 100644 --- a/src/nv_hw.c +++ b/src/nv_hw.c @@ -65,7 +65,7 @@ CARD32 nvReadRAMDAC(NVPtr pNv, uint8_t head, uint32_t ramdac_reg) void nvWriteRAMDAC(NVPtr pNv, uint8_t head, uint32_t ramdac_reg, CARD32 val) { volatile const void *ptr = head ? pNv->PRAMDAC1 : pNv->PRAMDAC0; - MMIO_OUT32(ptr, ramdac_reg, val); + NV_WR32(ptr, ramdac_reg, val); } CARD32 nvReadCRTC(NVPtr pNv, uint8_t head, uint32_t reg) @@ -77,42 +77,7 @@ CARD32 nvReadCRTC(NVPtr pNv, uint8_t head, uint32_t reg) void nvWriteCRTC(NVPtr pNv, uint8_t head, uint32_t reg, CARD32 val) { volatile const void *ptr = head ? pNv->PCRTC1 : pNv->PCRTC0; - MMIO_OUT32(ptr, reg, val); -} - -void NVLockUnlock ( - NVPtr pNv, - Bool Lock -) -{ - CARD8 cr11; - - nvWriteVGA(pNv, NV_VGA_CRTCX_LOCK, Lock ? 0x99 : 0x57 ); - - cr11 = nvReadVGA(pNv, NV_VGA_CRTCX_VSYNCE); - if(Lock) cr11 |= 0x80; - else cr11 &= ~0x80; - nvWriteVGA(pNv, NV_VGA_CRTCX_VSYNCE, cr11); -} - -int NVShowHideCursor ( - NVPtr pNv, - int ShowHide -) -{ - int current = pNv->CurrentState->cursor1; - - pNv->CurrentState->cursor1 = (pNv->CurrentState->cursor1 & 0xFE) | - (ShowHide & 0x01); - - nvWriteVGA(pNv, NV_VGA_CRTCX_CURCTL1, pNv->CurrentState->cursor1); - - if(pNv->Architecture == NV_ARCH_40) { /* HW bug */ - volatile CARD32 curpos = nvReadCurRAMDAC(pNv, NV_RAMDAC_CURSOR_POS); - nvWriteCurRAMDAC(pNv, NV_RAMDAC_CURSOR_POS, curpos); - } - - return (current & 0x01); + NV_WR32(ptr, reg, val); } /****************************************************************************\ @@ -277,7 +242,7 @@ static void nvGetClocks(NVPtr pNv, unsigned int *MClk, unsigned int *NVClk) } -static void nv4CalcArbitration ( +void nv4CalcArbitration ( nv4_fifo_info *fifo, nv4_sim_state *arb ) @@ -416,7 +381,7 @@ static void nv4CalcArbitration ( } } -static void nv4UpdateArbitrationSettings ( +void nv4UpdateArbitrationSettings ( unsigned VClk, unsigned pixelDepth, unsigned *burst, @@ -452,7 +417,7 @@ static void nv4UpdateArbitrationSettings ( } } -static void nv10CalcArbitration ( +void nv10CalcArbitration ( nv10_fifo_info *fifo, nv10_sim_state *arb ) @@ -643,7 +608,7 @@ static void nv10CalcArbitration ( } } -static void nv10UpdateArbitrationSettings ( +void nv10UpdateArbitrationSettings ( unsigned VClk, unsigned pixelDepth, unsigned *burst, @@ -680,11 +645,9 @@ static void nv10UpdateArbitrationSettings ( } -static void nv30UpdateArbitrationSettings ( - NVPtr pNv, - unsigned *burst, - unsigned *lwm -) +void nv30UpdateArbitrationSettings (NVPtr pNv, + unsigned *burst, + unsigned *lwm) { unsigned int MClk, NVClk; unsigned int fifo_size, burst_size, graphics_lwm; @@ -701,12 +664,11 @@ static void nv30UpdateArbitrationSettings ( *lwm = graphics_lwm >> 3; } -static void nForceUpdateArbitrationSettings ( - unsigned VClk, - unsigned pixelDepth, - unsigned *burst, - unsigned *lwm, - NVPtr pNv +void nForceUpdateArbitrationSettings (unsigned VClk, + unsigned pixelDepth, + unsigned *burst, + unsigned *lwm, + NVPtr pNv ) { nv10_fifo_info fifo_data; @@ -764,376 +726,3 @@ static void nForceUpdateArbitrationSettings ( } } - -/****************************************************************************\ -* * -* RIVA Mode State Routines * -* * -\****************************************************************************/ - -/* - * Calculate the Video Clock parameters for the PLL. - */ -static void CalcVClock ( - int clockIn, - int *clockOut, - CARD32 *pllOut, - NVPtr pNv -) -{ - unsigned lowM, highM; - unsigned DeltaNew, DeltaOld; - unsigned VClk, Freq; - unsigned M, N, P; - - DeltaOld = 0xFFFFFFFF; - - VClk = (unsigned)clockIn; - - if (pNv->CrystalFreqKHz == 13500) { - lowM = 7; - highM = 13; - } else { - lowM = 8; - highM = 14; - } - - for (P = 0; P <= 4; P++) { - Freq = VClk << P; - if ((Freq >= 128000) && (Freq <= 350000)) { - for (M = lowM; M <= highM; M++) { - N = ((VClk << P) * M) / pNv->CrystalFreqKHz; - if(N <= 255) { - Freq = ((pNv->CrystalFreqKHz * N) / M) >> P; - if (Freq > VClk) - DeltaNew = Freq - VClk; - else - DeltaNew = VClk - Freq; - if (DeltaNew < DeltaOld) { - *pllOut = (P << 16) | (N << 8) | M; - *clockOut = Freq; - DeltaOld = DeltaNew; - } - } - } - } - } -} - -static void CalcVClock2Stage ( - int clockIn, - int *clockOut, - CARD32 *pllOut, - CARD32 *pllBOut, - NVPtr pNv -) -{ - unsigned DeltaNew, DeltaOld; - unsigned VClk, Freq; - unsigned M, N, P; - - DeltaOld = 0xFFFFFFFF; - - *pllBOut = 0x80000401; /* fixed at x4 for now */ - - VClk = (unsigned)clockIn; - - for (P = 0; P <= 6; P++) { - Freq = VClk << P; - if ((Freq >= 400000) && (Freq <= 1000000)) { - for (M = 1; M <= 13; M++) { - N = ((VClk << P) * M) / (pNv->CrystalFreqKHz << 2); - if((N >= 5) && (N <= 255)) { - Freq = (((pNv->CrystalFreqKHz << 2) * N) / M) >> P; - if (Freq > VClk) - DeltaNew = Freq - VClk; - else - DeltaNew = VClk - Freq; - if (DeltaNew < DeltaOld) { - *pllOut = (P << 16) | (N << 8) | M; - *clockOut = Freq; - DeltaOld = DeltaNew; - } - } - } - } - } -} - -/* - * Calculate extended mode parameters (SVGA) and save in a - * mode state structure. - */ -void NVCalcStateExt ( - NVPtr pNv, - RIVA_HW_STATE *state, - int bpp, - int width, - int hDisplaySize, - int height, - int dotClock, - int flags -) -{ - int pixelDepth, VClk; - CARD32 CursorStart; - - /* - * Save mode parameters. - */ - state->bpp = bpp; /* this is not bitsPerPixel, it's 8,15,16,32 */ - state->width = width; - state->height = height; - /* - * Extended RIVA registers. - */ - pixelDepth = (bpp + 1)/8; - if(pNv->twoStagePLL) - CalcVClock2Stage(dotClock, &VClk, &state->pll, &state->pllB, pNv); - else - CalcVClock(dotClock, &VClk, &state->pll, pNv); - - switch (pNv->Architecture) - { - case NV_ARCH_04: - nv4UpdateArbitrationSettings(VClk, - pixelDepth * 8, - &(state->arbitration0), - &(state->arbitration1), - pNv); - state->cursor0 = 0x00; - state->cursor1 = 0xbC; - if (flags & V_DBLSCAN) - state->cursor1 |= 2; - state->cursor2 = 0x00000000; - state->pllsel = 0x10000700; - state->config = 0x00001114; - state->general = bpp == 16 ? 0x00101100 : 0x00100100; - state->repaint1 = hDisplaySize < 1280 ? 0x04 : 0x00; - break; - case NV_ARCH_10: - case NV_ARCH_20: - case NV_ARCH_30: - default: - if(((pNv->Chipset & 0xfff0) == CHIPSET_C51) || - ((pNv->Chipset & 0xfff0) == CHIPSET_C512)) - { - state->arbitration0 = 128; - state->arbitration1 = 0x0480; - } else - if(((pNv->Chipset & 0xffff) == CHIPSET_NFORCE) || - ((pNv->Chipset & 0xffff) == CHIPSET_NFORCE2)) - { - nForceUpdateArbitrationSettings(VClk, - pixelDepth * 8, - &(state->arbitration0), - &(state->arbitration1), - pNv); - } else if(pNv->Architecture < NV_ARCH_30) { - nv10UpdateArbitrationSettings(VClk, - pixelDepth * 8, - &(state->arbitration0), - &(state->arbitration1), - pNv); - } else { - nv30UpdateArbitrationSettings(pNv, - &(state->arbitration0), - &(state->arbitration1)); - } - CursorStart = pNv->Cursor->offset; - state->cursor0 = 0x80 | (CursorStart >> 17); - state->cursor1 = (CursorStart >> 11) << 2; - state->cursor2 = CursorStart >> 24; - if (flags & V_DBLSCAN) - state->cursor1 |= 2; - state->pllsel = 0x10000700; - state->config = nvReadFB(pNv, NV_PFB_CFG0); - state->general = bpp == 16 ? 0x00101100 : 0x00100100; - state->repaint1 = hDisplaySize < 1280 ? 0x04 : 0x00; - break; - } - - if(bpp != 8) /* DirectColor */ - state->general |= 0x00000030; - - state->repaint0 = (((width / 8) * pixelDepth) & 0x700) >> 3; - state->pixel = (pixelDepth > 2) ? 3 : pixelDepth; -} - - -void NVLoadStateExt ( - ScrnInfoPtr pScrn, - RIVA_HW_STATE *state -) -{ - NVPtr pNv = NVPTR(pScrn); - int i, j; - CARD32 temp; - - if(pNv->Architecture >= NV_ARCH_40) { - switch(pNv->Chipset & 0xfff0) { - case CHIPSET_NV44: - case CHIPSET_NV44A: - case CHIPSET_C51: - case CHIPSET_G70: - case CHIPSET_G71: - case CHIPSET_G72: - case CHIPSET_G73: - case CHIPSET_C512: - temp = nvReadCurRAMDAC(pNv, NV_RAMDAC_TEST_CONTROL); - nvWriteCurRAMDAC(pNv, NV_RAMDAC_TEST_CONTROL, temp | 0x00100000); - break; - default: - break; - }; - } - - if(pNv->Architecture >= NV_ARCH_10) { - if(pNv->twoHeads) { - nvWriteCRTC(pNv, 0, NV_CRTC_HEAD_CONFIG, state->head); - nvWriteCRTC(pNv, 1, NV_CRTC_HEAD_CONFIG, state->head2); - } - temp = nvReadCurRAMDAC(pNv, NV_RAMDAC_0404); - nvWriteCurRAMDAC(pNv, NV_RAMDAC_0404, temp | (1 << 25)); - - nvWriteVIDEO(pNv, NV_PVIDEO_STOP, 1); - nvWriteVIDEO(pNv, NV_PVIDEO_INTR_EN, 0); - nvWriteVIDEO(pNv, NV_PVIDEO_OFFSET_BUFF(0), 0); - nvWriteVIDEO(pNv, NV_PVIDEO_OFFSET_BUFF(1), 0); - nvWriteVIDEO(pNv, NV_PVIDEO_LIMIT(0), pNv->VRAMPhysicalSize - 1); - nvWriteVIDEO(pNv, NV_PVIDEO_LIMIT(1), pNv->VRAMPhysicalSize - 1); - nvWriteMC(pNv, 0x1588, 0); - - nvWriteCurCRTC(pNv, NV_CRTC_CURSOR_CONFIG, state->cursorConfig); - nvWriteCurCRTC(pNv, NV_CRTC_0830, state->displayV - 3); - nvWriteCurCRTC(pNv, NV_CRTC_0834, state->displayV - 1); - - if(pNv->FlatPanel) { - if((pNv->Chipset & 0x0ff0) == CHIPSET_NV11) { - nvWriteCurRAMDAC(pNv, NV_RAMDAC_DITHER_NV11, state->dither); - } else - if(pNv->twoHeads) { - nvWriteCurRAMDAC(pNv, NV_RAMDAC_FP_DITHER, state->dither); - } - - nvWriteVGA(pNv, NV_VGA_CRTCX_FP_HTIMING, state->timingH); - nvWriteVGA(pNv, NV_VGA_CRTCX_FP_VTIMING, state->timingV); - nvWriteVGA(pNv, NV_VGA_CRTCX_BUFFER, 0xfa); - } - - nvWriteVGA(pNv, NV_VGA_CRTCX_EXTRA, state->extra); - } - - nvWriteVGA(pNv, NV_VGA_CRTCX_REPAINT0, state->repaint0); - nvWriteVGA(pNv, NV_VGA_CRTCX_REPAINT1, state->repaint1); - nvWriteVGA(pNv, NV_VGA_CRTCX_LSR, state->screen); - nvWriteVGA(pNv, NV_VGA_CRTCX_PIXEL, state->pixel); - nvWriteVGA(pNv, NV_VGA_CRTCX_HEB, state->horiz); - nvWriteVGA(pNv, NV_VGA_CRTCX_FIFO1, state->fifo); - nvWriteVGA(pNv, NV_VGA_CRTCX_FIFO0, state->arbitration0); - nvWriteVGA(pNv, NV_VGA_CRTCX_FIFO_LWM, state->arbitration1); - if(pNv->Architecture >= NV_ARCH_30) { - nvWriteVGA(pNv, NV_VGA_CRTCX_FIFO_LWM_NV30, state->arbitration1 >> 8); - } - - nvWriteVGA(pNv, NV_VGA_CRTCX_CURCTL0, state->cursor0); - nvWriteVGA(pNv, NV_VGA_CRTCX_CURCTL1, state->cursor1); - if(pNv->Architecture == NV_ARCH_40) { /* HW bug */ - volatile CARD32 curpos = nvReadCurRAMDAC(pNv, NV_RAMDAC_CURSOR_POS); - nvWriteCurRAMDAC(pNv, NV_RAMDAC_CURSOR_POS, curpos); - } - nvWriteVGA(pNv, NV_VGA_CRTCX_CURCTL2, state->cursor2); - nvWriteVGA(pNv, NV_VGA_CRTCX_INTERLACE, state->interlace); - - if(!pNv->FlatPanel) { - nvWriteRAMDAC0(pNv, NV_RAMDAC_PLL_SELECT, state->pllsel); - nvWriteRAMDAC0(pNv, NV_RAMDAC_VPLL, state->vpll); - if(pNv->twoHeads) - nvWriteRAMDAC0(pNv, NV_RAMDAC_VPLL2, state->vpll2); - if(pNv->twoStagePLL) { - nvWriteRAMDAC0(pNv, NV_RAMDAC_VPLL_B, state->vpllB); - nvWriteRAMDAC0(pNv, NV_RAMDAC_VPLL2_B, state->vpll2B); - } - } else { - nvWriteCurRAMDAC(pNv, NV_RAMDAC_FP_CONTROL, state->scale); - nvWriteCurRAMDAC(pNv, NV_RAMDAC_FP_HCRTC, state->crtcSync); - } - nvWriteCurRAMDAC(pNv, NV_RAMDAC_GENERAL_CONTROL, state->general); - - nvWriteCurCRTC(pNv, NV_CRTC_INTR_EN_0, 0); - nvWriteCurCRTC(pNv, NV_CRTC_INTR_0, NV_CRTC_INTR_VBLANK); - - pNv->CurrentState = state; -} - -void NVUnloadStateExt -( - NVPtr pNv, - RIVA_HW_STATE *state -) -{ - state->repaint0 = nvReadVGA(pNv, NV_VGA_CRTCX_REPAINT0); - state->repaint1 = nvReadVGA(pNv, NV_VGA_CRTCX_REPAINT1); - state->screen = nvReadVGA(pNv, NV_VGA_CRTCX_LSR); - state->pixel = nvReadVGA(pNv, NV_VGA_CRTCX_PIXEL); - state->horiz = nvReadVGA(pNv, NV_VGA_CRTCX_HEB); - state->fifo = nvReadVGA(pNv, NV_VGA_CRTCX_FIFO1); - state->arbitration0 = nvReadVGA(pNv, NV_VGA_CRTCX_FIFO0); - state->arbitration1 = nvReadVGA(pNv, NV_VGA_CRTCX_FIFO_LWM); - if(pNv->Architecture >= NV_ARCH_30) { - state->arbitration1 |= (nvReadVGA(pNv, NV_VGA_CRTCX_FIFO_LWM_NV30) & 1) << 8; - } - state->cursor0 = nvReadVGA(pNv, NV_VGA_CRTCX_CURCTL0); - state->cursor1 = nvReadVGA(pNv, NV_VGA_CRTCX_CURCTL1); - state->cursor2 = nvReadVGA(pNv, NV_VGA_CRTCX_CURCTL2); - state->interlace = nvReadVGA(pNv, NV_VGA_CRTCX_INTERLACE); - - state->vpll = nvReadRAMDAC0(pNv, NV_RAMDAC_VPLL); - if(pNv->twoHeads) - state->vpll2 = nvReadRAMDAC0(pNv, NV_RAMDAC_VPLL2); - if(pNv->twoStagePLL) { - state->vpllB = nvReadRAMDAC0(pNv, NV_RAMDAC_VPLL_B); - state->vpll2B = nvReadRAMDAC0(pNv, NV_RAMDAC_VPLL2_B); - } - state->pllsel = nvReadRAMDAC0(pNv, NV_RAMDAC_PLL_SELECT); - state->general = nvReadCurRAMDAC(pNv, NV_RAMDAC_GENERAL_CONTROL); - state->scale = nvReadCurRAMDAC(pNv, NV_RAMDAC_FP_CONTROL); - state->config = nvReadFB(pNv, NV_PFB_CFG0); - - if(pNv->Architecture >= NV_ARCH_10) { - if(pNv->twoHeads) { - state->head = nvReadCRTC(pNv, 0, NV_CRTC_HEAD_CONFIG); - state->head2 = nvReadCRTC(pNv, 1, NV_CRTC_HEAD_CONFIG); - state->crtcOwner = nvReadVGA(pNv, NV_VGA_CRTCX_OWNER); - } - state->extra = nvReadVGA(pNv, NV_VGA_CRTCX_EXTRA); - - state->cursorConfig = nvReadCurCRTC(pNv, NV_CRTC_CURSOR_CONFIG); - - if((pNv->Chipset & 0x0ff0) == CHIPSET_NV11) { - state->dither = nvReadCurRAMDAC(pNv, NV_RAMDAC_DITHER_NV11); - } else - if(pNv->twoHeads) { - state->dither = nvReadCurRAMDAC(pNv, NV_RAMDAC_FP_DITHER); - } - - if(pNv->FlatPanel) { - state->timingH = nvReadVGA(pNv, NV_VGA_CRTCX_FP_HTIMING); - state->timingV = nvReadVGA(pNv, NV_VGA_CRTCX_FP_VTIMING); - } - } - - if(pNv->FlatPanel) { - state->crtcSync = nvReadCurRAMDAC(pNv, NV_RAMDAC_FP_HCRTC); - } -} - -void NVSetStartAddress ( - NVPtr pNv, - CARD32 start -) -{ - nvWriteCurCRTC(pNv, NV_CRTC_START, start); -} - - diff --git a/src/nv_i2c.c b/src/nv_i2c.c new file mode 100644 index 0000000..93bef4f --- /dev/null +++ b/src/nv_i2c.c @@ -0,0 +1,70 @@ + +#include "nv_include.h" + +/* + * DDC1 support only requires DDC_SDA_MASK, + * DDC2 support requires DDC_SDA_MASK and DDC_SCL_MASK + */ +#define DDC_SDA_READ_MASK (1 << 3) +#define DDC_SCL_READ_MASK (1 << 2) +#define DDC_SDA_WRITE_MASK (1 << 4) +#define DDC_SCL_WRITE_MASK (1 << 5) + +static void +NVI2CGetBits(I2CBusPtr b, int *clock, int *data) +{ + NVPtr pNv = NVPTR(xf86Screens[b->scrnIndex]); + unsigned char val; + + /* Get the result. */ + val = nvReadVGA(pNv, b->DriverPrivate.uval); + + *clock = (val & DDC_SCL_READ_MASK) != 0; + *data = (val & DDC_SDA_READ_MASK) != 0; +} + +static void +NVI2CPutBits(I2CBusPtr b, int clock, int data) +{ + NVPtr pNv = NVPTR(xf86Screens[b->scrnIndex]); + unsigned char val; + + val = nvReadVGA(pNv, b->DriverPrivate.uval + 1) & 0xf0; + if (clock) + val |= DDC_SCL_WRITE_MASK; + else + val &= ~DDC_SCL_WRITE_MASK; + + if (data) + val |= DDC_SDA_WRITE_MASK; + else + val &= ~DDC_SDA_WRITE_MASK; + + nvWriteVGA(pNv, b->DriverPrivate.uval + 1, val | 0x1); +} + +Bool +NV_I2CInit(ScrnInfoPtr pScrn, I2CBusPtr *bus_ptr, int i2c_reg, char *name) +{ + I2CBusPtr pI2CBus; + + pI2CBus = xf86CreateI2CBusRec(); + if(!pI2CBus) + return FALSE; + + pI2CBus->BusName = name; + pI2CBus->scrnIndex = pScrn->scrnIndex; + pI2CBus->I2CPutBits = NVI2CPutBits; + pI2CBus->I2CGetBits = NVI2CGetBits; + pI2CBus->AcknTimeout = 5; + + pI2CBus->DriverPrivate.uval = i2c_reg; + + if (!xf86I2CBusInit(pI2CBus)) { + return FALSE; + } + + *bus_ptr = pI2CBus; + return TRUE; +} + diff --git a/src/nv_include.h b/src/nv_include.h index 2d9ec3c..eaa5090 100644 --- a/src/nv_include.h +++ b/src/nv_include.h @@ -74,4 +74,6 @@ #include "nouveau_reg.h" #include "nvreg.h" +#include "xf86Crtc.h" + #endif /* __NV_INCLUDE_H__ */ diff --git a/src/nv_local.h b/src/nv_local.h index 5a74ee2..f539a2c 100644 --- a/src/nv_local.h +++ b/src/nv_local.h @@ -49,14 +49,37 @@ #include "compiler.h" #include "xf86_OSproc.h" +//#define DAVE_DEBUG +#ifdef DAVE_DEBUG + +extern CARD32 debug_offset; +static inline void nv_wr08(void *p, int i, CARD8 d, char *fname) +{ + static int last_vga = 0; + + if (i == 0x3d4) + last_vga = d; + + if (strcmp(fname, "nvReadVGA") && last_vga != 0x3f && last_vga != 0x37) + ErrorF("wr08: %08X %08X, %02X\t%s\n", p-debug_offset, i, d, fname); + MMIO_OUT8((pointer)(p), (i), (d)); +} + + +#define NV_WR08(p,i,d) nv_wr08(p, i, d, __FUNCTION__) +#define NV_WR32(p,i,d) do { ErrorF("wr32: %08X, %08X\t%s\n", p -debug_offset + i, d, __FUNCTION__); MMIO_OUT32((pointer)(p), (i), (d)); } while(0) +#else +#define NV_WR08(p,i,d) MMIO_OUT8((pointer)(p), (i), (d)) +#define NV_WR32(p,i,d) MMIO_OUT32((pointer)(p), (i), (d)) +#endif + + /* * HW access macros. These assume memory-mapped I/O, and not normal I/O space. */ -#define NV_WR08(p,i,d) MMIO_OUT8((pointer)(p), (i), (d)) #define NV_RD08(p,i) MMIO_IN8((pointer)(p), (i)) #define NV_WR16(p,i,d) MMIO_OUT16((pointer)(p), (i), (d)) #define NV_RD16(p,i) MMIO_IN16((pointer)(p), (i)) -#define NV_WR32(p,i,d) MMIO_OUT32((pointer)(p), (i), (d)) #define NV_RD32(p,i) MMIO_IN32((pointer)(p), (i)) /* VGA I/O is now always done through MMIO */ diff --git a/src/nv_output.c b/src/nv_output.c new file mode 100644 index 0000000..9f72fd3 --- /dev/null +++ b/src/nv_output.c @@ -0,0 +1,885 @@ +/* + * Copyright 2006 Dave Airlie + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + * Authors: + * Dave Airlie + */ +/* + * this code uses ideas taken from the NVIDIA nv driver - the nvidia license + * decleration is at the bottom of this file as it is rather ugly + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "xf86.h" +#include "os.h" +#include "mibank.h" +#include "globals.h" +#include "xf86.h" +#include "xf86Priv.h" +#include "xf86DDC.h" +#include "mipointer.h" +#include "windowstr.h" +#include <randrstr.h> +#include <X11/extensions/render.h> + +#include "xf86Crtc.h" +#include "nv_include.h" + +const char *OutputType[] = { + "None", + "VGA", + "DVI", + "LVDS", + "S-video", + "Composite", +}; + +const char *MonTypeName[7] = { + "AUTO", + "NONE", + "CRT", + "LVDS", + "TMDS", + "CTV", + "STV" +}; + +void NVOutputWriteRAMDAC(xf86OutputPtr output, CARD32 ramdac_reg, CARD32 val) +{ + NVOutputPrivatePtr nv_output = output->driver_private; + ScrnInfoPtr pScrn = output->scrn; + NVPtr pNv = NVPTR(pScrn); + + nvWriteRAMDAC(pNv, nv_output->ramdac, ramdac_reg, val); +} + +CARD32 NVOutputReadRAMDAC(xf86OutputPtr output, CARD32 ramdac_reg) +{ + NVOutputPrivatePtr nv_output = output->driver_private; + ScrnInfoPtr pScrn = output->scrn; + NVPtr pNv = NVPTR(pScrn); + + return nvReadRAMDAC(pNv, nv_output->ramdac, ramdac_reg); +} + +static void nv_output_backlight_enable(xf86OutputPtr output, Bool on) +{ + ScrnInfoPtr pScrn = output->scrn; + NVPtr pNv = NVPTR(pScrn); + + /* This is done differently on each laptop. Here we + define the ones we know for sure. */ + +#if defined(__powerpc__) + if((pNv->Chipset == 0x10DE0179) || + (pNv->Chipset == 0x10DE0189) || + (pNv->Chipset == 0x10DE0329)) + { + /* NV17,18,34 Apple iMac, iBook, PowerBook */ + CARD32 tmp_pmc, tmp_pcrt; + tmp_pmc = nvReadMC(pNv, 0x10F0) & 0x7FFFFFFF; + tmp_pcrt = nvReadCRTC0(pNv, NV_CRTC_081C) & 0xFFFFFFFC; + if(on) { + tmp_pmc |= (1 << 31); + tmp_pcrt |= 0x1; + } + nvWriteMC(pNv, 0x10F0, tmp_pmc); + nvWriteCRTC0(pNv, NV_CRTC_081C, tmp_pcrt); + } +#endif + + if(pNv->twoHeads && ((pNv->Chipset & 0x0ff0) != CHIPSET_NV11)) + nvWriteMC(pNv, 0x130C, on ? 3 : 7); +} + +static void +nv_panel_output_dpms(xf86OutputPtr output, int mode) +{ + + switch(mode) { + case DPMSModeStandby: + case DPMSModeSuspend: + case DPMSModeOff: + nv_output_backlight_enable(output, 0); + break; + case DPMSModeOn: + nv_output_backlight_enable(output, 1); + default: + break; + } +} + +static void +nv_analog_output_dpms(xf86OutputPtr output, int mode) +{ + +} + +static void +nv_digital_output_dpms(xf86OutputPtr output, int mode) +{ + NVOutputPrivatePtr nv_output = output->driver_private; + xf86CrtcPtr crtc = output->crtc; + ScrnInfoPtr pScrn = output->scrn; + NVPtr pNv = NVPTR(pScrn); + NVCrtcPrivatePtr nv_crtc; + + CARD32 fpcontrol; + + if (crtc) { + nv_crtc = crtc->driver_private; + + fpcontrol = nvReadRAMDAC(pNv, nv_crtc->crtc, NV_RAMDAC_FP_CONTROL) & 0xCfffffCC; + switch(mode) { + case DPMSModeStandby: + case DPMSModeSuspend: + case DPMSModeOff: + /* cut the TMDS output */ + fpcontrol |= 0x20000022; + break; + case DPMSModeOn: + fpcontrol |= nv_output->fpSyncs; + } + + nvWriteRAMDAC(pNv, nv_crtc->crtc, NV_RAMDAC_FP_CONTROL, fpcontrol); + } +} + +void nv_output_save_state_ext(xf86OutputPtr output, RIVA_HW_STATE *state) +{ + NVOutputPrivatePtr nv_output = output->driver_private; + ScrnInfoPtr pScrn = output->scrn; + NVPtr pNv = NVPTR(pScrn); + NVOutputRegPtr regp; + + regp = &state->dac_reg[nv_output->ramdac]; + regp->general = NVOutputReadRAMDAC(output, NV_RAMDAC_GENERAL_CONTROL); + regp->fp_control = NVOutputReadRAMDAC(output, NV_RAMDAC_FP_CONTROL); + regp->debug_0 = NVOutputReadRAMDAC(output, NV_RAMDAC_FP_DEBUG_0); + state->config = nvReadFB(pNv, NV_PFB_CFG0); + + regp->output = NVOutputReadRAMDAC(output, NV_RAMDAC_OUTPUT); + + if((pNv->Chipset & 0x0ff0) == CHIPSET_NV11) { + regp->dither = NVOutputReadRAMDAC(output, NV_RAMDAC_DITHER_NV11); + } else if(pNv->twoHeads) { + regp->dither = NVOutputReadRAMDAC(output, NV_RAMDAC_FP_DITHER); + } + // regp->crtcSync = NVOutputReadRAMDAC(output, NV_RAMDAC_FP_HCRTC); + regp->nv10_cursync = NVOutputReadRAMDAC(output, NV_RAMDAC_NV10_CURSYNC); + + if (nv_output->type == OUTPUT_DIGITAL) { + int i; + + for (i = 0; i < 7; i++) { + uint32_t ramdac_reg = NV_RAMDAC_FP_HDISP_END + (i * 4); + + regp->fp_horiz_regs[i] = NVOutputReadRAMDAC(output, ramdac_reg); + } + + for (i = 0; i < 7; i++) { + uint32_t ramdac_reg = NV_RAMDAC_FP_VDISP_END + (i * 4); + + regp->fp_vert_regs[i] = NVOutputReadRAMDAC(output, ramdac_reg); + } + } + +} + +void nv_output_load_state_ext(xf86OutputPtr output, RIVA_HW_STATE *state) +{ + NVOutputPrivatePtr nv_output = output->driver_private; + ScrnInfoPtr pScrn = output->scrn; + NVPtr pNv = NVPTR(pScrn); + NVOutputRegPtr regp; + + regp = &state->dac_reg[nv_output->ramdac]; + + NVOutputWriteRAMDAC(output, NV_RAMDAC_FP_DEBUG_0, regp->debug_0); + NVOutputWriteRAMDAC(output, NV_RAMDAC_OUTPUT, regp->output); + NVOutputWriteRAMDAC(output, NV_RAMDAC_FP_CONTROL, regp->fp_control); + // NVOutputWriteRAMDAC(output, NV_RAMDAC_FP_HCRTC, regp->crtcSync); + + + if((pNv->Chipset & 0x0ff0) == CHIPSET_NV11) { + NVOutputWriteRAMDAC(output, NV_RAMDAC_DITHER_NV11, regp->dither); + } else if(pNv->twoHeads) { + NVOutputWriteRAMDAC(output, NV_RAMDAC_FP_DITHER, regp->dither); + } + + NVOutputWriteRAMDAC(output, NV_RAMDAC_GENERAL_CONTROL, regp->general); + NVOutputWriteRAMDAC(output, NV_RAMDAC_NV10_CURSYNC, regp->nv10_cursync); + + if (nv_output->type == OUTPUT_DIGITAL) { + int i; + + for (i = 0; i < 7; i++) { + uint32_t ramdac_reg = NV_RAMDAC_FP_HDISP_END + (i * 4); + NVOutputWriteRAMDAC(output, ramdac_reg, regp->fp_horiz_regs[i]); + } + + for (i = 0; i < 7; i++) { + uint32_t ramdac_reg = NV_RAMDAC_FP_VDISP_END + (i * 4); + + NVOutputWriteRAMDAC(output, ramdac_reg, regp->fp_vert_regs[i]); + } + } + +} + + +static void +nv_output_save (xf86OutputPtr output) +{ + ScrnInfoPtr pScrn = output->scrn; + NVPtr pNv = NVPTR(pScrn); + RIVA_HW_STATE *state; + + state = &pNv->SavedReg; + + nv_output_save_state_ext(output, state); + +} + +static void +nv_output_restore (xf86OutputPtr output) +{ + ScrnInfoPtr pScrn = output->scrn; + NVPtr pNv = NVPTR(pScrn); + RIVA_HW_STATE *state; + + state = &pNv->SavedReg; + + nv_output_load_state_ext(output, state); +} + +static int +nv_output_mode_valid(xf86OutputPtr output, DisplayModePtr pMode) +{ + if (pMode->Flags & V_DBLSCAN) + return MODE_NO_DBLESCAN; + + if (pMode->Clock > 400000 || pMode->Clock < 25000) + return MODE_CLOCK_RANGE; + + return MODE_OK; +} + + +static Bool +nv_output_mode_fixup(xf86OutputPtr output, DisplayModePtr mode, + DisplayModePtr adjusted_mode) +{ + return TRUE; +} + +static int +nv_output_tweak_panel(xf86OutputPtr output, NVRegPtr state) +{ + NVOutputPrivatePtr nv_output = output->driver_private; + ScrnInfoPtr pScrn = output->scrn; + NVPtr pNv = NVPTR(pScrn); + NVOutputRegPtr regp; + int tweak = 0; + + regp = &state->dac_reg[nv_output->ramdac]; + if (pNv->usePanelTweak) { + tweak = pNv->PanelTweak; + } else { + /* begin flat panel hacks */ + /* This is unfortunate, but some chips need this register + tweaked or else you get artifacts where adjacent pixels are + swapped. There are no hard rules for what to set here so all + we can do is experiment and apply hacks. */ + + if(((pNv->Chipset & 0xffff) == 0x0328) && (regp->bpp == 32)) { + /* At least one NV34 laptop needs this workaround. */ + tweak = -1; + } + + if((pNv->Chipset & 0xfff0) == CHIPSET_NV31) { + tweak = 1; + } + /* end flat panel hacks */ + } + return tweak; +} + +static void +nv_output_mode_set_regs(xf86OutputPtr output, DisplayModePtr mode) +{ + NVOutputPrivatePtr nv_output = output->driver_private; + ScrnInfoPtr pScrn = output->scrn; + int bpp; + NVPtr pNv = NVPTR(pScrn); + NVFBLayout *pLayout = &pNv->CurrentLayout; + RIVA_HW_STATE *state, *sv_state; + Bool is_fp = FALSE; + NVOutputRegPtr regp, savep; + xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn); + int i; + + state = &pNv->ModeReg; + regp = &state->dac_reg[nv_output->ramdac]; + + sv_state = &pNv->SavedReg; + savep = &sv_state->dac_reg[nv_output->ramdac]; + + if ((nv_output->type == OUTPUT_PANEL) || (nv_output->type == OUTPUT_DIGITAL)) + { + is_fp = TRUE; + + for (i = 0; i < 7; i++) { + regp->fp_horiz_regs[i] = savep->fp_horiz_regs[i]; + regp->fp_vert_regs[i] = savep->fp_vert_regs[i]; + } + + regp->fp_horiz_regs[REG_DISP_END] = mode->CrtcHDisplay - 1; + regp->fp_horiz_regs[REG_DISP_TOTAL] = mode->CrtcHTotal - 1; + regp->fp_horiz_regs[REG_DISP_CRTC] = mode->CrtcHDisplay; + regp->fp_horiz_regs[REG_DISP_SYNC_START] = mode->CrtcHSyncStart - 1; + regp->fp_horiz_regs[REG_DISP_SYNC_END] = mode->CrtcHSyncEnd - 1; + regp->fp_horiz_regs[REG_DISP_VALID_START] = mode->CrtcHSkew; + regp->fp_horiz_regs[REG_DISP_VALID_END] = mode->CrtcHDisplay - 1; + + regp->fp_vert_regs[REG_DISP_END] = mode->CrtcVDisplay - 1; + regp->fp_vert_regs[REG_DISP_TOTAL] = mode->CrtcVTotal - 1; + regp->fp_vert_regs[REG_DISP_CRTC] = mode->CrtcVDisplay; + regp->fp_vert_regs[REG_DISP_SYNC_START] = mode->CrtcVSyncStart - 1; + regp->fp_vert_regs[REG_DISP_SYNC_END] = mode->CrtcVSyncEnd - 1; + regp->fp_vert_regs[REG_DISP_VALID_START] = 0; + regp->fp_vert_regs[REG_DISP_VALID_END] = mode->CrtcVDisplay - 1; + + } + + if (pNv->Architecture >= NV_ARCH_10) + regp->nv10_cursync = savep->nv10_cursync | (1<<25); + + regp->bpp = bpp; /* this is not bitsPerPixel, it's 8,15,16,32 */ + + regp->debug_0 = savep->debug_0; + regp->fp_control = savep->fp_control & 0xfff000ff; + if(is_fp == 1) { + if(!pNv->fpScaler || (nv_output->fpWidth <= mode->HDisplay) + || (nv_output->fpHeight <= mode->VDisplay)) + { + regp->fp_control |= (1 << 8) ; + } + regp->crtcSync = savep->crtcSync; + regp->crtcSync += nv_output_tweak_panel(output, state); + + regp->debug_0 &= ~NV_RAMDAC_FP_DEBUG_0_PWRDOWN_BOTH; + } + else + regp->debug_0 |= NV_RAMDAC_FP_DEBUG_0_PWRDOWN_BOTH; + + ErrorF("output %d debug_0 %08X\n", nv_output->ramdac, regp->debug_0); + + if(pNv->twoHeads) { + if((pNv->Chipset & 0x0ff0) == CHIPSET_NV11) { + regp->dither = savep->dither & ~0x00010000; + if(pNv->FPDither) + regp->dither |= 0x00010000; + } else { + ErrorF("savep->dither %08X\n", savep->dither); + regp->dither = savep->dither & ~1; + if(pNv->FPDither) + regp->dither |= 1; + } + } + + if(pLayout->depth < 24) + bpp = pLayout->depth; + else bpp = 32; + + regp->general = bpp == 16 ? 0x00101100 : 0x00100100; + + if (pNv->alphaCursor) + regp->general |= (1<<29); + + if(bpp != 8) /* DirectColor */ + regp->general |= 0x00000030; + + if (output->crtc) { + NVCrtcPrivatePtr nv_crtc = output->crtc->driver_private; + int two_crt = FALSE; + int two_mon = FALSE; + + for (i = 0; i < config->num_output; i++) { + NVOutputPrivatePtr nv_output2 = config->output[i]->driver_private; + + /* is it this output ?? */ + if (config->output[i] == output) + continue; + + /* it the output connected */ + if (config->output[i]->crtc == NULL) + continue; + + two_mon = TRUE; + if ((nv_output2->type == OUTPUT_ANALOG) && (nv_output->type == OUTPUT_ANALOG)) + two_crt = TRUE; + } + + if (is_fp == TRUE) + regp->output = 0x0; + else + regp->output = NV_RAMDAC_OUTPUT_DAC_ENABLE; + + if (nv_crtc->crtc == 1 && two_mon) + regp->output |= NV_RAMDAC_OUTPUT_SELECT_CRTC2; + + ErrorF("%d: crtc %d output%d: %04X: twocrt %d twomon %d\n", is_fp, nv_crtc->crtc, nv_output->ramdac, regp->output, two_crt, two_mon); + } +} + +static void +nv_output_mode_set(xf86OutputPtr output, DisplayModePtr mode, + DisplayModePtr adjusted_mode) +{ + ScrnInfoPtr pScrn = output->scrn; + NVPtr pNv = NVPTR(pScrn); + RIVA_HW_STATE *state; + + state = &pNv->ModeReg; + + nv_output_mode_set_regs(output, mode); + nv_output_load_state_ext(output, state); +} + +static Bool +nv_ddc_detect(xf86OutputPtr output) +{ + /* no use for shared DDC output */ + NVOutputPrivatePtr nv_output = output->driver_private; + xf86MonPtr ddc_mon; + + ddc_mon = xf86OutputGetEDID(output, nv_output->pDDCBus); + if (!ddc_mon) + return 0; + + if (ddc_mon->features.input_type && (nv_output->type == OUTPUT_ANALOG)) + return 0; + + if ((!ddc_mon->features.input_type) && (nv_output->type == OUTPUT_DIGITAL)) + return 0; + + return 1; +} + +static Bool +nv_crt_load_detect(xf86OutputPtr output) +{ + ScrnInfoPtr pScrn = output->scrn; + CARD32 reg_output, reg_test_ctrl, temp; + int present = FALSE; + + reg_output = NVOutputReadRAMDAC(output, NV_RAMDAC_OUTPUT); + reg_test_ctrl = NVOutputReadRAMDAC(output, NV_RAMDAC_TEST_CONTROL); + + NVOutputWriteRAMDAC(output, NV_RAMDAC_TEST_CONTROL, (reg_test_ctrl & ~0x00010000)); + + NVOutputWriteRAMDAC(output, NV_RAMDAC_OUTPUT, (reg_output & 0x0000FEEE)); + usleep(1000); + + temp = NVOutputReadRAMDAC(output, NV_RAMDAC_OUTPUT); + NVOutputWriteRAMDAC(output, NV_RAMDAC_OUTPUT, temp | 1); + + NVOutputWriteRAMDAC(output, NV_RAMDAC_TEST_DATA, 0x94050140); + temp = NVOutputReadRAMDAC(output, NV_RAMDAC_TEST_CONTROL); + NVOutputWriteRAMDAC(output, NV_RAMDAC_TEST_CONTROL, temp | 0x1000); + + usleep(1000); + + present = (NVOutputReadRAMDAC(output, NV_RAMDAC_TEST_CONTROL) & (1 << 28)) ? TRUE : FALSE; + + temp = NVOutputReadRAMDAC(output, NV_RAMDAC_TEST_CONTROL); + NVOutputWriteRAMDAC(output, NV_RAMDAC_TEST_CONTROL, temp & 0x000EFFF); + + NVOutputWriteRAMDAC(output, NV_RAMDAC_OUTPUT, reg_output); + NVOutputWriteRAMDAC(output, NV_RAMDAC_TEST_CONTROL, reg_test_ctrl); + + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "CRT detect returned %d\n", + present); + + return present; + +} + +static xf86OutputStatus +nv_digital_output_detect(xf86OutputPtr output) +{ + NVOutputPrivatePtr nv_output = output->driver_private; + + if (nv_ddc_detect(output)) + return XF86OutputStatusConnected; + + return XF86OutputStatusDisconnected; +} + + +static xf86OutputStatus +nv_analog_output_detect(xf86OutputPtr output) +{ + NVOutputPrivatePtr nv_output = output->driver_private; + + if (nv_ddc_detect(output)) + return XF86OutputStatusConnected; + + /* seems a bit flaky on ramdac 1 */ + if ((nv_output->ramdac==0) && nv_crt_load_detect(output)) + return XF86OutputStatusConnected; + + return XF86OutputStatusDisconnected; +} + +static DisplayModePtr +nv_output_get_modes(xf86OutputPtr output) +{ + ScrnInfoPtr pScrn = output->scrn; + NVOutputPrivatePtr nv_output = output->driver_private; + xf86MonPtr ddc_mon; + DisplayModePtr ddc_modes, mode; + int i; + + + ddc_mon = xf86OutputGetEDID(output, nv_output->pDDCBus); + + if (ddc_mon == NULL) { + xf86OutputSetEDID(output, ddc_mon); + return NULL; + } + + if (ddc_mon->features.input_type && (nv_output->type == OUTPUT_ANALOG)) { + xf86OutputSetEDID(output, NULL); + return NULL; + } + + if ((!ddc_mon->features.input_type) && (nv_output->type == OUTPUT_DIGITAL)) { + xf86OutputSetEDID(output, NULL); + return NULL; + } + + xf86OutputSetEDID(output, ddc_mon); + + ddc_modes = xf86OutputGetEDIDModes (output); + return ddc_modes; + +} + +static void +nv_output_destroy (xf86OutputPtr output) +{ + if (output->driver_private) + xfree (output->driver_private); + +} + +static void +nv_output_prepare(xf86OutputPtr output) +{ + +} + +static void +nv_output_commit(xf86OutputPtr output) +{ + + +} + +static const xf86OutputFuncsRec nv_analog_output_funcs = { + .dpms = nv_analog_output_dpms, + .save = nv_output_save, + .restore = nv_output_restore, + .mode_valid = nv_output_mode_valid, + .mode_fixup = nv_output_mode_fixup, + .mode_set = nv_output_mode_set, + .detect = nv_analog_output_detect, + .get_modes = nv_output_get_modes, + .destroy = nv_output_destroy, + .prepare = nv_output_prepare, + .commit = nv_output_commit, +}; + +static const xf86OutputFuncsRec nv_digital_output_funcs = { + .dpms = nv_digital_output_dpms, + .save = nv_output_save, + .restore = nv_output_restore, + .mode_valid = nv_output_mode_valid, + .mode_fixup = nv_output_mode_fixup, + .mode_set = nv_output_mode_set, + .detect = nv_digital_output_detect, + .get_modes = nv_output_get_modes, + .destroy = nv_output_destroy, + .prepare = nv_output_prepare, + .commit = nv_output_commit, +}; + +static xf86OutputStatus +nv_output_lvds_detect(xf86OutputPtr output) +{ + return XF86OutputStatusUnknown; +} + +static DisplayModePtr +nv_output_lvds_get_modes(xf86OutputPtr output) +{ + ScrnInfoPtr pScrn = output->scrn; + NVOutputPrivatePtr nv_output = output->driver_private; + + // nv_output->fpWidth = NVOutputReadRAMDAC(output, NV_RAMDAC_FP_HDISP_END) + 1; + // nv_output->fpHeight = NVOutputReadRAMDAC(output, NV_RAMDAC_FP_VDISP_END) + 1; + nv_output->fpSyncs = NVOutputReadRAMDAC(output, NV_RAMDAC_FP_CONTROL) & 0x30000033; + // xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "Panel size is %i x %i\n", + // nv_output->fpWidth, nv_output->fpHeight); + + return NULL; + +} + +static const xf86OutputFuncsRec nv_lvds_output_funcs = { + .dpms = nv_panel_output_dpms, + .save = nv_output_save, + .restore = nv_output_restore, + .mode_valid = nv_output_mode_valid, + .mode_fixup = nv_output_mode_fixup, + .mode_set = nv_output_mode_set, + .detect = nv_output_lvds_detect, + .get_modes = nv_output_lvds_get_modes, + .destroy = nv_output_destroy, + .prepare = nv_output_prepare, + .commit = nv_output_commit, +}; + + +static void nv_add_analog_output(ScrnInfoPtr pScrn, int i2c_index) +{ + NVPtr pNv = NVPTR(pScrn); + xf86OutputPtr output; + NVOutputPrivatePtr nv_output; + char outputname[20]; + int crtc_mask = (1<<0) | (1<<1); + + sprintf(outputname, "Analog-%d", pNv->analog_count); + output = xf86OutputCreate (pScrn, &nv_analog_output_funcs, outputname); + if (!output) + return; + nv_output = xnfcalloc (sizeof (NVOutputPrivateRec), 1); + if (!nv_output) + { + xf86OutputDestroy (output); + return; + } + + output->driver_private = nv_output; + nv_output->type = OUTPUT_ANALOG; + + nv_output->ramdac = pNv->analog_count; + + nv_output->pDDCBus = pNv->pI2CBus[i2c_index]; + + output->possible_crtcs = crtc_mask; + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "Adding output %s\n", outputname); + + pNv->analog_count++; +} + + +static void nv_add_digital_output(ScrnInfoPtr pScrn, int i2c_index) +{ + NVPtr pNv = NVPTR(pScrn); + xf86OutputPtr output; + NVOutputPrivatePtr nv_output; + char outputname[20]; + int crtc_mask = (1<<0) | (1<<1); + + sprintf(outputname, "Digital-%d", pNv->digital_count); + output = xf86OutputCreate (pScrn, &nv_digital_output_funcs, outputname); + if (!output) + return; + nv_output = xnfcalloc (sizeof (NVOutputPrivateRec), 1); + if (!nv_output) + { + xf86OutputDestroy (output); + return; + } + + output->driver_private = nv_output; + nv_output->type = OUTPUT_DIGITAL; + + nv_output->ramdac = pNv->digital_count; + + nv_output->pDDCBus = pNv->pI2CBus[i2c_index]; + + output->possible_crtcs = crtc_mask; + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "Adding output %s\n", outputname); + + pNv->digital_count++; +} +/** + * Set up the outputs according to what type of chip we are. + * + * Some outputs may not initialize, due to allocation failure or because a + * controller chip isn't found. + */ + +void Nv20SetupOutputs(ScrnInfoPtr pScrn) +{ + NVPtr pNv = NVPTR(pScrn); + xf86OutputPtr output; + NVOutputPrivatePtr nv_output; + int i; + int num_analog_outputs = pNv->twoHeads ? 2 : 1; + int num_digital_outputs = 1; + + for (i = 0 ; i < num_analog_outputs; i++) { + nv_add_analog_output(pScrn, i); + } + + for (i = 0 ; i < num_digital_outputs; i++) { + nv_add_digital_output(pScrn, i); + } +} + +void NvDCBSetupOutputs(ScrnInfoPtr pScrn) +{ + unsigned char type, port, or; + NVPtr pNv = NVPTR(pScrn); + int i; + + /* we setup the outputs up from the BIOS table */ + if (pNv->dcb_entries) { + for (i = 0 ; i < pNv->dcb_entries; i++) { + type = pNv->dcb_table[i] & 0xf; + port = (pNv->dcb_table[i] >> 4) & 0xf; + or = ffs((pNv->dcb_table[i] >> 24) & 0xf) - 1; + + if (type < 4) + xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "DCB entry: %d: %08X type: %d, port %d:, or %d\n", i, pNv->dcb_table[i], type, port, or); + if (type < 4 && port != 0xf) { + switch(type) { + case 0: /* analog */ + nv_add_analog_output(pScrn, port); + break; + case 2: + nv_add_digital_output(pScrn, port); + default: + break; + } + } + } + } else + Nv20SetupOutputs(pScrn); + +} + +struct nv_i2c_struct { + int reg; + char *name; +} nv_i2c_buses[] = { + { 0x3e, "DDC1" }, + { 0x36, "DDC2" }, + { 0x50, "TV" }, +}; + + +void NvSetupOutputs(ScrnInfoPtr pScrn) +{ + int i; + NVPtr pNv = NVPTR(pScrn); + xf86OutputPtr output; + NVOutputPrivatePtr nv_output; + + int num_outputs = pNv->twoHeads ? 2 : 1; + char outputname[20]; + pNv->Television = FALSE; + + /* add the 3 I2C buses */ + for (i = 0; i < NV_I2C_BUSES; i++) { + NV_I2CInit(pScrn, &pNv->pI2CBus[i], nv_i2c_buses[i].reg, nv_i2c_buses[i].name); + } + + NvDCBSetupOutputs(pScrn); + +#if 0 + if (pNv->Mobile) { + output = xf86OutputCreate(pScrn, &nv_output_funcs, OutputType[OUTPUT_LVDS]); + if (!output) + return; + + nv_output = xnfcalloc(sizeof(NVOutputPrivateRec), 1); + if (!nv_output) { + xf86OutputDestroy(output); + return; + } + + output->driver_private = nv_output; + nv_output->type = output_type; + + output->possible_crtcs = i ? 1 : crtc_mask; + } +#endif +} + + +/*************************************************************************** \ +|* *| +|* Copyright 1993-2003 NVIDIA, Corporation. All rights reserved. *| +|* *| +|* NOTICE TO USER: The source code is copyrighted under U.S. and *| +|* international laws. Users and possessors of this source code are *| +|* hereby granted a nonexclusive, royalty-free copyright license to *| +|* use this code in individual and commercial software. *| +|* *| +|* Any use of this source code must include, in the user documenta- *| +|* tion and internal comments to the code, notices to the end user *| +|* as follows: *| +|* *| +|* Copyright 1993-1999 NVIDIA, Corporation. All rights reserved. *| +|* *| +|* NVIDIA, CORPORATION MAKES NO REPRESENTATION ABOUT THE SUITABILITY *| +|* OF THIS SOURCE CODE FOR ANY PURPOSE. IT IS PROVIDED "AS IS" *| +|* WITHOUT EXPRESS OR IMPLIED WARRANTY OF ANY KIND. NVIDIA, CORPOR- *| +|* ATION DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOURCE CODE, *| +|* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGE- *| +|* MENT, AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL *| +|* NVIDIA, CORPORATION BE LIABLE FOR ANY SPECIAL, INDIRECT, INCI- *| +|* DENTAL, OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RE- *| +|* SULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION *| +|* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF *| +|* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOURCE CODE. *| +|* *| +|* U.S. Government End Users. This source code is a "commercial *| +|* item," as that term is defined at 48 C.F.R. 2.101 (OCT 1995), *| +|* consisting of "commercial computer software" and "commercial *| +|* computer software documentation," as such terms are used in *| +|* 48 C.F.R. 12.212 (SEPT 1995) and is provided to the U.S. Govern- *| +|* ment only as a commercial end item. Consistent with 48 C.F.R. *| +|* 12.212 and 48 C.F.R. 227.7202-1 through 227.7202-4 (JUNE 1995), *| +|* all U.S. Government End Users acquire the source code with only *| +|* those rights set forth herein. *| +|* *| + \***************************************************************************/ diff --git a/src/nv_proto.h b/src/nv_proto.h index 9f5fbac..df6cbfb 100644 --- a/src/nv_proto.h +++ b/src/nv_proto.h @@ -40,17 +40,6 @@ Bool NVDRIFinishScreenInit(ScrnInfoPtr pScrn); extern const char *drmSymbols[], *driSymbols[]; Bool NVDRIGetVersion(ScrnInfoPtr pScrn); -/* in nv_dac.c */ -Bool NVDACInit(ScrnInfoPtr pScrn, DisplayModePtr mode); -void NVDACSave(ScrnInfoPtr pScrn, vgaRegPtr vgaReg, - NVRegPtr nvReg, Bool saveFonts); -void NVDACRestore(ScrnInfoPtr pScrn, vgaRegPtr vgaReg, - NVRegPtr nvReg, Bool restoreFonts); -void NVDACLoadPalette(ScrnInfoPtr pScrn, int numColors, int *indices, - LOCO *colors, VisualPtr pVisual ); -Bool NVDACi2cInit(ScrnInfoPtr pScrn); - - /* in nv_video.c */ void NVInitVideo(ScreenPtr); void NVResetVideo (ScrnInfoPtr pScrnInfo); @@ -85,8 +74,6 @@ void NVCalcStateExt(NVPtr,struct _riva_hw_state *,int,int,int,int,int,int); void NVLoadStateExt(ScrnInfoPtr pScrn,struct _riva_hw_state *); void NVUnloadStateExt(NVPtr,struct _riva_hw_state *); void NVSetStartAddress(NVPtr,CARD32); -int NVShowHideCursor(NVPtr,int); -void NVLockUnlock(NVPtr,int); uint8_t nvReadVGA(NVPtr pNv, uint8_t index); void nvWriteVGA(NVPtr pNv, uint8_t index, uint8_t data); void nvWriteRAMDAC(NVPtr pNv, uint8_t head, uint32_t ramdac_reg, CARD32 val); @@ -104,6 +91,43 @@ void NVPointerMoved(int index, int x, int y); /* in nv_bios.c */ unsigned int NVParseBios(ScrnInfoPtr pScrn); +void nForceUpdateArbitrationSettings (unsigned VClk, unsigned pixelDepth, + unsigned *burst, unsigned *lwm, + NVPtr pNv); + + +/* nv_crtc.c */ +Bool NVSetMode(ScrnInfoPtr pScrn, DisplayModePtr pMode, Rotation rotation); +Bool NVCrtcSetMode(xf86CrtcPtr crtc, DisplayModePtr pMode, Rotation rotation, int x, int y); +DisplayModePtr NVCrtcFindClosestMode(xf86CrtcPtr crtc, DisplayModePtr pMode); +void NVCrtcSetBase (xf86CrtcPtr crtc, int x, int y); +void NVCrtcLoadPalette(xf86CrtcPtr crtc); +void NVCrtcBlankScreen(xf86CrtcPtr crtc, Bool on); + +/* nv_hw.c */ +void nForceUpdateArbitrationSettings (unsigned VClk, unsigned pixelDepth, + unsigned *burst, unsigned *lwm, + NVPtr pNv); +void nv30UpdateArbitrationSettings (NVPtr pNv, + unsigned *burst, + unsigned *lwm); +void nv10UpdateArbitrationSettings (unsigned VClk, + unsigned pixelDepth, + unsigned *burst, + unsigned *lwm, + NVPtr pNv); +void nv4UpdateArbitrationSettings (unsigned VClk, + unsigned pixelDepth, + unsigned *burst, + unsigned *lwm, + NVPtr pNv); + +void NVInitSurface(ScrnInfoPtr pScrn, RIVA_HW_STATE *state); +void NVInitGraphContext(ScrnInfoPtr pScrn); + +/* nv_i2c.c */ +Bool NV_I2CInit(ScrnInfoPtr pScrn, I2CBusPtr *bus_ptr, int i2c_reg, char *name); + /* in nv30_exa.c */ Bool NVAccelInitNV40TCL(ScrnInfoPtr pScrn); Bool NV30EXACheckComposite(int, PicturePtr, PicturePtr, PicturePtr); @@ -112,5 +136,18 @@ Bool NV30EXAPrepareComposite(int, PicturePtr, PicturePtr, PicturePtr, void NV30EXAComposite(PixmapPtr, int, int, int, int, int, int, int, int); void NV30EXADoneComposite(PixmapPtr); +/* in nv50_exa.c */ +Bool NV50EXAPrepareSolid(PixmapPtr, int, Pixel, Pixel); +void NV50EXASolid(PixmapPtr, int, int, int, int); +void NV50EXADoneSolid(PixmapPtr); +Bool NV50EXAPrepareCopy(PixmapPtr, PixmapPtr, int, int, int, Pixel); +void NV50EXACopy(PixmapPtr, int, int, int, int, int, int); +void NV50EXADoneCopy(PixmapPtr); +Bool NV50EXACheckComposite(int, PicturePtr, PicturePtr, PicturePtr); +Bool NV50EXAPrepareComposite(int, PicturePtr, PicturePtr, PicturePtr, + PixmapPtr, PixmapPtr, PixmapPtr); +void NV50EXAComposite(PixmapPtr, int, int, int, int, int, int, int, int); +void NV50EXADoneComposite(PixmapPtr); + #endif /* __NV_PROTO_H__ */ diff --git a/src/nv_setup.c b/src/nv_setup.c index 8af34c1..55d144d 100644 --- a/src/nv_setup.c +++ b/src/nv_setup.c @@ -42,6 +42,8 @@ #include "nv_include.h" #include "nvreg.h" +CARD32 debug_offset; + /* * Override VGA I/O routines. */ @@ -178,50 +180,6 @@ static CARD8 NVReadDacData(vgaHWPtr pVga) return (VGA_RD08(ptr, VGA_DAC_DATA)); } -static Bool -NVIsConnected (ScrnInfoPtr pScrn, int output) -{ - NVPtr pNv = NVPTR(pScrn); - CARD32 reg52C, reg608, temp; - Bool present; - - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "Probing for analog device on output %s...\n", - output ? "B" : "A"); - - reg52C = nvReadRAMDAC(pNv, output, NV_RAMDAC_052C); - reg608 = nvReadRAMDAC(pNv, output, NV_RAMDAC_TEST_CONTROL); - - nvWriteRAMDAC(pNv, output, NV_RAMDAC_TEST_CONTROL, (reg608 & ~0x00010000)); - - nvWriteRAMDAC(pNv, output, NV_RAMDAC_052C, (reg52C & 0x0000FEEE)); - usleep(1000); - - temp = nvReadRAMDAC(pNv, output, NV_RAMDAC_052C); - nvWriteRAMDAC(pNv, output, NV_RAMDAC_052C, temp | 1); - - nvWriteRAMDAC(pNv, output, NV_RAMDAC_TEST_DATA, 0x94050140); - temp = nvReadRAMDAC(pNv, output, NV_RAMDAC_TEST_CONTROL); - nvWriteRAMDAC(pNv, output, NV_RAMDAC_TEST_CONTROL, temp | 0x1000); - - usleep(1000); - - present = (nvReadRAMDAC(pNv, output, NV_RAMDAC_TEST_CONTROL) & (1 << 28)) ? TRUE : FALSE; - - if(present) - xf86DrvMsg(pScrn->scrnIndex, X_PROBED, " ...found one\n"); - else - xf86DrvMsg(pScrn->scrnIndex, X_PROBED, " ...can't find one\n"); - - temp = nvReadRAMDAC(pNv, output, NV_RAMDAC_TEST_CONTROL); - nvWriteRAMDAC(pNv, output, NV_RAMDAC_TEST_CONTROL, temp & 0x000EFFF); - - nvWriteRAMDAC(pNv, output, NV_RAMDAC_052C, reg52C); - nvWriteRAMDAC(pNv, output, NV_RAMDAC_TEST_CONTROL, reg608); - - return present; -} - static void NVSelectHeadRegisters(ScrnInfoPtr pScrn, int head) { @@ -230,32 +188,6 @@ NVSelectHeadRegisters(ScrnInfoPtr pScrn, int head) pNv->cur_head = head; } -static xf86MonPtr -NVProbeDDC (ScrnInfoPtr pScrn, int bus) -{ - NVPtr pNv = NVPTR(pScrn); - xf86MonPtr MonInfo = NULL; - - if(!pNv->I2C) return NULL; - - pNv->DDCBase = bus ? 0x36 : 0x3e; - - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "Probing for EDID on I2C bus %s...\n", bus ? "B" : "A"); - - if ((MonInfo = xf86DoEDID_DDC2(pScrn->scrnIndex, pNv->I2C))) { - xf86DrvMsg(pScrn->scrnIndex, X_PROBED, - "DDC detected a %s:\n", MonInfo->features.input_type ? - "DFP" : "CRT"); - xf86PrintEDID( MonInfo ); - } else { - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - " ... none found\n"); - } - - return MonInfo; -} - static void nv3GetConfig (NVPtr pNv) { CARD32 reg_FB0 = nvReadFB(pNv, 0x0); @@ -352,12 +284,6 @@ NVCommonSetup(ScrnInfoPtr pScrn) NVPtr pNv = NVPTR(pScrn); vgaHWPtr pVga = VGAHWPTR(pScrn); CARD16 implementation = pNv->Chipset & 0x0ff0; - xf86MonPtr monitorA, monitorB; - Bool mobile = FALSE; - Bool tvA = FALSE; - Bool tvB = FALSE; - int FlatPanel = -1; /* really means the CRTC is slaved */ - Bool Television = FALSE; /* * Override VGA I/O routines. @@ -390,7 +316,8 @@ NVCommonSetup(ScrnInfoPtr pScrn) pNv->REGS = xf86MapPciMem(pScrn->scrnIndex, VIDMEM_MMIO | VIDMEM_READSIDEEFFECT, pNv->PciTag, pNv->IOAddress, 0x01000000); - + + debug_offset = pNv->REGS; pNv->PRAMIN = pNv->REGS + (NV_PRAMIN_OFFSET/4); pNv->PCRTC0 = pNv->REGS + (NV_PCRTC0_OFFSET/4); pNv->PRAMDAC0 = pNv->REGS + (NV_PRAMDAC0_OFFSET/4); @@ -430,6 +357,35 @@ NVCommonSetup(ScrnInfoPtr pScrn) pNv->BlendingPossible = ((pNv->Chipset & 0xffff) > CHIPSET_NV04); + /* Chipset from PMC_BOOT_0 register */ + if (pNv->Architecture == NV_ARCH_04) { + pNv->_Chipset = 0x04; + } else { + pNv->_Chipset = (nvReadMC(pNv, 0) >> 20) & 0xff; + } + + /* Parse the bios to initialize the card */ + NVSelectHeadRegisters(pScrn, 0); + NVParseBios(pScrn); +#if 0 + /* reset PFIFO and PGRAPH, then power up all the card units */ + nvWriteMC(pNv, 0x200, 0x17110013); + usleep(1000); + nvWriteMC(pNv, 0x200, 0x17111113); +#endif + + if(pNv->Architecture == NV_ARCH_03) + nv3GetConfig(pNv); + else if(pNv->Architecture == NV_ARCH_04) + nv4GetConfig(pNv); + else + nv10GetConfig(pNv); + + NVSelectHeadRegisters(pScrn, 0); + + pNv->vtOWNER = nvReadVGA(pNv, NV_VGA_CRTCX_OWNER); + + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "vtowner is %d\n", pNv->vtOWNER); /* look for known laptop chips */ /* FIXME we could add some ids here (0x0164,0x0167,0x0168,0x01D6,0x01D7,0x01D8,0x0298,0x0299,0x0398) */ switch(pNv->Chipset & 0xffff) { @@ -479,34 +435,27 @@ NVCommonSetup(ScrnInfoPtr pScrn) case 0x0148: case 0x0098: case 0x0099: - mobile = TRUE; + pNv->Mobile = TRUE; break; default: break; } - /* Parse the bios to initialize the card */ - NVSelectHeadRegisters(pScrn, 0); - NVParseBios(pScrn); - /* reset PFIFO and PGRAPH, then power up all the card units */ - nvWriteMC(pNv, 0x200, 0x17110013); - usleep(1000); - nvWriteMC(pNv, 0x200, 0x17111113); - - if(pNv->Architecture == NV_ARCH_03) - nv3GetConfig(pNv); - else if(pNv->Architecture == NV_ARCH_04) - nv4GetConfig(pNv); - else - nv10GetConfig(pNv); - - NVSelectHeadRegisters(pScrn, 0); - - NVLockUnlock(pNv, 0); + pNv->Television = FALSE; - NVI2CInit(pScrn); +} - pNv->Television = FALSE; +#if 0 +void NVPreInitOldCode(ScrnInfoPtr pScrn) +{ + NVPtr pNv = NVPTR(pScrn); + xf86MonPtr monitorA, monitorB; + Bool mobile = pNv->Mobile; + Bool tvA = FALSE; + Bool tvB = FALSE; + int FlatPanel = -1; /* really means the CRTC is slaved */ + Bool Television = FALSE; + CARD16 implementation = pNv->Chipset & 0x0ff0; if(!pNv->twoHeads) { pNv->CRTCnumber = 0; @@ -736,3 +685,4 @@ NVCommonSetup(ScrnInfoPtr pScrn) } } +#endif diff --git a/src/nv_type.h b/src/nv_type.h index 6c3edb0..01f76cc 100644 --- a/src/nv_type.h +++ b/src/nv_type.h @@ -15,16 +15,20 @@ #include "dri.h" #include <stdint.h> #include "nouveau_drm.h" +#include "xf86Crtc.h" #else #error "This driver requires a DRI-enabled X server" #endif +#include "nv50_type.h" + #define NV_ARCH_03 0x03 #define NV_ARCH_04 0x04 #define NV_ARCH_10 0x10 #define NV_ARCH_20 0x20 #define NV_ARCH_30 0x30 #define NV_ARCH_40 0x40 +#define NV_ARCH_50 0x50 #define CHIPSET_NV03 0x0010 #define CHIPSET_NV04 0x0020 @@ -49,6 +53,8 @@ #define CHIPSET_NV44 0x0160 #define CHIPSET_NV44A 0x0220 #define CHIPSET_NV45 0x0210 +#define CHIPSET_NV50 0x0190 +#define CHIPSET_NV84 0x0400 #define CHIPSET_MISC_BRIDGED 0x00F0 #define CHIPSET_G70 0x0090 #define CHIPSET_G71 0x0290 @@ -69,6 +75,18 @@ #define SetBit(n) (1<<(n)) #define Set8Bits(value) ((value)&0xff) +#define NV_I2C_BUSES 3 +#define NV40_NUM_DCB_ENTRIES 10 + +typedef enum +{ + OUTPUT_NONE, + OUTPUT_ANALOG, + OUTPUT_DIGITAL, + OUTPUT_PANEL, + OUTPUT_TV, +} NVOutputType; + typedef struct { int bitsPerPixel; int depth; @@ -77,21 +95,37 @@ typedef struct { DisplayModePtr mode; } NVFBLayout; -typedef struct _riva_hw_state +typedef struct _nv_crtc_reg { - CARD32 bpp; - CARD32 width; - CARD32 height; - CARD32 interlace; - CARD32 repaint0; - CARD32 repaint1; - CARD32 screen; - CARD32 scale; + unsigned char MiscOutReg; /* */ + CARD8 CRTC[90]; + CARD8 Sequencer[5]; + CARD8 Graphics[9]; + CARD8 Attribute[21]; + unsigned char DAC[768]; /* Internal Colorlookuptable */ + CARD32 cursorConfig; + CARD32 crtcOwner; + CARD32 unk830; + CARD32 unk834; + CARD32 head; +} NVCrtcRegRec, *NVCrtcRegPtr; + +typedef struct _nv_output_reg +{ + CARD32 fp_control; + CARD32 crtcSync; CARD32 dither; - CARD32 extra; - CARD32 fifo; - CARD32 pixel; - CARD32 horiz; + CARD32 general; + CARD32 bpp; + CARD32 nv10_cursync; + CARD32 output; + CARD32 debug_0; + CARD32 fp_horiz_regs[7]; + CARD32 fp_vert_regs[7]; +} NVOutputRegRec, *NVOutputRegPtr; + +typedef struct _riva_hw_state +{ CARD32 arbitration0; CARD32 arbitration1; CARD32 pll; @@ -101,19 +135,12 @@ typedef struct _riva_hw_state CARD32 vpllB; CARD32 vpll2B; CARD32 pllsel; - CARD32 general; - CARD32 crtcOwner; - CARD32 head; - CARD32 head2; CARD32 config; - CARD32 cursorConfig; - CARD32 cursor0; - CARD32 cursor1; - CARD32 cursor2; + CARD32 timingH; CARD32 timingV; - CARD32 displayV; - CARD32 crtcSync; + NVCrtcRegRec crtc_reg[2]; + NVOutputRegRec dac_reg[2]; } RIVA_HW_STATE, *NVRegPtr; typedef struct { @@ -123,6 +150,25 @@ typedef struct { void *map; } NVAllocRec; +typedef struct _NVCrtcPrivateRec { + int crtc; + Bool paletteEnabled; +} NVCrtcPrivateRec, *NVCrtcPrivatePtr; + +#define NVCrtcPrivate(c) ((NVCrtcPrivatePtr)(c)->driver_private) + +typedef struct _NVOutputPrivateRec { + int ramdac; + I2CBusPtr pDDCBus; + NVOutputType type; + CARD32 fpSyncs; + CARD32 fpWidth; + CARD32 fpHeight; + Bool fpdither; +} NVOutputPrivateRec, *NVOutputPrivatePtr; + +#define NVOutputPrivate(o) ((NVOutputPrivatePtr (o)->driver_private) + typedef struct _NVRec *NVPtr; typedef struct _NVRec { RIVA_HW_STATE SavedReg; @@ -133,9 +179,11 @@ typedef struct _NVRec { pciVideoPtr PciInfo; PCITAG PciTag; int Chipset; + int _Chipset; int ChipRev; Bool Primary; CARD32 IOAddress; + Bool cursorOn; /* VRAM physical address */ unsigned long VRAMPhysical; @@ -152,8 +200,10 @@ typedef struct _NVRec { NVAllocRec * FB; NVAllocRec * Cursor; + NVAllocRec * CLUT; /* NV50 only */ NVAllocRec * ScratchBuffer; NVAllocRec * GARTScratch; + Bool NoAccel; Bool HWCursor; Bool FpScale; @@ -193,6 +243,7 @@ typedef struct _NVRec { volatile CARD32 *RAMHT; CARD32 pramin_free; + unsigned int SaveGeneration; uint8_t cur_head; XAAInfoRecPtr AccelInfoRec; ExaDriverPtr EXADriverPtr; @@ -207,8 +258,8 @@ typedef struct _NVRec { CARD32 curFg, curBg; CARD32 curImage[256]; /* I2C / DDC */ - I2CBusPtr I2C; - xf86Int10InfoPtr pInt; + int ddc2; + xf86Int10InfoPtr pInt10; void (*VideoTimerCallback)(ScrnInfoPtr, Time); void (*DMAKickoffCallback)(NVPtr pNv); XF86VideoAdaptorPtr overlayAdaptor; @@ -216,6 +267,7 @@ typedef struct _NVRec { int videoKey; int FlatPanel; Bool FPDither; + int Mobile; Bool Television; int CRTCnumber; int vtOWNER; @@ -253,6 +305,21 @@ typedef struct _NVRec { DRIInfoPtr pDRIInfo; drmVersionPtr pLibDRMVersion; drmVersionPtr pKernelDRMVersion; + + CreateScreenResourcesProcPtr CreateScreenResources; + + /* we know about 3 i2c buses */ + I2CBusPtr pI2CBus[3]; + int dcb_entries; + + int analog_count; + int digital_count; + CARD32 dcb_table[NV40_NUM_DCB_ENTRIES]; /* 10 is a good limit */ + + struct { + ORNum dac; + ORNum sor; + } i2cMap[4]; } NVRec; #define NVPTR(p) ((NVPtr)((p)->driverPrivate)) diff --git a/src/nv_xaa.c b/src/nv_xaa.c index 3c0f033..ef8bbbc 100644 --- a/src/nv_xaa.c +++ b/src/nv_xaa.c @@ -45,7 +45,7 @@ #include "nv_dma.h" #include "nvreg.h" -static const int NVCopyROP[16] = +const int NVCopyROP[16] = { 0x00, /* GXclear */ 0x88, /* GXand */ diff --git a/src/nv_xf86Rename.h b/src/nv_xf86Rename.h new file mode 100644 index 0000000..cf8de62 --- /dev/null +++ b/src/nv_xf86Rename.h @@ -0,0 +1,66 @@ +/* + * Copyright © 2006 Keith Packard + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that copyright + * notice and this permission notice appear in supporting documentation, and + * that the name of the copyright holders not be used in advertising or + * publicity pertaining to distribution of the software without specific, + * written prior permission. The copyright holders make no representations + * about the suitability of this software for any purpose. It is provided "as + * is" without express or implied warranty. + * + * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, + * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE + * OF THIS SOFTWARE. + */ + +#ifndef _XF86RENAME_H_ +#define _XF86RENAME_H_ + +#include "local_xf86Rename.h" + +#define xf86CrtcConfigInit XF86NAME(xf86CrtcConfigInit) +#define xf86CrtcConfigPrivateIndex XF86NAME(xf86CrtcConfigPrivateIndex) +#define xf86CrtcCreate XF86NAME(xf86CrtcCreate) +#define xf86CrtcDestroy XF86NAME(xf86CrtcDestroy) +#define xf86CrtcInUse XF86NAME(xf86CrtcInUse) +#define xf86CrtcRotate XF86NAME(xf86CrtcRotate) +#define xf86CrtcSetMode XF86NAME(xf86CrtcSetMode) +#define xf86CrtcSetSizeRange XF86NAME(xf86CrtcSetSizeRange) +#define xf86CVTMode XF86NAME(xf86CVTMode) +#define xf86DisableUnusedFunctions XF86NAME(xf86DisableUnusedFunctions) +#define xf86DPMSSet XF86NAME(xf86DPMSSet) +#define xf86DuplicateMode XF86NAME(xf86DuplicateMode) +#define xf86DuplicateModes XF86NAME(xf86DuplicateModes) +#define xf86GetDefaultModes XF86NAME(xf86GetDefaultModes) +#define xf86GetMonitorModes XF86NAME(xf86GetMonitorModes) +#define xf86InitialConfiguration XF86NAME(xf86InitialConfiguration) +#define xf86ModeHSync XF86NAME(xf86ModeHSync) +#define xf86ModesAdd XF86NAME(xf86ModesAdd) +#define xf86ModesEqual XF86NAME(xf86ModesEqual) +#define xf86ModeVRefresh XF86NAME(xf86ModeVRefresh) +#define xf86OutputCreate XF86NAME(xf86OutputCreate) +#define xf86OutputDestroy XF86NAME(xf86OutputDestroy) +#define xf86OutputGetEDID XF86NAME(xf86OutputGetEDID) +#define xf86OutputGetEDIDModes XF86NAME(xf86OutputGetEDIDModes) +#define xf86OutputRename XF86NAME(xf86OutputRename) +#define xf86OutputSetEDID XF86NAME(xf86OutputSetEDID) +#define xf86PrintModeline XF86NAME(xf86PrintModeline) +#define xf86ProbeOutputModes XF86NAME(xf86ProbeOutputModes) +#define xf86PruneInvalidModes XF86NAME(xf86PruneInvalidModes) +#define xf86SetModeCrtc XF86NAME(xf86SetModeCrtc) +#define xf86SetModeDefaultName XF86NAME(xf86SetModeDefaultName) +#define xf86SetScrnInfoModes XF86NAME(xf86SetScrnInfoModes) +#define xf86ValidateModesClocks XF86NAME(xf86ValidateModesClocks) +#define xf86ValidateModesFlags XF86NAME(xf86ValidateModesFlags) +#define xf86ValidateModesSize XF86NAME(xf86ValidateModesSize) +#define xf86ValidateModesSync XF86NAME(xf86ValidateModesSync) +#define xf86ValidateModesUserConfig XF86NAME(xf86ValidateModesUserConfig) + +#endif /* _XF86RENAME_H_ */ diff --git a/src/nvreg.h b/src/nvreg.h index 0cbe930..ca0f850 100644 --- a/src/nvreg.h +++ b/src/nvreg.h @@ -120,6 +120,7 @@ #define NV_VGA_CRTCX_FIFO_LWM_NV30 0x47 #define NV_VGA_CRTCX_FP_HTIMING 0x53 #define NV_VGA_CRTCX_FP_VTIMING 0x54 +#define NV_VGA_CRTCX_59 0x59 #define NV_PGRAPH_STATUS (0x00000700) #define NV_PFIFO_RAMHT (0x00000210) @@ -131,7 +132,7 @@ #define NV_RAMDAC_CURSOR_DATA_LO 0x324 #define NV_RAMDAC_CURSOR_DATA_HI 0x328 -#define NV_RAMDAC_0404 0x404 +#define NV_RAMDAC_NV10_CURSYNC 0x404 #define NV_RAMDAC_NVPLL 0x500 #define NV_RAMDAC_MPLL 0x504 @@ -141,9 +142,37 @@ #define NV_RAMDAC_VPLL 0x508 #define NV_RAMDAC_PLL_SELECT 0x50c +#define NV_RAMDAC_PLL_SELECT_DLL_BYPASS (1<<4) +#define NV_RAMDAC_PLL_SELECT_PLL_SOURCE_DEFAULT (0<<8) +#define NV_RAMDAC_PLL_SELECT_PLL_SOURCE_MPLL (1<<8) +#define NV_RAMDAC_PLL_SELECT_PLL_SOURCE_VPLL (2<<8) +#define NV_RAMDAC_PLL_SELECT_PLL_SOURCE_NVPLL (4<<8) +#define NV_RAMDAC_PLL_SELECT_PLL_SOURCE_ALL (7<<8) +#define NV_RAMDAC_PLL_SELECT_MPLL_BYPASS_FALSE (0<<12) +#define NV_RAMDAC_PLL_SELECT_MPLL_BYPASS_TRUE (1<<12) +#define NV_RAMDAC_PLL_SELECT_VS_PCLK_TV_NONE (0<<16) +#define NV_RAMDAC_PLL_SELECT_VS_PCLK_TV_VSCLK (1<<16) +#define NV_RAMDAC_PLL_SELECT_VS_PCLK_TV_PCLK (2<<16) +#define NV_RAMDAC_PLL_SELECT_VS_PCLK_TV_BOTH (3<<16) + +#define NV_RAMDAC_PLL_SELECT_TVCLK_SOURCE_EXT (0<<20) +#define NV_RAMDAC_PLL_SELECT_TVCLK_SOURCE_VIP (1<<20) + +#define NV_RAMDAC_PLL_SELECT_TVCLK_RATIO_DB1 (0<<24) +#define NV_RAMDAC_PLL_SELECT_TVCLK_RATIO_DB2 (1<<24) +#define NV_RAMDAC_PLL_SELECT_VCLK_RATIO_DB1 (0<<28) +#define NV_RAMDAC_PLL_SELECT_VCLK_RATIO_DB2 (1<<28) + + +#define NV_RAMDAC_PLL_SETUP_CONTROL 0x510 +#define NV_RAMDAC_PLL_TEST_COUNTER 0x514 +#define NV_RAMDAC_PALETTE_TEST 0x518 #define NV_RAMDAC_VPLL2 0x520 +#define NV_RAMDAC_SEL_CLK 0x524 #define NV_RAMDAC_DITHER_NV11 0x528 -#define NV_RAMDAC_052C 0x52c +#define NV_RAMDAC_OUTPUT 0x52c +#define NV_RAMDAC_OUTPUT_DAC_ENABLE (1<<0) +#define NV_RAMDAC_OUTPUT_SELECT_CRTC2 (1<<8) #define NV_RAMDAC_NVPLL_B 0x570 #define NV_RAMDAC_MPLL_B 0x574 @@ -154,14 +183,59 @@ #define NV_RAMDAC_TEST_CONTROL 0x608 #define NV_RAMDAC_TEST_DATA 0x610 +#define NV_RAMDAC_TV_SETUP 0x700 +#define NV_RAMDAC_TV_VBLANK_START 0x704 +#define NV_RAMDAC_TV_VBLANK_END 0x708 +#define NV_RAMDAC_TV_HBLANK_START 0x70c +#define NV_RAMDAC_TV_HBLANK_END 0x710 +#define NV_RAMDAC_TV_BLANK_COLOR 0x714 +#define NV_RAMDAC_TV_VTOTAL 0x720 +#define NV_RAMDAC_TV_VSYNC_START 0x724 +#define NV_RAMDAC_TV_VSYNC_END 0x728 +#define NV_RAMDAC_TV_HTOTAL 0x72c +#define NV_RAMDAC_TV_HSYNC_START 0x730 +#define NV_RAMDAC_TV_HSYNC_END 0x734 +#define NV_RAMDAC_TV_SYNC_DELAY 0x738 + +#define REG_DISP_END 0 +#define REG_DISP_TOTAL 1 +#define REG_DISP_CRTC 2 +#define REG_DISP_SYNC_START 3 +#define REG_DISP_SYNC_END 4 +#define REG_DISP_VALID_START 5 +#define REG_DISP_VALID_END 6 + #define NV_RAMDAC_FP_VDISP_END 0x800 +#define NV_RAMDAC_FP_VTOTAL 0x804 +#define NV_RAMDAC_FP_VCRTC 0x808 +#define NV_RAMDAC_FP_VSYNC_START 0x80c +#define NV_RAMDAC_FP_VSYNC_END 0x810 +#define NV_RAMDAC_FP_VVALID_START 0x814 +#define NV_RAMDAC_FP_VVALID_END 0x818 #define NV_RAMDAC_FP_HDISP_END 0x820 +#define NV_RAMDAC_FP_HTOTAL 0x824 #define NV_RAMDAC_FP_HCRTC 0x828 +#define NV_RAMDAC_FP_HSYNC_START 0x82c +#define NV_RAMDAC_FP_HSYNC_END 0x830 +#define NV_RAMDAC_FP_HVALID_START 0x834 +#define NV_RAMDAC_FP_HVALID_END 0x838 + #define NV_RAMDAC_FP_DITHER 0x83c +#define NV_RAMDAC_FP_CHECKSUM 0x840 +#define NV_RAMDAC_FP_TEST_CONTROL 0x844 #define NV_RAMDAC_FP_CONTROL 0x848 +#define NV_RAMDAC_FP_CONTROL_ENABLE (1<<28) // toggling this bit turns things on/off + +#define NV_RAMDAC_FP_DEBUG_0 0x880 +#define NV_RAMDAC_FP_DEBUG_0_PWRDOWN_FPCLK (1<<28) +#define NV_RAMDAC_FP_DEBUG_0_PWRDOWN_TMDS_PLL (2<<28) +#define NV_RAMDAC_FP_DEBUG_0_PWRDOWN_BOTH (3<<28) -#define NV_RAMDAC_FP_TMDS_DATA 0x8b0 -#define NV_RAMDAC_FP_TMDS_LVDS 0x8b4 +#define NV_RAMDAC_FP_TMDS_CONTROL 0x8b0 +/* 0xff - address mask */ +#define NV_RAMDAC_FP_TMDS_CONTROL_WRITE_DISABLE (1<<16) +#define NV_RAMDAC_FP_TMDS_DATA 0x8b4 +/* 0xff - data mask */ #define NV_CRTC_INTR_0 0x100 # define NV_CRTC_INTR_VBLANK 1 @@ -171,7 +245,13 @@ #define NV_CRTC_081C 0x81c #define NV_CRTC_0830 0x830 #define NV_CRTC_0834 0x834 -#define NV_CRTC_HEAD_CONFIG 0x860 +#define NV_CRTC_FSEL 0x860 +#define NV_CRTC_FSEL_I2C (1<<4) +#define NV_CRTC_FSEL_TVOUT1 (1<<8) +#define NV_CRTC_FSEL_TVOUT2 (2<<8) +#define NV_CRTC_FSEL_OVERLAY (1<<12) +#define NV_CRTC_FSEL_FPP2 (1<<16) +#define NV_CRTC_FSEL_FPP1 (2<<16) #define NV_PFB_CFG0 0x200 #define NV_PFB_CFG1 0x204 |