summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/Makefile.am12
-rw-r--r--src/i2c_vid.h16
-rw-r--r--src/local_xf86Rename.h23
-rw-r--r--src/nv50_cursor.c104
-rw-r--r--src/nv50_cursor.h12
-rw-r--r--src/nv50_dac.c199
-rw-r--r--src/nv50_display.c535
-rw-r--r--src/nv50_display.h22
-rw-r--r--src/nv50_exa.c254
-rw-r--r--src/nv50_output.c372
-rw-r--r--src/nv50_output.h34
-rw-r--r--src/nv50_sor.c152
-rw-r--r--src/nv50_type.h22
-rw-r--r--src/nv_accel_common.c82
-rw-r--r--src/nv_bios.c90
-rw-r--r--src/nv_crtc.c1436
-rw-r--r--src/nv_cursor.c76
-rw-r--r--src/nv_dac.c425
-rw-r--r--src/nv_dma.c81
-rw-r--r--src/nv_dma.h2
-rw-r--r--src/nv_driver.c3719
-rw-r--r--src/nv_exa.c46
-rw-r--r--src/nv_hw.c439
-rw-r--r--src/nv_i2c.c70
-rw-r--r--src/nv_include.h2
-rw-r--r--src/nv_local.h27
-rw-r--r--src/nv_output.c885
-rw-r--r--src/nv_proto.h63
-rw-r--r--src/nv_setup.c146
-rw-r--r--src/nv_type.h117
-rw-r--r--src/nv_xaa.c2
-rw-r--r--src/nv_xf86Rename.h66
-rw-r--r--src/nvreg.h90
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