2 * Copyright 2006 Dave Airlie
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
11 * The above copyright notice and this permission notice (including the next
12 * paragraph) shall be included in all copies or substantial portions of the
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20 * FROM, OUT OF OR IN CONNECT
23 * this code uses ideas taken from the NVIDIA nv driver - the nvidia license
24 * decleration is at the bottom of this file as it is rather ugly
40 #include "mipointer.h"
41 #include "windowstr.h"
43 #include <X11/extensions/render.h>
46 #include "nv_include.h"
50 #define CRTC_INDEX 0x3d4
51 #define CRTC_DATA 0x3d5
52 #define CRTC_IN_STAT_1 0x3da
54 #define WHITE_VALUE 0x3F
55 #define BLACK_VALUE 0x00
56 #define OVERSCAN_VALUE 0x01
58 static void nv_crtc_load_state_vga(xf86CrtcPtr crtc, RIVA_HW_STATE *state);
59 static void nv_crtc_load_state_ext (xf86CrtcPtr crtc, RIVA_HW_STATE *state);
60 static void nv_crtc_save_state_ext(xf86CrtcPtr crtc, RIVA_HW_STATE *state);
61 static void nv_crtc_save_state_vga(xf86CrtcPtr crtc, RIVA_HW_STATE *state);
63 static void NVWriteMiscOut(xf86CrtcPtr crtc, CARD8 value)
65 ScrnInfoPtr pScrn = crtc->scrn;
66 NVCrtcPrivatePtr nv_crtc = crtc->driver_private;
67 NVPtr pNv = NVPTR(pScrn);
69 NV_WR08(pNv->PVIO, VGA_MISC_OUT_W, value);
72 static CARD8 NVReadMiscOut(xf86CrtcPtr crtc)
74 ScrnInfoPtr pScrn = crtc->scrn;
75 NVCrtcPrivatePtr nv_crtc = crtc->driver_private;
76 NVPtr pNv = NVPTR(pScrn);
78 return NV_RD08(pNv->PVIO, VGA_MISC_OUT_R);
82 static void NVWriteVgaCrtc(xf86CrtcPtr crtc, CARD8 index, CARD8 value)
84 ScrnInfoPtr pScrn = crtc->scrn;
85 NVCrtcPrivatePtr nv_crtc = crtc->driver_private;
86 NVPtr pNv = NVPTR(pScrn);
87 volatile CARD8 *pCRTCReg = nv_crtc->crtc ? pNv->PCIO1 : pNv->PCIO0;
89 NV_WR08(pCRTCReg, CRTC_INDEX, index);
90 NV_WR08(pCRTCReg, CRTC_DATA, value);
93 static CARD8 NVReadVgaCrtc(xf86CrtcPtr crtc, CARD8 index)
95 ScrnInfoPtr pScrn = crtc->scrn;
96 NVCrtcPrivatePtr nv_crtc = crtc->driver_private;
97 NVPtr pNv = NVPTR(pScrn);
98 volatile CARD8 *pCRTCReg = nv_crtc->crtc ? pNv->PCIO1 : pNv->PCIO0;
100 NV_WR08(pCRTCReg, CRTC_INDEX, index);
101 return NV_RD08(pCRTCReg, CRTC_DATA);
104 static void NVWriteVgaSeq(xf86CrtcPtr crtc, CARD8 index, CARD8 value)
106 ScrnInfoPtr pScrn = crtc->scrn;
107 NVCrtcPrivatePtr nv_crtc = crtc->driver_private;
108 NVPtr pNv = NVPTR(pScrn);
110 NV_WR08(pNv->PVIO, VGA_SEQ_INDEX, index);
111 NV_WR08(pNv->PVIO, VGA_SEQ_DATA, value);
114 static CARD8 NVReadVgaSeq(xf86CrtcPtr crtc, CARD8 index)
116 ScrnInfoPtr pScrn = crtc->scrn;
117 NVCrtcPrivatePtr nv_crtc = crtc->driver_private;
118 NVPtr pNv = NVPTR(pScrn);
119 volatile CARD8 *pVGAReg = pNv->PVIO;
121 NV_WR08(pNv->PVIO, VGA_SEQ_INDEX, index);
122 return NV_RD08(pNv->PVIO, VGA_SEQ_DATA);
125 static void NVWriteVgaGr(xf86CrtcPtr crtc, CARD8 index, CARD8 value)
127 ScrnInfoPtr pScrn = crtc->scrn;
128 NVCrtcPrivatePtr nv_crtc = crtc->driver_private;
129 NVPtr pNv = NVPTR(pScrn);
131 NV_WR08(pNv->PVIO, VGA_GRAPH_INDEX, index);
132 NV_WR08(pNv->PVIO, VGA_GRAPH_DATA, value);
135 static CARD8 NVReadVgaGr(xf86CrtcPtr crtc, CARD8 index)
137 ScrnInfoPtr pScrn = crtc->scrn;
138 NVCrtcPrivatePtr nv_crtc = crtc->driver_private;
139 NVPtr pNv = NVPTR(pScrn);
140 volatile CARD8 *pVGAReg = pNv->PVIO;
142 NV_WR08(pVGAReg, VGA_GRAPH_INDEX, index);
143 return NV_RD08(pVGAReg, VGA_GRAPH_DATA);
147 static void NVWriteVgaAttr(xf86CrtcPtr crtc, CARD8 index, CARD8 value)
149 ScrnInfoPtr pScrn = crtc->scrn;
150 NVCrtcPrivatePtr nv_crtc = crtc->driver_private;
151 NVPtr pNv = NVPTR(pScrn);
152 volatile CARD8 *pCRTCReg = nv_crtc->crtc ? pNv->PCIO1 : pNv->PCIO0;
154 NV_RD08(pCRTCReg, CRTC_IN_STAT_1);
155 if (nv_crtc->paletteEnabled)
159 NV_WR08(pCRTCReg, VGA_ATTR_INDEX, index);
160 NV_WR08(pCRTCReg, VGA_ATTR_DATA_W, value);
163 static CARD8 NVReadVgaAttr(xf86CrtcPtr crtc, CARD8 index)
165 ScrnInfoPtr pScrn = crtc->scrn;
166 NVCrtcPrivatePtr nv_crtc = crtc->driver_private;
167 NVPtr pNv = NVPTR(pScrn);
168 volatile CARD8 *pCRTCReg = nv_crtc->crtc ? pNv->PCIO1 : pNv->PCIO0;
170 NV_RD08(pCRTCReg, CRTC_IN_STAT_1);
171 if (nv_crtc->paletteEnabled)
175 NV_WR08(pCRTCReg, VGA_ATTR_INDEX, index);
176 return NV_RD08(pCRTCReg, VGA_ATTR_DATA_R);
179 void NVCrtcSetOwner(xf86CrtcPtr crtc)
181 NVCrtcPrivatePtr nv_crtc = crtc->driver_private;
182 /*TODO beos double writes this on nv11 */
183 NVWriteVgaCrtc(crtc, NV_VGA_CRTCX_OWNER, nv_crtc->crtc * 0x3);
187 NVEnablePalette(xf86CrtcPtr crtc)
189 ScrnInfoPtr pScrn = crtc->scrn;
190 NVCrtcPrivatePtr nv_crtc = crtc->driver_private;
191 NVPtr pNv = NVPTR(pScrn);
192 volatile CARD8 *pCRTCReg = nv_crtc->crtc ? pNv->PCIO1 : pNv->PCIO0;
194 NV_RD08(pCRTCReg, CRTC_IN_STAT_1);
195 NV_WR08(pCRTCReg, VGA_ATTR_INDEX, 0);
196 nv_crtc->paletteEnabled = TRUE;
200 NVDisablePalette(xf86CrtcPtr crtc)
202 ScrnInfoPtr pScrn = crtc->scrn;
203 NVCrtcPrivatePtr nv_crtc = crtc->driver_private;
204 NVPtr pNv = NVPTR(pScrn);
205 volatile CARD8 *pCRTCReg = nv_crtc->crtc ? pNv->PCIO1 : pNv->PCIO0;
207 NV_RD08(pCRTCReg, CRTC_IN_STAT_1);
208 NV_WR08(pCRTCReg, VGA_ATTR_INDEX, 0x20);
209 nv_crtc->paletteEnabled = FALSE;
212 static void NVWriteVgaReg(xf86CrtcPtr crtc, CARD32 reg, CARD8 value)
214 ScrnInfoPtr pScrn = crtc->scrn;
215 NVCrtcPrivatePtr nv_crtc = crtc->driver_private;
216 NVPtr pNv = NVPTR(pScrn);
217 volatile CARD8 *pCRTCReg = nv_crtc->crtc ? pNv->PCIO1 : pNv->PCIO0;
219 NV_WR08(pCRTCReg, reg, value);
222 /* perform a sequencer reset */
223 static void NVVgaSeqReset(xf86CrtcPtr crtc, Bool start)
226 NVWriteVgaSeq(crtc, 0x00, 0x1);
228 NVWriteVgaSeq(crtc, 0x00, 0x3);
231 static void NVVgaProtect(xf86CrtcPtr crtc, Bool on)
236 tmp = NVReadVgaSeq(crtc, 0x1);
237 NVVgaSeqReset(crtc, TRUE);
238 NVWriteVgaSeq(crtc, 0x01, tmp | 0x20);
240 NVEnablePalette(crtc);
243 * Reenable sequencer, then turn on screen.
245 tmp = NVReadVgaSeq(crtc, 0x1);
246 NVWriteVgaSeq(crtc, 0x01, tmp & ~0x20); /* reenable display */
247 NVVgaSeqReset(crtc, FALSE);
249 NVDisablePalette(crtc);
253 void NVCrtcLockUnlock(xf86CrtcPtr crtc, Bool Lock)
257 NVWriteVgaCrtc(crtc, NV_VGA_CRTCX_LOCK, Lock ? 0x99 : 0x57);
258 cr11 = NVReadVgaCrtc(crtc, NV_VGA_CRTCX_VSYNCE);
259 if (Lock) cr11 |= 0x80;
261 NVWriteVgaCrtc(crtc, NV_VGA_CRTCX_VSYNCE, cr11);
264 * Calculate the Video Clock parameters for the PLL.
266 static void CalcVClock (
273 unsigned lowM, highM;
274 unsigned DeltaNew, DeltaOld;
278 DeltaOld = 0xFFFFFFFF;
280 VClk = (unsigned)clockIn;
282 if (pNv->CrystalFreqKHz == 13500) {
290 for (P = 0; P <= 4; P++) {
292 if ((Freq >= 128000) && (Freq <= 350000)) {
293 for (M = lowM; M <= highM; M++) {
294 N = ((VClk << P) * M) / pNv->CrystalFreqKHz;
296 Freq = ((pNv->CrystalFreqKHz * N) / M) >> P;
298 DeltaNew = Freq - VClk;
300 DeltaNew = VClk - Freq;
301 if (DeltaNew < DeltaOld) {
302 *pllOut = (P << 16) | (N << 8) | M;
312 static void CalcVClock2Stage (
320 unsigned DeltaNew, DeltaOld;
324 DeltaOld = 0xFFFFFFFF;
326 *pllBOut = 0x80000401; /* fixed at x4 for now */
328 VClk = (unsigned)clockIn;
330 for (P = 0; P <= 6; P++) {
332 if ((Freq >= 400000) && (Freq <= 1000000)) {
333 for (M = 1; M <= 13; M++) {
334 N = ((VClk << P) * M) / (pNv->CrystalFreqKHz << 2);
335 if((N >= 5) && (N <= 255)) {
336 Freq = (((pNv->CrystalFreqKHz << 2) * N) / M) >> P;
338 DeltaNew = Freq - VClk;
340 DeltaNew = VClk - Freq;
341 if (DeltaNew < DeltaOld) {
342 *pllOut = (P << 16) | (N << 8) | M;
352 static void nv_crtc_save_state_pll(NVPtr pNv, RIVA_HW_STATE *state)
354 state->vpll = nvReadRAMDAC0(pNv, NV_RAMDAC_VPLL);
356 state->vpll2 = nvReadRAMDAC0(pNv, NV_RAMDAC_VPLL2);
357 if(pNv->twoStagePLL) {
358 state->vpllB = nvReadRAMDAC0(pNv, NV_RAMDAC_VPLL_B);
359 state->vpll2B = nvReadRAMDAC0(pNv, NV_RAMDAC_VPLL2_B);
361 state->pllsel = nvReadRAMDAC0(pNv, NV_RAMDAC_PLL_SELECT);
365 static void nv_crtc_load_state_pll(NVPtr pNv, RIVA_HW_STATE *state)
367 nvWriteRAMDAC0(pNv, NV_RAMDAC_PLL_SELECT, state->pllsel);
369 ErrorF("writting vpll %08X\n", state->vpll);
370 ErrorF("writting vpll2 %08X\n", state->vpll2);
371 nvWriteRAMDAC0(pNv, NV_RAMDAC_VPLL, state->vpll);
373 nvWriteRAMDAC0(pNv, NV_RAMDAC_VPLL2, state->vpll2);
374 if(pNv->twoStagePLL) {
375 nvWriteRAMDAC0(pNv, NV_RAMDAC_VPLL_B, state->vpllB);
376 nvWriteRAMDAC0(pNv, NV_RAMDAC_VPLL2_B, state->vpll2B);
381 * Calculate extended mode parameters (SVGA) and save in a
382 * mode state structure.
384 void nv_crtc_calc_state_ext(
394 ScrnInfoPtr pScrn = crtc->scrn;
395 int pixelDepth, VClk;
397 NVCrtcPrivatePtr nv_crtc = crtc->driver_private;
398 xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
400 NVPtr pNv = NVPTR(pScrn);
401 RIVA_HW_STATE *state;
402 int num_crtc_enabled, i;
404 state = &pNv->ModeReg;
406 regp = &pNv->ModeReg.crtc_reg[nv_crtc->crtc];
409 * Extended RIVA registers.
411 pixelDepth = (bpp + 1)/8;
413 CalcVClock2Stage(dotClock, &VClk, &state->pll, &state->pllB, pNv);
415 CalcVClock(dotClock, &VClk, &state->pll, pNv);
417 switch (pNv->Architecture)
420 nv4UpdateArbitrationSettings(VClk,
422 &(state->arbitration0),
423 &(state->arbitration1),
425 regp->CRTC[NV_VGA_CRTCX_CURCTL0] = 0x00;
426 regp->CRTC[NV_VGA_CRTCX_CURCTL1] = 0xbC;
427 if (flags & V_DBLSCAN)
428 regp->CRTC[NV_VGA_CRTCX_CURCTL1] |= 2;
429 regp->CRTC[NV_VGA_CRTCX_CURCTL2] = 0x00000000;
430 state->pllsel |= NV_RAMDAC_PLL_SELECT_VCLK_RATIO_DB2 | NV_RAMDAC_PLL_SELECT_PLL_SOURCE_ALL;
431 state->config = 0x00001114;
432 regp->CRTC[NV_VGA_CRTCX_REPAINT1] = hDisplaySize < 1280 ? 0x04 : 0x00;
438 if(((pNv->Chipset & 0xfff0) == CHIPSET_C51) ||
439 ((pNv->Chipset & 0xfff0) == CHIPSET_C512))
441 state->arbitration0 = 128;
442 state->arbitration1 = 0x0480;
444 if(((pNv->Chipset & 0xffff) == CHIPSET_NFORCE) ||
445 ((pNv->Chipset & 0xffff) == CHIPSET_NFORCE2))
447 nForceUpdateArbitrationSettings(VClk,
449 &(state->arbitration0),
450 &(state->arbitration1),
452 } else if(pNv->Architecture < NV_ARCH_30) {
453 nv10UpdateArbitrationSettings(VClk,
455 &(state->arbitration0),
456 &(state->arbitration1),
459 nv30UpdateArbitrationSettings(pNv,
460 &(state->arbitration0),
461 &(state->arbitration1));
465 CursorStart = pNv->Cursor->offset;
467 regp->CRTC[NV_VGA_CRTCX_CURCTL0] = 0x80 | (CursorStart >> 17);
468 regp->CRTC[NV_VGA_CRTCX_CURCTL1] = (CursorStart >> 11) << 2;
469 regp->CRTC[NV_VGA_CRTCX_CURCTL2] = CursorStart >> 24;
471 if (flags & V_DBLSCAN)
472 regp->CRTC[NV_VGA_CRTCX_CURCTL1]|= 2;
475 state->config = nvReadFB(pNv, NV_PFB_CFG0);
476 regp->CRTC[NV_VGA_CRTCX_REPAINT1] = hDisplaySize < 1280 ? 0x04 : 0x00;
480 /* okay do we have 2 CRTCs running ? */
481 num_crtc_enabled = 0;
482 for (i = 0; i < xf86_config->num_crtc; i++) {
483 if (xf86_config->crtc[i]->enabled)
487 if (num_crtc_enabled > 1) {
488 if (nv_crtc->crtc == 1) {
489 state->vpll2 = state->pll;
490 state->vpll2B = state->pllB;
491 state->pllsel |= (1<<29) | (1<<11);
493 state->vpll = state->pll;
494 state->vpllB = state->pllB;
495 state->pllsel |= NV_RAMDAC_PLL_SELECT_PLL_SOURCE_ALL;
496 state->pllsel &= ~NV_RAMDAC_PLL_SELECT_VCLK_RATIO_DB2;
499 state->vpll = state->pll;
500 state->vpllB = state->pllB;
501 state->pllsel |= NV_RAMDAC_PLL_SELECT_PLL_SOURCE_ALL;
502 state->pllsel &= ~NV_RAMDAC_PLL_SELECT_VCLK_RATIO_DB2;
506 regp->CRTC[NV_VGA_CRTCX_FIFO0] = state->arbitration0;
507 regp->CRTC[NV_VGA_CRTCX_FIFO_LWM] = state->arbitration1 & 0xff;
508 if (pNv->Architecture >= NV_ARCH_30) {
509 regp->CRTC[NV_VGA_CRTCX_FIFO_LWM_NV30] = state->arbitration1 >> 8;
513 regp->CRTC[NV_VGA_CRTCX_REPAINT0] = (((width / 8) * pixelDepth) & 0x700) >> 3;
514 regp->CRTC[NV_VGA_CRTCX_PIXEL] = (pixelDepth > 2) ? 3 : pixelDepth;
519 nv_crtc_dpms(xf86CrtcPtr crtc, int mode)
521 NVCrtcPrivatePtr nv_crtc = crtc->driver_private;
522 unsigned char seq1 = 0, crtc17 = 0;
523 unsigned char crtc1A;
525 Bool crtc_is_on = FALSE;
527 NVCrtcSetOwner(crtc);
529 crtc1A = NVReadVgaCrtc(crtc, NV_VGA_CRTCX_REPAINT1) & ~0xC0;
531 case DPMSModeStandby:
532 /* Screen: Off; HSync: Off, VSync: On -- Not Supported */
537 case DPMSModeSuspend:
538 /* Screen: Off; HSync: On, VSync: Off -- Not Supported */
544 /* Screen: Off; HSync: Off, VSync: Off */
551 /* Screen: On; HSync: On, VSync: On */
558 NVWriteVgaSeq(crtc, 0x00, 0x1);
559 seq1 = NVReadVgaSeq(crtc, 0x01) & ~0x20;
560 NVWriteVgaSeq(crtc, 0x1, seq1);
561 crtc17 |= NVReadVgaCrtc(crtc, NV_VGA_CRTCX_MODECTL) & ~0x80;
563 NVWriteVgaCrtc(crtc, NV_VGA_CRTCX_MODECTL, crtc17);
564 NVWriteVgaSeq(crtc, 0x0, 0x3);
566 NVWriteVgaCrtc(crtc, NV_VGA_CRTCX_REPAINT1, crtc1A);
568 /* This is usefull for Xv NVWaitVSync() */
569 nv_crtc->pNv->crtc_active[nv_crtc->crtc] = crtc_is_on;
573 nv_crtc_mode_fixup(xf86CrtcPtr crtc, DisplayModePtr mode,
574 DisplayModePtr adjusted_mode)
580 nv_crtc_mode_set_vga(xf86CrtcPtr crtc, DisplayModePtr mode)
582 ScrnInfoPtr pScrn = crtc->scrn;
583 NVCrtcPrivatePtr nv_crtc = crtc->driver_private;
585 NVPtr pNv = NVPTR(pScrn);
586 int depth = pScrn->depth;
589 regp = &pNv->ModeReg.crtc_reg[nv_crtc->crtc];
593 * compute correct Hsync & Vsync polarity
595 if ((mode->Flags & (V_PHSYNC | V_NHSYNC))
596 && (mode->Flags & (V_PVSYNC | V_NVSYNC)))
598 regp->MiscOutReg = 0x23;
599 if (mode->Flags & V_NHSYNC) regp->MiscOutReg |= 0x40;
600 if (mode->Flags & V_NVSYNC) regp->MiscOutReg |= 0x80;
604 int VDisplay = mode->VDisplay;
605 if (mode->Flags & V_DBLSCAN)
608 VDisplay *= mode->VScan;
610 regp->MiscOutReg = 0xA3; /* +hsync -vsync */
611 else if (VDisplay < 480)
612 regp->MiscOutReg = 0x63; /* -hsync +vsync */
613 else if (VDisplay < 768)
614 regp->MiscOutReg = 0xE3; /* -hsync -vsync */
616 regp->MiscOutReg = 0x23; /* +hsync +vsync */
619 regp->MiscOutReg |= (mode->ClockIndex & 0x03) << 2;
625 regp->Sequencer[0] = 0x02;
627 regp->Sequencer[0] = 0x00;
628 if (mode->Flags & V_CLKDIV2)
629 regp->Sequencer[1] = 0x09;
631 regp->Sequencer[1] = 0x01;
633 regp->Sequencer[2] = 1 << BIT_PLANE;
635 regp->Sequencer[2] = 0x0F;
636 regp->Sequencer[3] = 0x00; /* Font select */
638 regp->Sequencer[4] = 0x06; /* Misc */
640 regp->Sequencer[4] = 0x0E; /* Misc */
645 regp->CRTC[0] = (mode->CrtcHTotal >> 3) - 5;
646 regp->CRTC[1] = (mode->CrtcHDisplay >> 3) - 1;
647 regp->CRTC[2] = (mode->CrtcHBlankStart >> 3) - 1;
648 regp->CRTC[3] = (((mode->CrtcHBlankEnd >> 3) - 1) & 0x1F) | 0x80;
649 i = (((mode->CrtcHSkew << 2) + 0x10) & ~0x1F);
652 regp->CRTC[4] = (mode->CrtcHSyncStart >> 3);
653 regp->CRTC[5] = ((((mode->CrtcHBlankEnd >> 3) - 1) & 0x20) << 2)
654 | (((mode->CrtcHSyncEnd >> 3)) & 0x1F);
655 regp->CRTC[6] = (mode->CrtcVTotal - 2) & 0xFF;
656 regp->CRTC[7] = (((mode->CrtcVTotal - 2) & 0x100) >> 8)
657 | (((mode->CrtcVDisplay - 1) & 0x100) >> 7)
658 | ((mode->CrtcVSyncStart & 0x100) >> 6)
659 | (((mode->CrtcVBlankStart - 1) & 0x100) >> 5)
661 | (((mode->CrtcVTotal - 2) & 0x200) >> 4)
662 | (((mode->CrtcVDisplay - 1) & 0x200) >> 3)
663 | ((mode->CrtcVSyncStart & 0x200) >> 2);
664 regp->CRTC[8] = 0x00;
665 regp->CRTC[9] = (((mode->CrtcVBlankStart - 1) & 0x200) >> 4) | 0x40;
666 if (mode->Flags & V_DBLSCAN)
667 regp->CRTC[9] |= 0x80;
668 if (mode->VScan >= 32)
669 regp->CRTC[9] |= 0x1F;
670 else if (mode->VScan > 1)
671 regp->CRTC[9] |= mode->VScan - 1;
672 regp->CRTC[10] = 0x00;
673 regp->CRTC[11] = 0x00;
674 regp->CRTC[12] = 0x00;
675 regp->CRTC[13] = 0x00;
676 regp->CRTC[14] = 0x00;
677 regp->CRTC[15] = 0x00;
678 regp->CRTC[16] = mode->CrtcVSyncStart & 0xFF;
679 regp->CRTC[17] = (mode->CrtcVSyncEnd & 0x0F) | 0x20;
680 regp->CRTC[18] = (mode->CrtcVDisplay - 1) & 0xFF;
681 regp->CRTC[19] = mode->CrtcHDisplay >> 4; /* just a guess */
682 regp->CRTC[20] = 0x00;
683 regp->CRTC[21] = (mode->CrtcVBlankStart - 1) & 0xFF;
684 regp->CRTC[22] = (mode->CrtcVBlankEnd - 1) & 0xFF;
686 regp->CRTC[23] = 0xE3;
688 regp->CRTC[23] = 0xC3;
689 regp->CRTC[24] = 0xFF;
692 * Theory resumes here....
696 * Graphics Display Controller
698 regp->Graphics[0] = 0x00;
699 regp->Graphics[1] = 0x00;
700 regp->Graphics[2] = 0x00;
701 regp->Graphics[3] = 0x00;
703 regp->Graphics[4] = BIT_PLANE;
704 regp->Graphics[5] = 0x00;
706 regp->Graphics[4] = 0x00;
708 regp->Graphics[5] = 0x02;
710 regp->Graphics[5] = 0x40;
712 regp->Graphics[6] = 0x05; /* only map 64k VGA memory !!!! */
713 regp->Graphics[7] = 0x0F;
714 regp->Graphics[8] = 0xFF;
717 /* Initialise the Mono map according to which bit-plane gets used */
719 Bool flipPixels = xf86GetFlipPixels();
722 if (((i & (1 << BIT_PLANE)) != 0) != flipPixels)
723 regp->Attribute[i] = WHITE_VALUE;
725 regp->Attribute[i] = BLACK_VALUE;
728 regp->Attribute[0] = 0x00; /* standard colormap translation */
729 regp->Attribute[1] = 0x01;
730 regp->Attribute[2] = 0x02;
731 regp->Attribute[3] = 0x03;
732 regp->Attribute[4] = 0x04;
733 regp->Attribute[5] = 0x05;
734 regp->Attribute[6] = 0x06;
735 regp->Attribute[7] = 0x07;
736 regp->Attribute[8] = 0x08;
737 regp->Attribute[9] = 0x09;
738 regp->Attribute[10] = 0x0A;
739 regp->Attribute[11] = 0x0B;
740 regp->Attribute[12] = 0x0C;
741 regp->Attribute[13] = 0x0D;
742 regp->Attribute[14] = 0x0E;
743 regp->Attribute[15] = 0x0F;
745 regp->Attribute[16] = 0x81; /* wrong for the ET4000 */
747 regp->Attribute[16] = 0x41; /* wrong for the ET4000 */
749 regp->Attribute[17] = 0xff;
750 /* Attribute[17] (overscan) initialised in vgaHWGetHWRec() */
752 regp->Attribute[18] = 0x0F;
753 regp->Attribute[19] = 0x00;
754 regp->Attribute[20] = 0x00;
758 /* This should accomodate up to 65535x65535 */
759 #define NOUVEAU_RES(_h_res, _v_res) ((_h_res << 16) | _v_res)
761 /* These are timing modes for DFP's */
762 /* These are not neccesarily correct, just our best guess */
763 struct timing_modes {
768 {NOUVEAU_RES(1024, 768), 0x40, 0x00},
769 {NOUVEAU_RES(1280, 1024), 0x0a, 0x02},
770 {NOUVEAU_RES(1680, 1050), 0x00, 0x00},
771 {NOUVEAU_RES(2560, 1600), 0x00, 0x00},
777 * Sets up registers for the given mode/adjusted_mode pair.
779 * The clocks, CRTCs and outputs attached to this CRTC must be off.
781 * This shouldn't enable any clocks, CRTCs, or outputs, but they should
782 * be easily turned on/off after this.
785 nv_crtc_mode_set_regs(xf86CrtcPtr crtc, DisplayModePtr mode)
787 ScrnInfoPtr pScrn = crtc->scrn;
788 NVPtr pNv = NVPTR(pScrn);
789 NVRegPtr state = &pNv->ModeReg;
790 xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
791 NVCrtcPrivatePtr nv_crtc = crtc->driver_private;
792 NVFBLayout *pLayout = &pNv->CurrentLayout;
793 NVCrtcRegPtr regp, savep;
795 int horizDisplay = (mode->CrtcHDisplay/8) - 1;
796 int horizStart = (mode->CrtcHSyncStart/8) - 1;
797 int horizEnd = (mode->CrtcHSyncEnd/8) - 1;
798 int horizTotal = (mode->CrtcHTotal/8) - 5;
799 int horizBlankStart = (mode->CrtcHDisplay/8) - 1;
800 int horizBlankEnd = (mode->CrtcHTotal/8) - 1;
801 int vertDisplay = mode->CrtcVDisplay - 1;
802 int vertStart = mode->CrtcVSyncStart - 1;
803 int vertEnd = mode->CrtcVSyncEnd - 1;
804 int vertTotal = mode->CrtcVTotal - 2;
805 int vertBlankStart = mode->CrtcVDisplay - 1;
806 int vertBlankEnd = mode->CrtcVTotal - 1;
807 /* What about vsync and hsync? */
810 for (i = 0; i < xf86_config->num_output; i++) {
811 xf86OutputPtr output = xf86_config->output[i];
812 NVOutputPrivatePtr nv_output = output->driver_private;
814 if (output->crtc == crtc) {
815 if ((nv_output->type == OUTPUT_PANEL) ||
816 (nv_output->type == OUTPUT_DIGITAL)) {
823 regp = &pNv->ModeReg.crtc_reg[nv_crtc->crtc];
824 savep = &pNv->SavedReg.crtc_reg[nv_crtc->crtc];
826 if(mode->Flags & V_INTERLACE)
829 regp->CRTC[NV_VGA_CRTCX_HTOTAL] = Set8Bits(horizTotal);
830 regp->CRTC[NV_VGA_CRTCX_HDISPE] = Set8Bits(horizDisplay);
831 regp->CRTC[NV_VGA_CRTCX_HBLANKS] = Set8Bits(horizBlankStart);
832 regp->CRTC[NV_VGA_CRTCX_HBLANKE] = SetBitField(horizBlankEnd,4:0,4:0)
834 regp->CRTC[NV_VGA_CRTCX_HSYNCS] = Set8Bits(horizStart);
835 regp->CRTC[NV_VGA_CRTCX_HSYNCE] = SetBitField(horizBlankEnd,5:5,7:7)
836 | SetBitField(horizEnd,4:0,4:0);
837 regp->CRTC[NV_VGA_CRTCX_VTOTAL] = SetBitField(vertTotal,7:0,7:0);
838 regp->CRTC[NV_VGA_CRTCX_OVERFLOW] = SetBitField(vertTotal,8:8,0:0)
839 | SetBitField(vertDisplay,8:8,1:1)
840 | SetBitField(vertStart,8:8,2:2)
841 | SetBitField(vertBlankStart,8:8,3:3)
843 | SetBitField(vertTotal,9:9,5:5)
844 | SetBitField(vertDisplay,9:9,6:6)
845 | SetBitField(vertStart,9:9,7:7);
846 regp->CRTC[NV_VGA_CRTCX_MAXSCLIN] = SetBitField(vertBlankStart,9:9,5:5)
848 | ((mode->Flags & V_DBLSCAN) ? 0x80 : 0x00);
849 regp->CRTC[NV_VGA_CRTCX_VSYNCS] = Set8Bits(vertStart);
850 regp->CRTC[NV_VGA_CRTCX_VSYNCE] = SetBitField(vertEnd,3:0,3:0) | SetBit(5);
851 regp->CRTC[NV_VGA_CRTCX_VDISPE] = Set8Bits(vertDisplay);
852 regp->CRTC[NV_VGA_CRTCX_PITCHL] = ((pLayout->displayWidth/8)*(pLayout->bitsPerPixel/8));
853 regp->CRTC[NV_VGA_CRTCX_VBLANKS] = Set8Bits(vertBlankStart);
854 regp->CRTC[NV_VGA_CRTCX_VBLANKE] = Set8Bits(vertBlankEnd);
856 regp->Attribute[0x10] = 0x01;
859 regp->Attribute[0x11] = 0x00;
861 regp->CRTC[NV_VGA_CRTCX_LSR] = SetBitField(horizBlankEnd,6:6,4:4)
862 | SetBitField(vertBlankStart,10:10,3:3)
863 | SetBitField(vertStart,10:10,2:2)
864 | SetBitField(vertDisplay,10:10,1:1)
865 | SetBitField(vertTotal,10:10,0:0);
867 regp->CRTC[NV_VGA_CRTCX_HEB] = SetBitField(horizTotal,8:8,0:0)
868 | SetBitField(horizDisplay,8:8,1:1)
869 | SetBitField(horizBlankStart,8:8,2:2)
870 | SetBitField(horizStart,8:8,3:3);
872 regp->CRTC[NV_VGA_CRTCX_EXTRA] = SetBitField(vertTotal,11:11,0:0)
873 | SetBitField(vertDisplay,11:11,2:2)
874 | SetBitField(vertStart,11:11,4:4)
875 | SetBitField(vertBlankStart,11:11,6:6);
877 if(mode->Flags & V_INTERLACE) {
878 horizTotal = (horizTotal >> 1) & ~1;
879 regp->CRTC[NV_VGA_CRTCX_INTERLACE] = Set8Bits(horizTotal);
880 regp->CRTC[NV_VGA_CRTCX_HEB] |= SetBitField(horizTotal,8:8,4:4);
882 regp->CRTC[NV_VGA_CRTCX_INTERLACE] = 0xff; /* interlace off */
885 regp->CRTC[NV_VGA_CRTCX_BUFFER] = 0xfa;
888 regp->CRTC[NV_VGA_CRTCX_LCD] = savep->CRTC[NV_VGA_CRTCX_LCD] | 1;
889 /* this turns on the DFP on nv28 outputs */
890 regp->CRTC[NV_VGA_CRTCX_59] = savep->CRTC[NV_VGA_CRTCX_59] | 1;
892 regp->CRTC[NV_VGA_CRTCX_LCD] = savep->CRTC[NV_VGA_CRTCX_LCD] & ~1;
896 * Initialize DAC palette.
898 if(pLayout->bitsPerPixel != 8 ) {
899 for (i = 0; i < 256; i++) {
901 regp->DAC[(i*3)+1] = i;
902 regp->DAC[(i*3)+2] = i;
907 * Calculate the extended registers.
910 if(pLayout->depth < 24) {
916 if(pNv->Architecture >= NV_ARCH_10) {
917 pNv->CURSOR = (CARD32 *)pNv->Cursor->map;
920 ErrorF("crtc %d %d %d\n", nv_crtc->crtc, mode->CrtcHDisplay, pLayout->displayWidth);
921 nv_crtc_calc_state_ext(crtc,
923 pLayout->displayWidth,
930 regp->CRTC[NV_VGA_CRTCX_PIXEL] |= (1 << 7);
933 regp->CRTC[NV_VGA_CRTCX_FIFO1] = savep->CRTC[NV_VGA_CRTCX_FIFO1] & ~(1<<5);
937 regp->head &= ~NV_CRTC_FSEL_FPP2;
938 regp->head |= NV_CRTC_FSEL_FPP1;
940 regp->head &= ~NV_CRTC_FSEL_FPP1;
941 regp->head |= NV_CRTC_FSEL_FPP2;
945 /* only enable secondary pllsel if CRTC 1 is selected on */
947 /* Maybe use pNv->crtc_active[1], or is it too early for that? */
949 regp->head = savep->head | 0x00001000;
951 regp->head &= ~NV_CRTC_FSEL_FPP2;
952 regp->head |= NV_CRTC_FSEL_FPP1;
954 regp->head &= ~NV_CRTC_FSEL_FPP1;
955 regp->head |= NV_CRTC_FSEL_FPP2;
962 regp->cursorConfig = 0x00000100;
963 if(mode->Flags & V_DBLSCAN)
964 regp->cursorConfig |= (1 << 4);
965 if(pNv->alphaCursor) {
966 if((pNv->Chipset & 0x0ff0) != CHIPSET_NV11) {
967 regp->cursorConfig |= 0x04011000;
969 regp->cursorConfig |= 0x14011000;
972 regp->cursorConfig |= 0x02000000;
975 regp->CRTC[NV_VGA_CRTCX_FP_HTIMING] = 0;
976 regp->CRTC[NV_VGA_CRTCX_FP_VTIMING] = 0;
978 regp->unk830 = mode->CrtcVDisplay - 3;
979 regp->unk834 = mode->CrtcVDisplay - 1;
983 * Sets up registers for the given mode/adjusted_mode pair.
985 * The clocks, CRTCs and outputs attached to this CRTC must be off.
987 * This shouldn't enable any clocks, CRTCs, or outputs, but they should
988 * be easily turned on/off after this.
991 nv_crtc_mode_set(xf86CrtcPtr crtc, DisplayModePtr mode,
992 DisplayModePtr adjusted_mode,
995 ScrnInfoPtr pScrn = crtc->scrn;
996 NVCrtcPrivatePtr nv_crtc = crtc->driver_private;
997 NVPtr pNv = NVPTR(pScrn);
999 xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "Mode on CRTC %d\n", nv_crtc->crtc);
1000 xf86PrintModeline(pScrn->scrnIndex, mode);
1001 NVCrtcSetOwner(crtc);
1003 nv_crtc_mode_set_vga(crtc, mode);
1004 nv_crtc_mode_set_regs(crtc, mode);
1007 NVVgaProtect(crtc, TRUE);
1008 nv_crtc_load_state_ext(crtc, &pNv->ModeReg);
1009 nv_crtc_load_state_vga(crtc, &pNv->ModeReg);
1010 nv_crtc_load_state_pll(pNv, &pNv->ModeReg);
1012 NVVgaProtect(crtc, FALSE);
1013 // NVCrtcLockUnlock(crtc, 1);
1015 NVCrtcSetBase(crtc, x, y);
1016 #if X_BYTE_ORDER == X_BIG_ENDIAN
1017 /* turn on LFB swapping */
1021 tmp = NVReadVgaCrtc(crtc, NV_VGA_CRTCX_SWAPPING);
1023 NVWriteVgaCrtc(crtc, NV_VGA_CRTCX_SWAPPING, tmp);
1029 void nv_crtc_save(xf86CrtcPtr crtc)
1031 ScrnInfoPtr pScrn = crtc->scrn;
1032 NVCrtcPrivatePtr nv_crtc = crtc->driver_private;
1033 NVPtr pNv = NVPTR(pScrn);
1035 NVCrtcSetOwner(crtc);
1036 nv_crtc_save_state_pll(pNv, &pNv->SavedReg);
1037 nv_crtc_save_state_vga(crtc, &pNv->SavedReg);
1038 nv_crtc_save_state_ext(crtc, &pNv->SavedReg);
1042 void nv_crtc_restore(xf86CrtcPtr crtc)
1044 ScrnInfoPtr pScrn = crtc->scrn;
1045 NVCrtcPrivatePtr nv_crtc = crtc->driver_private;
1046 NVPtr pNv = NVPTR(pScrn);
1048 NVCrtcSetOwner(crtc);
1049 nv_crtc_load_state_ext(crtc, &pNv->SavedReg);
1050 nv_crtc_load_state_vga(crtc, &pNv->SavedReg);
1051 nv_crtc_load_state_pll(pNv, &pNv->SavedReg);
1052 nvWriteVGA(pNv, NV_VGA_CRTCX_OWNER, pNv->vtOWNER);
1056 void nv_crtc_prepare(xf86CrtcPtr crtc)
1058 ScrnInfoPtr pScrn = crtc->scrn;
1059 NVPtr pNv = NVPTR(pScrn);
1061 /* Sync the engine before adjust mode */
1062 if (pNv->EXADriverPtr) {
1063 exaMarkSync(pScrn->pScreen);
1064 exaWaitSync(pScrn->pScreen);
1068 void nv_crtc_commit(xf86CrtcPtr crtc)
1074 static Bool nv_crtc_lock(xf86CrtcPtr crtc)
1079 static void nv_crtc_unlock(xf86CrtcPtr crtc)
1084 static const xf86CrtcFuncsRec nv_crtc_funcs = {
1085 .dpms = nv_crtc_dpms,
1086 .save = nv_crtc_save, /* XXX */
1087 .restore = nv_crtc_restore, /* XXX */
1088 .mode_fixup = nv_crtc_mode_fixup,
1089 .mode_set = nv_crtc_mode_set,
1090 .prepare = nv_crtc_prepare,
1091 .commit = nv_crtc_commit,
1092 .destroy = NULL, /* XXX */
1093 .lock = nv_crtc_lock,
1094 .unlock = nv_crtc_unlock,
1098 nv_crtc_init(ScrnInfoPtr pScrn, int crtc_num)
1100 NVPtr pNv = NVPTR(pScrn);
1102 NVCrtcPrivatePtr nv_crtc;
1104 crtc = xf86CrtcCreate (pScrn, &nv_crtc_funcs);
1108 nv_crtc = xnfcalloc (sizeof (NVCrtcPrivateRec), 1);
1109 nv_crtc->crtc = crtc_num;
1110 /* This is usefull to do stuff from crtc functions */
1113 crtc->driver_private = nv_crtc;
1115 NVCrtcLockUnlock(crtc, 0);
1119 static void nv_crtc_load_state_vga(xf86CrtcPtr crtc, RIVA_HW_STATE *state)
1121 ScrnInfoPtr pScrn = crtc->scrn;
1122 NVPtr pNv = NVPTR(pScrn);
1123 NVCrtcPrivatePtr nv_crtc = crtc->driver_private;
1128 regp = &state->crtc_reg[nv_crtc->crtc];
1130 NVWriteMiscOut(crtc, regp->MiscOutReg);
1132 for (i = 1; i < 5; i++)
1133 NVWriteVgaSeq(crtc, i, regp->Sequencer[i]);
1135 /* Ensure CRTC registers 0-7 are unlocked by clearing bit 7 of CRTC[17] */
1136 NVWriteVgaCrtc(crtc, 17, regp->CRTC[17] & ~0x80);
1138 for (i = 0; i < 25; i++)
1139 NVWriteVgaCrtc(crtc, i, regp->CRTC[i]);
1141 for (i = 0; i < 9; i++)
1142 NVWriteVgaGr(crtc, i, regp->Graphics[i]);
1144 NVEnablePalette(crtc);
1145 for (i = 0; i < 21; i++)
1146 NVWriteVgaAttr(crtc, i, regp->Attribute[i]);
1147 NVDisablePalette(crtc);
1151 static void nv_crtc_fix_nv40_hw_cursor(xf86CrtcPtr crtc)
1153 /* TODO - implement this properly */
1154 ScrnInfoPtr pScrn = crtc->scrn;
1155 NVPtr pNv = NVPTR(pScrn);
1157 if(pNv->Architecture == NV_ARCH_40) { /* HW bug */
1158 volatile CARD32 curpos = nvReadCurRAMDAC(pNv, NV_RAMDAC_CURSOR_POS);
1159 nvWriteCurRAMDAC(pNv, NV_RAMDAC_CURSOR_POS, curpos);
1163 static void nv_crtc_load_state_ext(xf86CrtcPtr crtc, RIVA_HW_STATE *state)
1165 ScrnInfoPtr pScrn = crtc->scrn;
1166 NVPtr pNv = NVPTR(pScrn);
1167 NVCrtcPrivatePtr nv_crtc = crtc->driver_private;
1172 regp = &state->crtc_reg[nv_crtc->crtc];
1174 if(pNv->Architecture >= NV_ARCH_10) {
1176 nvWriteCRTC(pNv, nv_crtc->crtc, NV_CRTC_FSEL, regp->head);
1178 nvWriteVIDEO(pNv, NV_PVIDEO_STOP, 1);
1179 nvWriteVIDEO(pNv, NV_PVIDEO_INTR_EN, 0);
1180 nvWriteVIDEO(pNv, NV_PVIDEO_OFFSET_BUFF(0), 0);
1181 nvWriteVIDEO(pNv, NV_PVIDEO_OFFSET_BUFF(1), 0);
1182 nvWriteVIDEO(pNv, NV_PVIDEO_LIMIT(0), pNv->VRAMPhysicalSize - 1);
1183 nvWriteVIDEO(pNv, NV_PVIDEO_LIMIT(1), pNv->VRAMPhysicalSize - 1);
1184 nvWriteMC(pNv, 0x1588, 0);
1186 NVWriteVgaCrtc(crtc, NV_VGA_CRTCX_BUFFER, 0xff);
1187 NVWriteVgaCrtc(crtc, NV_VGA_CRTCX_BUFFER, regp->CRTC[NV_VGA_CRTCX_BUFFER]);
1188 nvWriteCRTC(pNv, nv_crtc->crtc, NV_CRTC_CURSOR_CONFIG, regp->cursorConfig);
1189 nvWriteCRTC(pNv, nv_crtc->crtc, NV_CRTC_0830, regp->unk830);
1190 nvWriteCRTC(pNv, nv_crtc->crtc, NV_CRTC_0834, regp->unk834);
1192 NVWriteVgaCrtc(crtc, NV_VGA_CRTCX_FP_HTIMING, regp->CRTC[NV_VGA_CRTCX_FP_HTIMING]);
1193 NVWriteVgaCrtc(crtc, NV_VGA_CRTCX_FP_VTIMING, regp->CRTC[NV_VGA_CRTCX_FP_VTIMING]);
1195 NVWriteVgaCrtc(crtc, NV_VGA_CRTCX_59, regp->CRTC[NV_VGA_CRTCX_59]);
1196 NVWriteVgaCrtc(crtc, NV_VGA_CRTCX_EXTRA, regp->CRTC[NV_VGA_CRTCX_EXTRA]);
1199 NVWriteVgaCrtc(crtc, NV_VGA_CRTCX_REPAINT0, regp->CRTC[NV_VGA_CRTCX_REPAINT0]);
1200 NVWriteVgaCrtc(crtc, NV_VGA_CRTCX_REPAINT1, regp->CRTC[NV_VGA_CRTCX_REPAINT1]);
1201 NVWriteVgaCrtc(crtc, NV_VGA_CRTCX_LSR, regp->CRTC[NV_VGA_CRTCX_LSR]);
1202 NVWriteVgaCrtc(crtc, NV_VGA_CRTCX_PIXEL, regp->CRTC[NV_VGA_CRTCX_PIXEL]);
1203 NVWriteVgaCrtc(crtc, NV_VGA_CRTCX_LCD, regp->CRTC[NV_VGA_CRTCX_LCD]);
1204 NVWriteVgaCrtc(crtc, NV_VGA_CRTCX_HEB, regp->CRTC[NV_VGA_CRTCX_HEB]);
1205 NVWriteVgaCrtc(crtc, NV_VGA_CRTCX_FIFO1, regp->CRTC[NV_VGA_CRTCX_FIFO1]);
1206 NVWriteVgaCrtc(crtc, NV_VGA_CRTCX_FIFO0, regp->CRTC[NV_VGA_CRTCX_FIFO0]);
1207 NVWriteVgaCrtc(crtc, NV_VGA_CRTCX_FIFO_LWM, regp->CRTC[NV_VGA_CRTCX_FIFO_LWM]);
1208 if(pNv->Architecture >= NV_ARCH_30) {
1209 NVWriteVgaCrtc(crtc, NV_VGA_CRTCX_FIFO_LWM_NV30, regp->CRTC[NV_VGA_CRTCX_FIFO_LWM_NV30]);
1212 NVWriteVgaCrtc(crtc, NV_VGA_CRTCX_CURCTL0, regp->CRTC[NV_VGA_CRTCX_CURCTL0]);
1213 NVWriteVgaCrtc(crtc, NV_VGA_CRTCX_CURCTL1, regp->CRTC[NV_VGA_CRTCX_CURCTL1]);
1214 nv_crtc_fix_nv40_hw_cursor(crtc);
1215 NVWriteVgaCrtc(crtc, NV_VGA_CRTCX_CURCTL2, regp->CRTC[NV_VGA_CRTCX_CURCTL2]);
1216 NVWriteVgaCrtc(crtc, NV_VGA_CRTCX_INTERLACE, regp->CRTC[NV_VGA_CRTCX_INTERLACE]);
1218 nvWriteCRTC(pNv, nv_crtc->crtc, NV_CRTC_INTR_EN_0, 0);
1219 nvWriteCRTC(pNv, nv_crtc->crtc, NV_CRTC_INTR_0, NV_CRTC_INTR_VBLANK);
1221 pNv->CurrentState = state;
1224 static void nv_crtc_save_state_vga(xf86CrtcPtr crtc, RIVA_HW_STATE *state)
1226 ScrnInfoPtr pScrn = crtc->scrn;
1227 NVPtr pNv = NVPTR(pScrn);
1228 NVCrtcPrivatePtr nv_crtc = crtc->driver_private;
1232 regp = &state->crtc_reg[nv_crtc->crtc];
1234 regp->MiscOutReg = NVReadMiscOut(crtc);
1236 for (i = 0; i < 25; i++)
1237 regp->CRTC[i] = NVReadVgaCrtc(crtc, i);
1239 NVEnablePalette(crtc);
1240 for (i = 0; i < 21; i++)
1241 regp->Attribute[i] = NVReadVgaAttr(crtc, i);
1242 NVDisablePalette(crtc);
1244 for (i = 0; i < 9; i++)
1245 regp->Graphics[i] = NVReadVgaGr(crtc, i);
1247 for (i = 1; i < 5; i++)
1248 regp->Sequencer[i] = NVReadVgaSeq(crtc, i);
1252 static void nv_crtc_save_state_ext(xf86CrtcPtr crtc, RIVA_HW_STATE *state)
1254 ScrnInfoPtr pScrn = crtc->scrn;
1255 NVPtr pNv = NVPTR(pScrn);
1256 NVCrtcPrivatePtr nv_crtc = crtc->driver_private;
1260 regp = &state->crtc_reg[nv_crtc->crtc];
1262 regp->CRTC[NV_VGA_CRTCX_59] = NVReadVgaCrtc(crtc, NV_VGA_CRTCX_59);
1263 regp->CRTC[NV_VGA_CRTCX_LCD] = NVReadVgaCrtc(crtc, NV_VGA_CRTCX_LCD);
1264 regp->CRTC[NV_VGA_CRTCX_REPAINT0] = NVReadVgaCrtc(crtc, NV_VGA_CRTCX_REPAINT0);
1265 regp->CRTC[NV_VGA_CRTCX_REPAINT1] = NVReadVgaCrtc(crtc, NV_VGA_CRTCX_REPAINT1);
1266 regp->CRTC[NV_VGA_CRTCX_LSR] = NVReadVgaCrtc(crtc, NV_VGA_CRTCX_LSR);
1267 regp->CRTC[NV_VGA_CRTCX_PIXEL] = NVReadVgaCrtc(crtc, NV_VGA_CRTCX_PIXEL);
1268 regp->CRTC[NV_VGA_CRTCX_HEB] = NVReadVgaCrtc(crtc, NV_VGA_CRTCX_HEB);
1269 regp->CRTC[NV_VGA_CRTCX_FIFO1] = NVReadVgaCrtc(crtc, NV_VGA_CRTCX_FIFO1);
1271 regp->CRTC[NV_VGA_CRTCX_FIFO0] = NVReadVgaCrtc(crtc, NV_VGA_CRTCX_FIFO0);
1272 regp->CRTC[NV_VGA_CRTCX_FIFO_LWM] = NVReadVgaCrtc(crtc, NV_VGA_CRTCX_FIFO_LWM);
1273 if(pNv->Architecture >= NV_ARCH_30) {
1274 regp->CRTC[NV_VGA_CRTCX_FIFO_LWM_NV30] = NVReadVgaCrtc(crtc, NV_VGA_CRTCX_FIFO_LWM_NV30);
1276 regp->CRTC[NV_VGA_CRTCX_CURCTL0] = NVReadVgaCrtc(crtc, NV_VGA_CRTCX_CURCTL0);
1277 regp->CRTC[NV_VGA_CRTCX_CURCTL1] = NVReadVgaCrtc(crtc, NV_VGA_CRTCX_CURCTL1);
1278 regp->CRTC[NV_VGA_CRTCX_CURCTL2] = NVReadVgaCrtc(crtc, NV_VGA_CRTCX_CURCTL2);
1279 regp->CRTC[NV_VGA_CRTCX_INTERLACE] = NVReadVgaCrtc(crtc, NV_VGA_CRTCX_INTERLACE);
1281 regp->unk830 = nvReadCRTC(pNv, nv_crtc->crtc, NV_CRTC_0830);
1282 regp->unk834 = nvReadCRTC(pNv, nv_crtc->crtc, NV_CRTC_0834);
1284 if(pNv->Architecture >= NV_ARCH_10) {
1286 regp->head = nvReadCRTC(pNv, nv_crtc->crtc, NV_CRTC_FSEL);
1287 regp->crtcOwner = NVReadVgaCrtc(crtc, NV_VGA_CRTCX_OWNER);
1289 regp->CRTC[NV_VGA_CRTCX_EXTRA] = NVReadVgaCrtc(crtc, NV_VGA_CRTCX_EXTRA);
1291 regp->cursorConfig = nvReadCRTC(pNv, nv_crtc->crtc, NV_CRTC_CURSOR_CONFIG);
1293 regp->CRTC[NV_VGA_CRTCX_BUFFER] = NVReadVgaCrtc(crtc, NV_VGA_CRTCX_BUFFER);
1294 regp->CRTC[NV_VGA_CRTCX_FP_HTIMING] = NVReadVgaCrtc(crtc, NV_VGA_CRTCX_FP_HTIMING);
1295 regp->CRTC[NV_VGA_CRTCX_FP_VTIMING] = NVReadVgaCrtc(crtc, NV_VGA_CRTCX_FP_VTIMING);
1300 NVCrtcSetBase (xf86CrtcPtr crtc, int x, int y)
1302 ScrnInfoPtr pScrn = crtc->scrn;
1303 NVPtr pNv = NVPTR(pScrn);
1304 NVCrtcPrivatePtr nv_crtc = crtc->driver_private;
1305 NVFBLayout *pLayout = &pNv->CurrentLayout;
1308 start += ((y * pScrn->displayWidth + x) * (pLayout->bitsPerPixel/8));
1309 start += pNv->FB->offset;
1311 nvWriteCRTC(pNv, nv_crtc->crtc, NV_CRTC_START, start);
1317 void NVCrtcSetCursor(xf86CrtcPtr crtc, Bool state)
1319 int current = NVReadVgaCrtc(crtc, NV_VGA_CRTCX_CURCTL1);
1326 NVWriteVgaCrtc(crtc, NV_VGA_CRTCX_CURCTL1, current);
1329 void NVSetMode(ScrnInfoPtr pScrn, DisplayModePtr mode)
1331 xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
1333 for (i = 0; i < xf86_config->num_crtc; i++) {
1334 if (xf86_config->crtc[i]->enabled) {
1335 nv_crtc_mode_set(xf86_config->crtc[i], mode, NULL, 0,0);
1340 static void NVCrtcWriteDacMask(xf86CrtcPtr crtc, CARD8 value)
1342 ScrnInfoPtr pScrn = crtc->scrn;
1343 NVCrtcPrivatePtr nv_crtc = crtc->driver_private;
1344 NVPtr pNv = NVPTR(pScrn);
1345 volatile CARD8 *pDACReg = nv_crtc->crtc ? pNv->PDIO1 : pNv->PDIO0;
1347 NV_WR08(pDACReg, VGA_DAC_MASK, value);
1350 static CARD8 NVCrtcReadDacMask(xf86CrtcPtr crtc)
1352 ScrnInfoPtr pScrn = crtc->scrn;
1353 NVCrtcPrivatePtr nv_crtc = crtc->driver_private;
1354 NVPtr pNv = NVPTR(pScrn);
1355 volatile CARD8 *pDACReg = nv_crtc->crtc ? pNv->PDIO1 : pNv->PDIO0;
1357 return NV_RD08(pDACReg, VGA_DAC_MASK);
1360 static void NVCrtcWriteDacReadAddr(xf86CrtcPtr crtc, CARD8 value)
1362 ScrnInfoPtr pScrn = crtc->scrn;
1363 NVCrtcPrivatePtr nv_crtc = crtc->driver_private;
1364 NVPtr pNv = NVPTR(pScrn);
1365 volatile CARD8 *pDACReg = nv_crtc->crtc ? pNv->PDIO1 : pNv->PDIO0;
1367 NV_WR08(pDACReg, VGA_DAC_READ_ADDR, value);
1370 static void NVCrtcWriteDacWriteAddr(xf86CrtcPtr crtc, CARD8 value)
1372 ScrnInfoPtr pScrn = crtc->scrn;
1373 NVCrtcPrivatePtr nv_crtc = crtc->driver_private;
1374 NVPtr pNv = NVPTR(pScrn);
1375 volatile CARD8 *pDACReg = nv_crtc->crtc ? pNv->PDIO1 : pNv->PDIO0;
1377 NV_WR08(pDACReg, VGA_DAC_WRITE_ADDR, value);
1380 static void NVCrtcWriteDacData(xf86CrtcPtr crtc, CARD8 value)
1382 ScrnInfoPtr pScrn = crtc->scrn;
1383 NVCrtcPrivatePtr nv_crtc = crtc->driver_private;
1384 NVPtr pNv = NVPTR(pScrn);
1385 volatile CARD8 *pDACReg = nv_crtc->crtc ? pNv->PDIO1 : pNv->PDIO0;
1387 NV_WR08(pDACReg, VGA_DAC_DATA, value);
1390 static CARD8 NVCrtcReadDacData(xf86CrtcPtr crtc, CARD8 value)
1392 ScrnInfoPtr pScrn = crtc->scrn;
1393 NVCrtcPrivatePtr nv_crtc = crtc->driver_private;
1394 NVPtr pNv = NVPTR(pScrn);
1395 volatile CARD8 *pDACReg = nv_crtc->crtc ? pNv->PDIO1 : pNv->PDIO0;
1397 return NV_RD08(pDACReg, VGA_DAC_DATA);
1400 void NVCrtcLoadPalette(xf86CrtcPtr crtc)
1403 NVCrtcPrivatePtr nv_crtc = crtc->driver_private;
1405 ScrnInfoPtr pScrn = crtc->scrn;
1406 NVPtr pNv = NVPTR(pScrn);
1408 regp = &pNv->ModeReg.crtc_reg[nv_crtc->crtc];
1410 NVWriteVgaCrtc(crtc, NV_VGA_CRTCX_OWNER, nv_crtc->crtc * 0x3);
1411 NVCrtcWriteDacMask(crtc, 0xff);
1412 NVCrtcWriteDacWriteAddr(crtc, 0x00);
1414 for (i = 0; i<768; i++) {
1415 NVCrtcWriteDacData(crtc, regp->DAC[i]);
1417 NVDisablePalette(crtc);
1420 void NVCrtcBlankScreen(xf86CrtcPtr crtc, Bool on)
1422 NVCrtcPrivatePtr nv_crtc = crtc->driver_private;
1425 NVWriteVgaCrtc(crtc, NV_VGA_CRTCX_OWNER, nv_crtc->crtc * 0x3);
1427 scrn = NVReadVgaSeq(crtc, 0x01);
1434 NVVgaSeqReset(crtc, TRUE);
1435 NVWriteVgaSeq(crtc, 0x01, scrn);
1436 NVVgaSeqReset(crtc, FALSE);
1439 /*************************************************************************** \
1441 |* Copyright 1993-2003 NVIDIA, Corporation. All rights reserved. *|
1443 |* NOTICE TO USER: The source code is copyrighted under U.S. and *|
1444 |* international laws. Users and possessors of this source code are *|
1445 |* hereby granted a nonexclusive, royalty-free copyright license to *|
1446 |* use this code in individual and commercial software. *|
1448 |* Any use of this source code must include, in the user documenta- *|
1449 |* tion and internal comments to the code, notices to the end user *|
1452 |* Copyright 1993-1999 NVIDIA, Corporation. All rights reserved. *|
1454 |* NVIDIA, CORPORATION MAKES NO REPRESENTATION ABOUT THE SUITABILITY *|
1455 |* OF THIS SOURCE CODE FOR ANY PURPOSE. IT IS PROVIDED "AS IS" *|
1456 |* WITHOUT EXPRESS OR IMPLIED WARRANTY OF ANY KIND. NVIDIA, CORPOR- *|
1457 |* ATION DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOURCE CODE, *|
1458 |* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGE- *|
1459 |* MENT, AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL *|
1460 |* NVIDIA, CORPORATION BE LIABLE FOR ANY SPECIAL, INDIRECT, INCI- *|
1461 |* DENTAL, OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RE- *|
1462 |* SULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION *|
1463 |* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF *|
1464 |* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOURCE CODE. *|
1466 |* U.S. Government End Users. This source code is a "commercial *|
1467 |* item," as that term is defined at 48 C.F.R. 2.101 (OCT 1995), *|
1468 |* consisting of "commercial computer software" and "commercial *|
1469 |* computer software documentation," as such terms are used in *|
1470 |* 48 C.F.R. 12.212 (SEPT 1995) and is provided to the U.S. Govern- *|
1471 |* ment only as a commercial end item. Consistent with 48 C.F.R. *|
1472 |* 12.212 and 48 C.F.R. 227.7202-1 through 227.7202-4 (JUNE 1995), *|
1473 |* all U.S. Government End Users acquire the source code with only *|
1474 |* those rights set forth herein. *|
1476 \***************************************************************************/