Remove list that is incorrect and no longer needed.
[nouveau] / src / nv_crtc.c
1 /*
2  * Copyright 2006 Dave Airlie
3  *
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:
10  *
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
13  * Software.
14  *
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
21  */
22 /*
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 
25  */
26
27
28 #ifdef HAVE_CONFIG_H
29 #include "config.h"
30 #endif
31
32 #include <assert.h>
33 #include "xf86.h"
34 #include "os.h"
35 #include "mibank.h"
36 #include "globals.h"
37 #include "xf86.h"
38 #include "xf86Priv.h"
39 #include "xf86DDC.h"
40 #include "mipointer.h"
41 #include "windowstr.h"
42 #include <randrstr.h>
43 #include <X11/extensions/render.h>
44
45 #include "xf86Crtc.h"
46 #include "nv_include.h"
47
48 #include "vgaHW.h"
49
50 #define CRTC_INDEX 0x3d4
51 #define CRTC_DATA 0x3d5
52 #define CRTC_IN_STAT_1 0x3da
53
54 #define WHITE_VALUE 0x3F
55 #define BLACK_VALUE 0x00
56 #define OVERSCAN_VALUE 0x01
57
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);
62
63 static void NVWriteMiscOut(xf86CrtcPtr crtc, CARD8 value)
64 {
65   ScrnInfoPtr pScrn = crtc->scrn;
66   NVCrtcPrivatePtr nv_crtc = crtc->driver_private;
67   NVPtr pNv = NVPTR(pScrn);
68
69   NV_WR08(pNv->PVIO, VGA_MISC_OUT_W, value);
70 }
71
72 static CARD8 NVReadMiscOut(xf86CrtcPtr crtc)
73 {
74   ScrnInfoPtr pScrn = crtc->scrn;
75   NVCrtcPrivatePtr nv_crtc = crtc->driver_private;
76   NVPtr pNv = NVPTR(pScrn);
77
78   return NV_RD08(pNv->PVIO, VGA_MISC_OUT_R);
79 }
80
81
82 static void NVWriteVgaCrtc(xf86CrtcPtr crtc, CARD8 index, CARD8 value)
83 {
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;
88
89   NV_WR08(pCRTCReg, CRTC_INDEX, index);
90   NV_WR08(pCRTCReg, CRTC_DATA, value);
91 }
92
93 static CARD8 NVReadVgaCrtc(xf86CrtcPtr crtc, CARD8 index)
94 {
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;
99
100   NV_WR08(pCRTCReg, CRTC_INDEX, index);
101   return NV_RD08(pCRTCReg, CRTC_DATA);
102 }
103
104 static void NVWriteVgaSeq(xf86CrtcPtr crtc, CARD8 index, CARD8 value)
105 {
106   ScrnInfoPtr pScrn = crtc->scrn;
107   NVCrtcPrivatePtr nv_crtc = crtc->driver_private;
108   NVPtr pNv = NVPTR(pScrn);
109
110   NV_WR08(pNv->PVIO, VGA_SEQ_INDEX, index);
111   NV_WR08(pNv->PVIO, VGA_SEQ_DATA, value);
112 }
113
114 static CARD8 NVReadVgaSeq(xf86CrtcPtr crtc, CARD8 index)
115 {
116   ScrnInfoPtr pScrn = crtc->scrn;
117   NVCrtcPrivatePtr nv_crtc = crtc->driver_private;
118   NVPtr pNv = NVPTR(pScrn);
119   volatile CARD8 *pVGAReg = pNv->PVIO;
120
121   NV_WR08(pNv->PVIO, VGA_SEQ_INDEX, index);
122   return NV_RD08(pNv->PVIO, VGA_SEQ_DATA);
123 }
124
125 static void NVWriteVgaGr(xf86CrtcPtr crtc, CARD8 index, CARD8 value)
126 {
127   ScrnInfoPtr pScrn = crtc->scrn;
128   NVCrtcPrivatePtr nv_crtc = crtc->driver_private;
129   NVPtr pNv = NVPTR(pScrn);
130
131   NV_WR08(pNv->PVIO, VGA_GRAPH_INDEX, index);
132   NV_WR08(pNv->PVIO, VGA_GRAPH_DATA, value);
133 }
134
135 static CARD8 NVReadVgaGr(xf86CrtcPtr crtc, CARD8 index)
136 {
137   ScrnInfoPtr pScrn = crtc->scrn;
138   NVCrtcPrivatePtr nv_crtc = crtc->driver_private;
139   NVPtr pNv = NVPTR(pScrn);
140   volatile CARD8 *pVGAReg = pNv->PVIO;
141
142   NV_WR08(pVGAReg, VGA_GRAPH_INDEX, index);
143   return NV_RD08(pVGAReg, VGA_GRAPH_DATA);
144
145
146
147 static void NVWriteVgaAttr(xf86CrtcPtr crtc, CARD8 index, CARD8 value)
148 {
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;
153
154   NV_RD08(pCRTCReg, CRTC_IN_STAT_1);
155   if (nv_crtc->paletteEnabled)
156     index &= ~0x20;
157   else
158     index |= 0x20;
159   NV_WR08(pCRTCReg, VGA_ATTR_INDEX, index);
160   NV_WR08(pCRTCReg, VGA_ATTR_DATA_W, value);
161 }
162
163 static CARD8 NVReadVgaAttr(xf86CrtcPtr crtc, CARD8 index)
164 {
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;
169
170   NV_RD08(pCRTCReg, CRTC_IN_STAT_1);
171   if (nv_crtc->paletteEnabled)
172     index &= ~0x20;
173   else
174     index |= 0x20;
175   NV_WR08(pCRTCReg, VGA_ATTR_INDEX, index);
176   return NV_RD08(pCRTCReg, VGA_ATTR_DATA_R);
177 }
178
179 void NVCrtcSetOwner(xf86CrtcPtr crtc)
180 {
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);
184 }
185
186 static void
187 NVEnablePalette(xf86CrtcPtr crtc)
188 {
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;
193
194   NV_RD08(pCRTCReg, CRTC_IN_STAT_1);
195   NV_WR08(pCRTCReg, VGA_ATTR_INDEX, 0);
196   nv_crtc->paletteEnabled = TRUE;
197 }
198
199 static void
200 NVDisablePalette(xf86CrtcPtr crtc)
201 {
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;
206
207   NV_RD08(pCRTCReg, CRTC_IN_STAT_1);
208   NV_WR08(pCRTCReg, VGA_ATTR_INDEX, 0x20);
209   nv_crtc->paletteEnabled = FALSE;
210 }
211
212 static void NVWriteVgaReg(xf86CrtcPtr crtc, CARD32 reg, CARD8 value)
213 {
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;
218
219   NV_WR08(pCRTCReg, reg, value);
220 }
221
222 /* perform a sequencer reset */
223 static void NVVgaSeqReset(xf86CrtcPtr crtc, Bool start)
224 {
225   if (start)
226     NVWriteVgaSeq(crtc, 0x00, 0x1);
227   else
228     NVWriteVgaSeq(crtc, 0x00, 0x3);
229
230 }
231 static void NVVgaProtect(xf86CrtcPtr crtc, Bool on)
232 {
233   CARD8 tmp;
234
235   if (on) {
236     tmp = NVReadVgaSeq(crtc, 0x1);
237     NVVgaSeqReset(crtc, TRUE);
238     NVWriteVgaSeq(crtc, 0x01, tmp | 0x20);
239
240     NVEnablePalette(crtc);
241   } else {
242     /*
243      * Reenable sequencer, then turn on screen.
244      */
245     tmp = NVReadVgaSeq(crtc, 0x1);
246     NVWriteVgaSeq(crtc, 0x01, tmp & ~0x20);     /* reenable display */
247     NVVgaSeqReset(crtc, FALSE);
248
249     NVDisablePalette(crtc);
250   }
251 }
252
253 void NVCrtcLockUnlock(xf86CrtcPtr crtc, Bool Lock)
254 {
255   CARD8 cr11;
256
257   NVWriteVgaCrtc(crtc, NV_VGA_CRTCX_LOCK, Lock ? 0x99 : 0x57);
258   cr11 = NVReadVgaCrtc(crtc, NV_VGA_CRTCX_VSYNCE);
259   if (Lock) cr11 |= 0x80;
260   else cr11 &= ~0x80;
261   NVWriteVgaCrtc(crtc, NV_VGA_CRTCX_VSYNCE, cr11);
262 }
263 /*
264  * Calculate the Video Clock parameters for the PLL.
265  */
266 static void CalcVClock (
267     int           clockIn,
268     int          *clockOut,
269     CARD32         *pllOut,
270     NVPtr        pNv
271 )
272 {
273     unsigned lowM, highM;
274     unsigned DeltaNew, DeltaOld;
275     unsigned VClk, Freq;
276     unsigned M, N, P;
277     
278     DeltaOld = 0xFFFFFFFF;
279
280     VClk = (unsigned)clockIn;
281     
282     if (pNv->CrystalFreqKHz == 13500) {
283         lowM  = 7;
284         highM = 13;
285     } else {
286         lowM  = 8;
287         highM = 14;
288     }
289
290     for (P = 0; P <= 4; P++) {
291         Freq = VClk << P;
292         if ((Freq >= 128000) && (Freq <= 350000)) {
293             for (M = lowM; M <= highM; M++) {
294                 N = ((VClk << P) * M) / pNv->CrystalFreqKHz;
295                 if(N <= 255) {
296                     Freq = ((pNv->CrystalFreqKHz * N) / M) >> P;
297                     if (Freq > VClk)
298                         DeltaNew = Freq - VClk;
299                     else
300                         DeltaNew = VClk - Freq;
301                     if (DeltaNew < DeltaOld) {
302                         *pllOut   = (P << 16) | (N << 8) | M;
303                         *clockOut = Freq;
304                         DeltaOld  = DeltaNew;
305                     }
306                 }
307             }
308         }
309     }
310 }
311
312 static void CalcVClock2Stage (
313     int           clockIn,
314     int          *clockOut,
315     CARD32         *pllOut,
316     CARD32         *pllBOut,
317     NVPtr        pNv
318 )
319 {
320     unsigned DeltaNew, DeltaOld;
321     unsigned VClk, Freq;
322     unsigned M, N, P;
323
324     DeltaOld = 0xFFFFFFFF;
325
326     *pllBOut = 0x80000401;  /* fixed at x4 for now */
327
328     VClk = (unsigned)clockIn;
329
330     for (P = 0; P <= 6; P++) {
331         Freq = VClk << 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;
337                     if (Freq > VClk)
338                         DeltaNew = Freq - VClk;
339                     else
340                         DeltaNew = VClk - Freq;
341                     if (DeltaNew < DeltaOld) {
342                         *pllOut   = (P << 16) | (N << 8) | M;
343                         *clockOut = Freq;
344                         DeltaOld  = DeltaNew;
345                     }
346                 }
347             }
348         }
349     }
350 }
351
352 static void nv_crtc_save_state_pll(NVPtr pNv, RIVA_HW_STATE *state)
353 {
354   state->vpll         = nvReadRAMDAC0(pNv, NV_RAMDAC_VPLL);
355   if(pNv->twoHeads)
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);
360   }
361   state->pllsel       = nvReadRAMDAC0(pNv, NV_RAMDAC_PLL_SELECT);
362 }
363
364
365 static void nv_crtc_load_state_pll(NVPtr pNv, RIVA_HW_STATE *state)
366 {
367   nvWriteRAMDAC0(pNv, NV_RAMDAC_PLL_SELECT, state->pllsel);
368   
369   ErrorF("writting vpll %08X\n", state->vpll);
370   ErrorF("writting vpll2 %08X\n", state->vpll2);
371   nvWriteRAMDAC0(pNv, NV_RAMDAC_VPLL, state->vpll);
372   if(pNv->twoHeads)
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);
377   }  
378 }
379
380 /*
381  * Calculate extended mode parameters (SVGA) and save in a 
382  * mode state structure.
383  */
384 void nv_crtc_calc_state_ext(
385     xf86CrtcPtr crtc,
386     int            bpp,
387     int            width,
388     int            hDisplaySize,
389     int            height,
390     int            dotClock,
391     int            flags 
392 )
393 {
394     ScrnInfoPtr pScrn = crtc->scrn;
395     int pixelDepth, VClk;
396     CARD32 CursorStart;
397     NVCrtcPrivatePtr nv_crtc = crtc->driver_private;
398     xf86CrtcConfigPtr   xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
399     NVCrtcRegPtr regp;
400     NVPtr pNv = NVPTR(pScrn);    
401     RIVA_HW_STATE *state;
402     int num_crtc_enabled, i;
403
404     state = &pNv->ModeReg;
405
406     regp = &pNv->ModeReg.crtc_reg[nv_crtc->crtc];
407
408     /*
409      * Extended RIVA registers.
410      */
411     pixelDepth = (bpp + 1)/8;
412     if(pNv->twoStagePLL)
413         CalcVClock2Stage(dotClock, &VClk, &state->pll, &state->pllB, pNv);
414     else
415         CalcVClock(dotClock, &VClk, &state->pll, pNv);
416
417     switch (pNv->Architecture)
418     {
419         case NV_ARCH_04:
420             nv4UpdateArbitrationSettings(VClk, 
421                                          pixelDepth * 8, 
422                                         &(state->arbitration0),
423                                         &(state->arbitration1),
424                                          pNv);
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;
433             break;
434         case NV_ARCH_10:
435         case NV_ARCH_20:
436         case NV_ARCH_30:
437         default:
438             if(((pNv->Chipset & 0xfff0) == CHIPSET_C51) ||
439                ((pNv->Chipset & 0xfff0) == CHIPSET_C512))
440             {
441                 state->arbitration0 = 128; 
442                 state->arbitration1 = 0x0480; 
443             } else
444             if(((pNv->Chipset & 0xffff) == CHIPSET_NFORCE) ||
445                ((pNv->Chipset & 0xffff) == CHIPSET_NFORCE2))
446             {
447                 nForceUpdateArbitrationSettings(VClk,
448                                           pixelDepth * 8,
449                                          &(state->arbitration0),
450                                          &(state->arbitration1),
451                                           pNv);
452             } else if(pNv->Architecture < NV_ARCH_30) {
453                 nv10UpdateArbitrationSettings(VClk, 
454                                           pixelDepth * 8, 
455                                          &(state->arbitration0),
456                                          &(state->arbitration1),
457                                           pNv);
458             } else {
459                 nv30UpdateArbitrationSettings(pNv,
460                                          &(state->arbitration0),
461                                          &(state->arbitration1));
462             }
463
464
465             CursorStart = pNv->Cursor->offset;
466
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;
470
471             if (flags & V_DBLSCAN) 
472                 regp->CRTC[NV_VGA_CRTCX_CURCTL1]|= 2;
473
474
475             state->config   = nvReadFB(pNv, NV_PFB_CFG0);
476             regp->CRTC[NV_VGA_CRTCX_REPAINT1] = hDisplaySize < 1280 ? 0x04 : 0x00;
477             break;
478     }
479
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)
484         num_crtc_enabled++;
485     }
486
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);
492       } else {
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;
497       }
498     } else {
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;
503     }
504
505
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;
510     }
511     
512     
513     regp->CRTC[NV_VGA_CRTCX_REPAINT0] = (((width / 8) * pixelDepth) & 0x700) >> 3;
514     regp->CRTC[NV_VGA_CRTCX_PIXEL] = (pixelDepth > 2) ? 3 : pixelDepth;
515 }
516
517
518 static void
519 nv_crtc_dpms(xf86CrtcPtr crtc, int mode)
520 {
521      NVCrtcPrivatePtr nv_crtc = crtc->driver_private;
522      unsigned char seq1 = 0, crtc17 = 0;
523      unsigned char crtc1A;
524      int ret;
525      Bool crtc_is_on = FALSE;
526
527      NVCrtcSetOwner(crtc);
528
529      crtc1A = NVReadVgaCrtc(crtc, NV_VGA_CRTCX_REPAINT1) & ~0xC0;
530      switch(mode) {
531      case DPMSModeStandby:
532        /* Screen: Off; HSync: Off, VSync: On -- Not Supported */
533        seq1 = 0x20;
534        crtc17 = 0x80;
535        crtc1A |= 0x80;
536        break;
537      case DPMSModeSuspend:
538        /* Screen: Off; HSync: On, VSync: Off -- Not Supported */
539        seq1 = 0x20;
540        crtc17 = 0x80;
541        crtc1A |= 0x40;
542        break;
543      case DPMSModeOff:
544        /* Screen: Off; HSync: Off, VSync: Off */
545        seq1 = 0x20;
546        crtc17 = 0x00;
547        crtc1A |= 0xC0;
548        break;
549      case DPMSModeOn:
550      default:
551        /* Screen: On; HSync: On, VSync: On */
552        seq1 = 0x00;
553        crtc17 = 0x80;
554        crtc_is_on = TRUE;
555        break;
556      }
557
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;
562      usleep(10000);
563      NVWriteVgaCrtc(crtc, NV_VGA_CRTCX_MODECTL, crtc17);
564      NVWriteVgaSeq(crtc, 0x0, 0x3);
565
566      NVWriteVgaCrtc(crtc, NV_VGA_CRTCX_REPAINT1, crtc1A);
567
568         /* This is usefull for Xv NVWaitVSync() */
569         nv_crtc->pNv->crtc_active[nv_crtc->crtc] = crtc_is_on;
570 }
571
572 static Bool
573 nv_crtc_mode_fixup(xf86CrtcPtr crtc, DisplayModePtr mode,
574                      DisplayModePtr adjusted_mode)
575 {
576     return TRUE;
577 }
578
579 static void
580 nv_crtc_mode_set_vga(xf86CrtcPtr crtc, DisplayModePtr mode)
581 {
582     ScrnInfoPtr pScrn = crtc->scrn;
583    NVCrtcPrivatePtr nv_crtc = crtc->driver_private;
584    NVCrtcRegPtr regp;
585    NVPtr pNv = NVPTR(pScrn);
586    int depth = pScrn->depth;
587    unsigned int i;
588
589    regp = &pNv->ModeReg.crtc_reg[nv_crtc->crtc];
590
591
592    /*
593     * compute correct Hsync & Vsync polarity 
594     */
595    if ((mode->Flags & (V_PHSYNC | V_NHSYNC))
596        && (mode->Flags & (V_PVSYNC | V_NVSYNC)))
597    {
598        regp->MiscOutReg = 0x23;
599        if (mode->Flags & V_NHSYNC) regp->MiscOutReg |= 0x40;
600        if (mode->Flags & V_NVSYNC) regp->MiscOutReg |= 0x80;
601    }
602    else
603    {
604        int VDisplay = mode->VDisplay;
605        if (mode->Flags & V_DBLSCAN)
606            VDisplay *= 2;
607        if (mode->VScan > 1)
608            VDisplay *= mode->VScan;
609        if      (VDisplay < 400)
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 */
615        else
616            regp->MiscOutReg = 0x23;             /* +hsync +vsync */
617    }
618    
619    regp->MiscOutReg |= (mode->ClockIndex & 0x03) << 2;
620    
621    /*
622     * Time Sequencer
623     */
624     if (depth == 4)
625         regp->Sequencer[0] = 0x02;
626     else
627         regp->Sequencer[0] = 0x00;
628     if (mode->Flags & V_CLKDIV2) 
629         regp->Sequencer[1] = 0x09;
630     else
631         regp->Sequencer[1] = 0x01;
632     if (depth == 1)
633         regp->Sequencer[2] = 1 << BIT_PLANE;
634     else
635         regp->Sequencer[2] = 0x0F;
636     regp->Sequencer[3] = 0x00;                             /* Font select */
637     if (depth < 8)
638         regp->Sequencer[4] = 0x06;                             /* Misc */
639     else
640         regp->Sequencer[4] = 0x0E;                             /* Misc */
641
642     /*
643      * CRTC Controller
644      */
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);
650     if (i < 0x80)
651         regp->CRTC[3] |= i;
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)
660         | 0x10
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;
685     if (depth < 8)
686         regp->CRTC[23] = 0xE3;
687     else
688         regp->CRTC[23] = 0xC3;
689     regp->CRTC[24] = 0xFF;
690
691     /*
692      * Theory resumes here....
693      */
694
695     /*
696      * Graphics Display Controller
697      */
698     regp->Graphics[0] = 0x00;
699     regp->Graphics[1] = 0x00;
700     regp->Graphics[2] = 0x00;
701     regp->Graphics[3] = 0x00;
702     if (depth == 1) {
703         regp->Graphics[4] = BIT_PLANE;
704         regp->Graphics[5] = 0x00;
705     } else {
706         regp->Graphics[4] = 0x00;
707         if (depth == 4)
708             regp->Graphics[5] = 0x02;
709         else
710             regp->Graphics[5] = 0x40;
711     }
712     regp->Graphics[6] = 0x05;   /* only map 64k VGA memory !!!! */
713     regp->Graphics[7] = 0x0F;
714     regp->Graphics[8] = 0xFF;
715   
716     if (depth == 1) {
717         /* Initialise the Mono map according to which bit-plane gets used */
718
719         Bool flipPixels = xf86GetFlipPixels();
720
721         for (i=0; i<16; i++)
722             if (((i & (1 << BIT_PLANE)) != 0) != flipPixels)
723                 regp->Attribute[i] = WHITE_VALUE;
724             else
725                 regp->Attribute[i] = BLACK_VALUE;
726
727     } else {
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;
744         if (depth == 4)
745             regp->Attribute[16] = 0x81; /* wrong for the ET4000 */
746         else
747             regp->Attribute[16] = 0x41; /* wrong for the ET4000 */
748         if (depth > 4)
749           regp->Attribute[17] = 0xff;
750         /* Attribute[17] (overscan) initialised in vgaHWGetHWRec() */
751     }
752     regp->Attribute[18] = 0x0F;
753     regp->Attribute[19] = 0x00;
754     regp->Attribute[20] = 0x00;
755
756 }
757
758 /**
759  * Sets up registers for the given mode/adjusted_mode pair.
760  *
761  * The clocks, CRTCs and outputs attached to this CRTC must be off.
762  *
763  * This shouldn't enable any clocks, CRTCs, or outputs, but they should
764  * be easily turned on/off after this.
765  */
766 static void
767 nv_crtc_mode_set_regs(xf86CrtcPtr crtc, DisplayModePtr mode)
768 {
769         ScrnInfoPtr pScrn = crtc->scrn;
770         NVPtr pNv = NVPTR(pScrn);
771         NVRegPtr state = &pNv->ModeReg;
772         xf86CrtcConfigPtr   xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
773         NVCrtcPrivatePtr nv_crtc = crtc->driver_private;
774         NVFBLayout *pLayout = &pNv->CurrentLayout;
775         NVCrtcRegPtr regp, savep;
776         unsigned int i;
777         int horizDisplay    = (mode->CrtcHDisplay/8)   - 1;
778         int horizStart      = (mode->CrtcHSyncStart/8) - 1;
779         int horizEnd        = (mode->CrtcHSyncEnd/8)   - 1;
780         int horizTotal      = (mode->CrtcHTotal/8)     - 5;
781         int horizBlankStart = (mode->CrtcHDisplay/8)   - 1;
782         int horizBlankEnd   = (mode->CrtcHTotal/8)     - 1;
783         int vertDisplay     =  mode->CrtcVDisplay      - 1;
784         int vertStart       =  mode->CrtcVSyncStart    - 1;
785         int vertEnd         =  mode->CrtcVSyncEnd      - 1;
786         int vertTotal       =  mode->CrtcVTotal        - 2;
787         int vertBlankStart  =  mode->CrtcVDisplay      - 1;
788         int vertBlankEnd    =  mode->CrtcVTotal        - 1;
789         /* What about vsync and hsync? */
790
791         Bool is_fp = FALSE;
792
793         for (i = 0; i < xf86_config->num_output; i++) {
794                 xf86OutputPtr  output = xf86_config->output[i];
795                 NVOutputPrivatePtr nv_output = output->driver_private;
796
797                 if (output->crtc == crtc) {
798                         if ((nv_output->type == OUTPUT_PANEL) || 
799                                 (nv_output->type == OUTPUT_DIGITAL)) {
800
801                                 is_fp = TRUE;
802                         }
803                 }
804         }
805
806         ErrorF("crtc: Pre-sync workaround\n");
807         /* The CRTC needs a little time to stay in sync at panel resultion */
808         /* I don't know at this state if this is the case, but elsewere is just a hack as well */
809         /* Any better ideas were to put this? */
810         if (is_fp) {
811                 if (pNv->Architecture >= NV_ARCH_40) {
812                         horizTotal -= 56/8;
813                         /* This is my observation, screen becomes fuzzy otherwise */
814                         /* Maybe this is because the crtc timing needs to end before the dfp's? */
815                         /* Check this on older hardware please */
816                         vertTotal -= 1;
817                 } else if (pNv->NVArch == 0x11) {
818                         horizTotal -= 56/8;
819                 } else {
820                         horizTotal -= 32/8;
821                 }
822         }
823         ErrorF("crtc: Post-sync workaround\n");
824
825         regp = &pNv->ModeReg.crtc_reg[nv_crtc->crtc];    
826         savep = &pNv->SavedReg.crtc_reg[nv_crtc->crtc];
827
828         if(mode->Flags & V_INTERLACE) 
829                 vertTotal |= 1;
830
831         regp->CRTC[NV_VGA_CRTCX_HTOTAL]  = Set8Bits(horizTotal);
832         regp->CRTC[NV_VGA_CRTCX_HDISPE]  = Set8Bits(horizDisplay);
833         regp->CRTC[NV_VGA_CRTCX_HBLANKS]  = Set8Bits(horizBlankStart);
834         regp->CRTC[NV_VGA_CRTCX_HBLANKE]  = SetBitField(horizBlankEnd,4:0,4:0) 
835                                 | SetBit(7);
836         regp->CRTC[NV_VGA_CRTCX_HSYNCS]  = Set8Bits(horizStart);
837         regp->CRTC[NV_VGA_CRTCX_HSYNCE]  = SetBitField(horizBlankEnd,5:5,7:7)
838                                 | SetBitField(horizEnd,4:0,4:0);
839         regp->CRTC[NV_VGA_CRTCX_VTOTAL]  = SetBitField(vertTotal,7:0,7:0);
840         regp->CRTC[NV_VGA_CRTCX_OVERFLOW]  = SetBitField(vertTotal,8:8,0:0)
841                                 | SetBitField(vertDisplay,8:8,1:1)
842                                 | SetBitField(vertStart,8:8,2:2)
843                                 | SetBitField(vertBlankStart,8:8,3:3)
844                                 | SetBit(4)
845                                 | SetBitField(vertTotal,9:9,5:5)
846                                 | SetBitField(vertDisplay,9:9,6:6)
847                                 | SetBitField(vertStart,9:9,7:7);
848         regp->CRTC[NV_VGA_CRTCX_MAXSCLIN]  = SetBitField(vertBlankStart,9:9,5:5)
849                                 | SetBit(6)
850                                 | ((mode->Flags & V_DBLSCAN) ? 0x80 : 0x00);
851         regp->CRTC[NV_VGA_CRTCX_VSYNCS] = Set8Bits(vertStart);
852         regp->CRTC[NV_VGA_CRTCX_VSYNCE] = SetBitField(vertEnd,3:0,3:0) | SetBit(5);
853         regp->CRTC[NV_VGA_CRTCX_VDISPE] = Set8Bits(vertDisplay);
854         regp->CRTC[NV_VGA_CRTCX_PITCHL] = ((pLayout->displayWidth/8)*(pLayout->bitsPerPixel/8));
855         regp->CRTC[NV_VGA_CRTCX_VBLANKS] = Set8Bits(vertBlankStart);
856         regp->CRTC[NV_VGA_CRTCX_VBLANKE] = Set8Bits(vertBlankEnd);
857
858         regp->Attribute[0x10] = 0x01;
859
860         if(pNv->Television)
861                 regp->Attribute[0x11] = 0x00;
862
863         regp->CRTC[NV_VGA_CRTCX_LSR] = SetBitField(horizBlankEnd,6:6,4:4)
864                                 | SetBitField(vertBlankStart,10:10,3:3)
865                                 | SetBitField(vertStart,10:10,2:2)
866                                 | SetBitField(vertDisplay,10:10,1:1)
867                                 | SetBitField(vertTotal,10:10,0:0);
868
869         regp->CRTC[NV_VGA_CRTCX_HEB] = SetBitField(horizTotal,8:8,0:0) 
870                                 | SetBitField(horizDisplay,8:8,1:1)
871                                 | SetBitField(horizBlankStart,8:8,2:2)
872                                 | SetBitField(horizStart,8:8,3:3);
873
874         regp->CRTC[NV_VGA_CRTCX_EXTRA] = SetBitField(vertTotal,11:11,0:0)
875                                 | SetBitField(vertDisplay,11:11,2:2)
876                                 | SetBitField(vertStart,11:11,4:4)
877                                 | SetBitField(vertBlankStart,11:11,6:6);
878
879         if(mode->Flags & V_INTERLACE) {
880                 horizTotal = (horizTotal >> 1) & ~1;
881                 regp->CRTC[NV_VGA_CRTCX_INTERLACE] = Set8Bits(horizTotal);
882                 regp->CRTC[NV_VGA_CRTCX_HEB] |= SetBitField(horizTotal,8:8,4:4);
883         } else {
884                 regp->CRTC[NV_VGA_CRTCX_INTERLACE] = 0xff;  /* interlace off */
885         }
886
887         regp->CRTC[NV_VGA_CRTCX_BUFFER] = 0xfa;
888     
889         if (is_fp) {
890                 regp->CRTC[NV_VGA_CRTCX_LCD] = savep->CRTC[NV_VGA_CRTCX_LCD] | 1;
891                 /* this turns on the DFP on nv28 outputs */
892                 regp->CRTC[NV_VGA_CRTCX_59] = savep->CRTC[NV_VGA_CRTCX_59] | 1;
893         } else {
894                 regp->CRTC[NV_VGA_CRTCX_LCD] = savep->CRTC[NV_VGA_CRTCX_LCD] & ~1;
895         }
896
897         /*
898         * Initialize DAC palette.
899         */
900         if(pLayout->bitsPerPixel != 8 ) {
901                 for (i = 0; i < 256; i++) {
902                         regp->DAC[i*3]     = i;
903                         regp->DAC[(i*3)+1] = i;
904                         regp->DAC[(i*3)+2] = i;
905                 }
906         }
907
908         /*
909         * Calculate the extended registers.
910         */
911
912         if(pLayout->depth < 24) {
913                 i = pLayout->depth;
914         } else {
915                 i = 32;
916         }
917
918         if(pNv->Architecture >= NV_ARCH_10) {
919                 pNv->CURSOR = (CARD32 *)pNv->Cursor->map;
920         }
921
922         ErrorF("crtc %d %d %d\n", nv_crtc->crtc, mode->CrtcHDisplay, pLayout->displayWidth);
923         nv_crtc_calc_state_ext(crtc,
924                                 i,
925                                 pLayout->displayWidth,
926                                 mode->CrtcHDisplay,
927                                 mode->CrtcVDisplay,
928                                 mode->Clock,
929                                 mode->Flags);
930
931         if (is_fp) {
932                 regp->CRTC[NV_VGA_CRTCX_PIXEL] |= (1 << 7);
933         }
934
935         regp->CRTC[NV_VGA_CRTCX_FIFO1] = savep->CRTC[NV_VGA_CRTCX_FIFO1] & ~(1<<5);
936
937         if(nv_crtc->crtc) {
938                 if (is_fp) {
939                         regp->head &= ~NV_CRTC_FSEL_FPP2;
940                         regp->head |= NV_CRTC_FSEL_FPP1;
941                 } else {
942                         regp->head &= ~NV_CRTC_FSEL_FPP1;
943                         regp->head |= NV_CRTC_FSEL_FPP2;
944                 }
945
946                 regp->crtcOwner = 3;
947         /* only enable secondary pllsel if CRTC 1 is selected on */
948         } else {
949                 /* Maybe use pNv->crtc_active[1], or is it too early for that? */
950                 if(pNv->twoHeads) {
951                         regp->head  =  savep->head | 0x00001000;
952                         if (is_fp) {
953                                 regp->head &= ~NV_CRTC_FSEL_FPP2;
954                                 regp->head |= NV_CRTC_FSEL_FPP1;
955                         } else {
956                                 regp->head &= ~NV_CRTC_FSEL_FPP1;
957                                 regp->head |= NV_CRTC_FSEL_FPP2;
958                         }
959
960                         regp->crtcOwner = 0;
961                 }
962         }
963
964         regp->cursorConfig = 0x00000100;
965         if(mode->Flags & V_DBLSCAN)
966                 regp->cursorConfig |= (1 << 4);
967         if(pNv->alphaCursor) {
968                 if((pNv->Chipset & 0x0ff0) != CHIPSET_NV11) {
969                         regp->cursorConfig |= 0x04011000;
970                 } else {
971                         regp->cursorConfig |= 0x14011000;
972                 }
973         } else {
974                 regp->cursorConfig |= 0x02000000;
975         }
976
977         regp->CRTC[NV_VGA_CRTCX_FP_HTIMING] = 0;
978         regp->CRTC[NV_VGA_CRTCX_FP_VTIMING] = 0;
979
980         regp->unk830 = mode->CrtcVDisplay - 3;
981         regp->unk834 = mode->CrtcVDisplay - 1;
982 }
983
984 /**
985  * Sets up registers for the given mode/adjusted_mode pair.
986  *
987  * The clocks, CRTCs and outputs attached to this CRTC must be off.
988  *
989  * This shouldn't enable any clocks, CRTCs, or outputs, but they should
990  * be easily turned on/off after this.
991  */
992 static void
993 nv_crtc_mode_set(xf86CrtcPtr crtc, DisplayModePtr mode,
994                  DisplayModePtr adjusted_mode,
995                  int x, int y)
996 {
997     ScrnInfoPtr pScrn = crtc->scrn;
998     NVCrtcPrivatePtr nv_crtc = crtc->driver_private;
999     NVPtr pNv = NVPTR(pScrn);
1000
1001     xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "Mode on CRTC %d\n", nv_crtc->crtc);
1002     xf86PrintModeline(pScrn->scrnIndex, mode);
1003     NVCrtcSetOwner(crtc);
1004
1005     nv_crtc_mode_set_vga(crtc, mode);
1006     nv_crtc_mode_set_regs(crtc, mode);
1007
1008
1009     NVVgaProtect(crtc, TRUE);
1010     nv_crtc_load_state_ext(crtc, &pNv->ModeReg);
1011     nv_crtc_load_state_vga(crtc, &pNv->ModeReg);
1012     nv_crtc_load_state_pll(pNv, &pNv->ModeReg);
1013
1014     NVVgaProtect(crtc, FALSE);
1015     //    NVCrtcLockUnlock(crtc, 1);
1016
1017     NVCrtcSetBase(crtc, x, y);
1018 #if X_BYTE_ORDER == X_BIG_ENDIAN
1019     /* turn on LFB swapping */
1020     {
1021         unsigned char tmp;
1022
1023         tmp = NVReadVgaCrtc(crtc, NV_VGA_CRTCX_SWAPPING);
1024         tmp |= (1 << 7);
1025         NVWriteVgaCrtc(crtc, NV_VGA_CRTCX_SWAPPING, tmp);
1026     }
1027 #endif
1028
1029 }
1030
1031 void nv_crtc_save(xf86CrtcPtr crtc)
1032 {
1033     ScrnInfoPtr pScrn = crtc->scrn;
1034     NVCrtcPrivatePtr nv_crtc = crtc->driver_private;
1035     NVPtr pNv = NVPTR(pScrn);
1036
1037     NVCrtcSetOwner(crtc);
1038     nv_crtc_save_state_pll(pNv, &pNv->SavedReg);
1039     nv_crtc_save_state_vga(crtc, &pNv->SavedReg);
1040     nv_crtc_save_state_ext(crtc, &pNv->SavedReg);
1041
1042 }
1043
1044 void nv_crtc_restore(xf86CrtcPtr crtc)
1045 {
1046     ScrnInfoPtr pScrn = crtc->scrn;
1047     NVCrtcPrivatePtr nv_crtc = crtc->driver_private;
1048     NVPtr pNv = NVPTR(pScrn);
1049
1050     NVCrtcSetOwner(crtc);    
1051     nv_crtc_load_state_ext(crtc, &pNv->SavedReg);
1052     nv_crtc_load_state_vga(crtc, &pNv->SavedReg);
1053     nv_crtc_load_state_pll(pNv, &pNv->SavedReg);
1054     nvWriteVGA(pNv, NV_VGA_CRTCX_OWNER, pNv->vtOWNER);
1055
1056 }
1057
1058 void nv_crtc_prepare(xf86CrtcPtr crtc)
1059 {
1060     ScrnInfoPtr pScrn = crtc->scrn;
1061     NVPtr pNv = NVPTR(pScrn);
1062
1063     /* Sync the engine before adjust mode */
1064     if (pNv->EXADriverPtr) {
1065         exaMarkSync(pScrn->pScreen);
1066         exaWaitSync(pScrn->pScreen);
1067     }
1068 }
1069
1070 void nv_crtc_commit(xf86CrtcPtr crtc)
1071 {
1072
1073
1074 }
1075
1076 static Bool nv_crtc_lock(xf86CrtcPtr crtc)
1077 {
1078         return FALSE;
1079 }
1080
1081 static void nv_crtc_unlock(xf86CrtcPtr crtc)
1082 {
1083
1084 }
1085
1086 static const xf86CrtcFuncsRec nv_crtc_funcs = {
1087     .dpms = nv_crtc_dpms,
1088     .save = nv_crtc_save, /* XXX */
1089     .restore = nv_crtc_restore, /* XXX */
1090     .mode_fixup = nv_crtc_mode_fixup,
1091     .mode_set = nv_crtc_mode_set,
1092     .prepare = nv_crtc_prepare,
1093     .commit = nv_crtc_commit,
1094     .destroy = NULL, /* XXX */
1095     .lock = nv_crtc_lock,
1096     .unlock = nv_crtc_unlock,
1097 };
1098
1099 void
1100 nv_crtc_init(ScrnInfoPtr pScrn, int crtc_num)
1101 {
1102     NVPtr pNv = NVPTR(pScrn);
1103     xf86CrtcPtr crtc;
1104     NVCrtcPrivatePtr nv_crtc;
1105
1106     crtc = xf86CrtcCreate (pScrn, &nv_crtc_funcs);
1107     if (crtc == NULL)
1108         return;
1109
1110     nv_crtc = xnfcalloc (sizeof (NVCrtcPrivateRec), 1);
1111     nv_crtc->crtc = crtc_num;
1112     /* This is usefull to do stuff from crtc functions */
1113     nv_crtc->pNv = pNv;
1114
1115     crtc->driver_private = nv_crtc;
1116
1117     NVCrtcLockUnlock(crtc, 0);
1118
1119 }
1120
1121 static void nv_crtc_load_state_vga(xf86CrtcPtr crtc, RIVA_HW_STATE *state)
1122 {
1123     ScrnInfoPtr pScrn = crtc->scrn;
1124     NVPtr pNv = NVPTR(pScrn);    
1125     NVCrtcPrivatePtr nv_crtc = crtc->driver_private;
1126     int i, j;
1127     CARD32 temp;
1128     NVCrtcRegPtr regp;
1129
1130     regp = &state->crtc_reg[nv_crtc->crtc];
1131
1132     NVWriteMiscOut(crtc, regp->MiscOutReg);
1133
1134     for (i = 1; i < 5; i++)
1135       NVWriteVgaSeq(crtc, i, regp->Sequencer[i]);
1136   
1137     /* Ensure CRTC registers 0-7 are unlocked by clearing bit 7 of CRTC[17] */
1138     NVWriteVgaCrtc(crtc, 17, regp->CRTC[17] & ~0x80);
1139
1140     for (i = 0; i < 25; i++)
1141       NVWriteVgaCrtc(crtc, i, regp->CRTC[i]);
1142
1143     for (i = 0; i < 9; i++)
1144       NVWriteVgaGr(crtc, i, regp->Graphics[i]);
1145     
1146     NVEnablePalette(crtc);
1147     for (i = 0; i < 21; i++)
1148       NVWriteVgaAttr(crtc, i, regp->Attribute[i]);
1149     NVDisablePalette(crtc);
1150
1151 }
1152
1153 static void nv_crtc_fix_nv40_hw_cursor(xf86CrtcPtr crtc)
1154 {
1155   /* TODO - implement this properly */
1156   ScrnInfoPtr pScrn = crtc->scrn;
1157   NVPtr pNv = NVPTR(pScrn);
1158    
1159   if(pNv->Architecture == NV_ARCH_40) {  /* HW bug */
1160     volatile CARD32 curpos = nvReadCurRAMDAC(pNv, NV_RAMDAC_CURSOR_POS);
1161     nvWriteCurRAMDAC(pNv, NV_RAMDAC_CURSOR_POS, curpos);
1162   }
1163
1164 }
1165 static void nv_crtc_load_state_ext(xf86CrtcPtr crtc, RIVA_HW_STATE *state)
1166 {
1167     ScrnInfoPtr pScrn = crtc->scrn;
1168     NVPtr pNv = NVPTR(pScrn);    
1169     NVCrtcPrivatePtr nv_crtc = crtc->driver_private;
1170     int i, j;
1171     CARD32 temp;
1172     NVCrtcRegPtr regp;
1173     
1174     regp = &state->crtc_reg[nv_crtc->crtc];
1175
1176     if(pNv->Architecture >= NV_ARCH_10) {
1177         if(pNv->twoHeads) {
1178            nvWriteCRTC(pNv, nv_crtc->crtc, NV_CRTC_FSEL, regp->head);
1179         }
1180         nvWriteVIDEO(pNv, NV_PVIDEO_STOP, 1);
1181         nvWriteVIDEO(pNv, NV_PVIDEO_INTR_EN, 0);
1182         nvWriteVIDEO(pNv, NV_PVIDEO_OFFSET_BUFF(0), 0);
1183         nvWriteVIDEO(pNv, NV_PVIDEO_OFFSET_BUFF(1), 0);
1184         nvWriteVIDEO(pNv, NV_PVIDEO_LIMIT(0), pNv->VRAMPhysicalSize - 1);
1185         nvWriteVIDEO(pNv, NV_PVIDEO_LIMIT(1), pNv->VRAMPhysicalSize - 1);
1186         nvWriteMC(pNv, 0x1588, 0);
1187
1188         NVWriteVgaCrtc(crtc, NV_VGA_CRTCX_BUFFER, 0xff);
1189         NVWriteVgaCrtc(crtc, NV_VGA_CRTCX_BUFFER, regp->CRTC[NV_VGA_CRTCX_BUFFER]);
1190         nvWriteCRTC(pNv, nv_crtc->crtc, NV_CRTC_CURSOR_CONFIG, regp->cursorConfig);
1191         nvWriteCRTC(pNv, nv_crtc->crtc, NV_CRTC_0830, regp->unk830);
1192         nvWriteCRTC(pNv, nv_crtc->crtc, NV_CRTC_0834, regp->unk834);
1193         
1194         NVWriteVgaCrtc(crtc, NV_VGA_CRTCX_FP_HTIMING, regp->CRTC[NV_VGA_CRTCX_FP_HTIMING]);
1195         NVWriteVgaCrtc(crtc, NV_VGA_CRTCX_FP_VTIMING, regp->CRTC[NV_VGA_CRTCX_FP_VTIMING]);
1196
1197         NVWriteVgaCrtc(crtc, NV_VGA_CRTCX_59, regp->CRTC[NV_VGA_CRTCX_59]);
1198         NVWriteVgaCrtc(crtc, NV_VGA_CRTCX_EXTRA, regp->CRTC[NV_VGA_CRTCX_EXTRA]);
1199     }
1200
1201     NVWriteVgaCrtc(crtc, NV_VGA_CRTCX_REPAINT0, regp->CRTC[NV_VGA_CRTCX_REPAINT0]);
1202     NVWriteVgaCrtc(crtc, NV_VGA_CRTCX_REPAINT1, regp->CRTC[NV_VGA_CRTCX_REPAINT1]);
1203     NVWriteVgaCrtc(crtc, NV_VGA_CRTCX_LSR, regp->CRTC[NV_VGA_CRTCX_LSR]);
1204     NVWriteVgaCrtc(crtc, NV_VGA_CRTCX_PIXEL, regp->CRTC[NV_VGA_CRTCX_PIXEL]);
1205     NVWriteVgaCrtc(crtc, NV_VGA_CRTCX_LCD, regp->CRTC[NV_VGA_CRTCX_LCD]);
1206     NVWriteVgaCrtc(crtc, NV_VGA_CRTCX_HEB, regp->CRTC[NV_VGA_CRTCX_HEB]);
1207     NVWriteVgaCrtc(crtc, NV_VGA_CRTCX_FIFO1, regp->CRTC[NV_VGA_CRTCX_FIFO1]);
1208     NVWriteVgaCrtc(crtc, NV_VGA_CRTCX_FIFO0, regp->CRTC[NV_VGA_CRTCX_FIFO0]);
1209     NVWriteVgaCrtc(crtc, NV_VGA_CRTCX_FIFO_LWM, regp->CRTC[NV_VGA_CRTCX_FIFO_LWM]);
1210     if(pNv->Architecture >= NV_ARCH_30) {
1211       NVWriteVgaCrtc(crtc, NV_VGA_CRTCX_FIFO_LWM_NV30, regp->CRTC[NV_VGA_CRTCX_FIFO_LWM_NV30]);
1212     }
1213
1214     NVWriteVgaCrtc(crtc, NV_VGA_CRTCX_CURCTL0, regp->CRTC[NV_VGA_CRTCX_CURCTL0]);
1215     NVWriteVgaCrtc(crtc, NV_VGA_CRTCX_CURCTL1, regp->CRTC[NV_VGA_CRTCX_CURCTL1]);
1216     nv_crtc_fix_nv40_hw_cursor(crtc);
1217     NVWriteVgaCrtc(crtc, NV_VGA_CRTCX_CURCTL2, regp->CRTC[NV_VGA_CRTCX_CURCTL2]);
1218     NVWriteVgaCrtc(crtc, NV_VGA_CRTCX_INTERLACE, regp->CRTC[NV_VGA_CRTCX_INTERLACE]);
1219
1220     nvWriteCRTC(pNv, nv_crtc->crtc, NV_CRTC_INTR_EN_0, 0);
1221     nvWriteCRTC(pNv, nv_crtc->crtc, NV_CRTC_INTR_0, NV_CRTC_INTR_VBLANK);
1222
1223     pNv->CurrentState = state;
1224 }
1225
1226 static void nv_crtc_save_state_vga(xf86CrtcPtr crtc, RIVA_HW_STATE *state)
1227 {
1228     ScrnInfoPtr pScrn = crtc->scrn;
1229     NVPtr pNv = NVPTR(pScrn);    
1230     NVCrtcPrivatePtr nv_crtc = crtc->driver_private;
1231     int i;
1232     NVCrtcRegPtr regp;
1233
1234     regp = &state->crtc_reg[nv_crtc->crtc];
1235
1236     regp->MiscOutReg = NVReadMiscOut(crtc);
1237
1238     for (i = 0; i < 25; i++)
1239         regp->CRTC[i] = NVReadVgaCrtc(crtc, i);
1240
1241     NVEnablePalette(crtc);
1242     for (i = 0; i < 21; i++)
1243         regp->Attribute[i] = NVReadVgaAttr(crtc, i);
1244     NVDisablePalette(crtc);
1245
1246     for (i = 0; i < 9; i++)
1247         regp->Graphics[i] = NVReadVgaGr(crtc, i);
1248
1249     for (i = 1; i < 5; i++)
1250         regp->Sequencer[i] = NVReadVgaSeq(crtc, i);
1251   
1252 }
1253
1254 static void nv_crtc_save_state_ext(xf86CrtcPtr crtc, RIVA_HW_STATE *state)
1255 {
1256     ScrnInfoPtr pScrn = crtc->scrn;
1257     NVPtr pNv = NVPTR(pScrn);    
1258     NVCrtcPrivatePtr nv_crtc = crtc->driver_private;
1259     NVCrtcRegPtr regp;
1260     int i;
1261
1262     regp = &state->crtc_reg[nv_crtc->crtc];
1263  
1264     regp->CRTC[NV_VGA_CRTCX_59] = NVReadVgaCrtc(crtc, NV_VGA_CRTCX_59);
1265     regp->CRTC[NV_VGA_CRTCX_LCD] = NVReadVgaCrtc(crtc, NV_VGA_CRTCX_LCD);
1266     regp->CRTC[NV_VGA_CRTCX_REPAINT0] = NVReadVgaCrtc(crtc, NV_VGA_CRTCX_REPAINT0);
1267     regp->CRTC[NV_VGA_CRTCX_REPAINT1] = NVReadVgaCrtc(crtc, NV_VGA_CRTCX_REPAINT1);
1268     regp->CRTC[NV_VGA_CRTCX_LSR] = NVReadVgaCrtc(crtc, NV_VGA_CRTCX_LSR);
1269     regp->CRTC[NV_VGA_CRTCX_PIXEL] = NVReadVgaCrtc(crtc, NV_VGA_CRTCX_PIXEL);
1270     regp->CRTC[NV_VGA_CRTCX_HEB] = NVReadVgaCrtc(crtc, NV_VGA_CRTCX_HEB);
1271     regp->CRTC[NV_VGA_CRTCX_FIFO1] = NVReadVgaCrtc(crtc, NV_VGA_CRTCX_FIFO1);
1272
1273     regp->CRTC[NV_VGA_CRTCX_FIFO0] = NVReadVgaCrtc(crtc, NV_VGA_CRTCX_FIFO0);
1274     regp->CRTC[NV_VGA_CRTCX_FIFO_LWM] = NVReadVgaCrtc(crtc, NV_VGA_CRTCX_FIFO_LWM);
1275     if(pNv->Architecture >= NV_ARCH_30) {
1276          regp->CRTC[NV_VGA_CRTCX_FIFO_LWM_NV30] = NVReadVgaCrtc(crtc, NV_VGA_CRTCX_FIFO_LWM_NV30);
1277     }
1278     regp->CRTC[NV_VGA_CRTCX_CURCTL0] = NVReadVgaCrtc(crtc, NV_VGA_CRTCX_CURCTL0);
1279     regp->CRTC[NV_VGA_CRTCX_CURCTL1] = NVReadVgaCrtc(crtc, NV_VGA_CRTCX_CURCTL1);
1280     regp->CRTC[NV_VGA_CRTCX_CURCTL2] = NVReadVgaCrtc(crtc, NV_VGA_CRTCX_CURCTL2);
1281     regp->CRTC[NV_VGA_CRTCX_INTERLACE] = NVReadVgaCrtc(crtc, NV_VGA_CRTCX_INTERLACE);
1282  
1283     regp->unk830 = nvReadCRTC(pNv, nv_crtc->crtc, NV_CRTC_0830);
1284     regp->unk834 = nvReadCRTC(pNv, nv_crtc->crtc, NV_CRTC_0834);
1285
1286     if(pNv->Architecture >= NV_ARCH_10) {
1287         if(pNv->twoHeads) {
1288            regp->head     = nvReadCRTC(pNv, nv_crtc->crtc, NV_CRTC_FSEL);
1289            regp->crtcOwner = NVReadVgaCrtc(crtc, NV_VGA_CRTCX_OWNER);
1290         }
1291         regp->CRTC[NV_VGA_CRTCX_EXTRA] = NVReadVgaCrtc(crtc, NV_VGA_CRTCX_EXTRA);
1292
1293         regp->cursorConfig = nvReadCRTC(pNv, nv_crtc->crtc, NV_CRTC_CURSOR_CONFIG);
1294
1295         regp->CRTC[NV_VGA_CRTCX_BUFFER] = NVReadVgaCrtc(crtc, NV_VGA_CRTCX_BUFFER);
1296         regp->CRTC[NV_VGA_CRTCX_FP_HTIMING] = NVReadVgaCrtc(crtc, NV_VGA_CRTCX_FP_HTIMING);
1297         regp->CRTC[NV_VGA_CRTCX_FP_VTIMING] = NVReadVgaCrtc(crtc, NV_VGA_CRTCX_FP_VTIMING);
1298     }
1299 }
1300
1301 void
1302 NVCrtcSetBase (xf86CrtcPtr crtc, int x, int y)
1303 {
1304     ScrnInfoPtr pScrn = crtc->scrn;
1305     NVPtr pNv = NVPTR(pScrn);    
1306     NVCrtcPrivatePtr nv_crtc = crtc->driver_private;
1307     NVFBLayout *pLayout = &pNv->CurrentLayout;
1308     CARD32 start = 0;
1309     
1310     start += ((y * pScrn->displayWidth + x) * (pLayout->bitsPerPixel/8));
1311     start += pNv->FB->offset;
1312
1313     nvWriteCRTC(pNv, nv_crtc->crtc, NV_CRTC_START, start);
1314
1315     crtc->x = x;
1316     crtc->y = y;
1317 }
1318
1319 void NVCrtcSetCursor(xf86CrtcPtr crtc, Bool state)
1320 {
1321   int current = NVReadVgaCrtc(crtc, NV_VGA_CRTCX_CURCTL1);
1322
1323   if(state) 
1324     current |= 1;
1325   else
1326     current &= ~1;
1327
1328   NVWriteVgaCrtc(crtc, NV_VGA_CRTCX_CURCTL1, current);
1329 }
1330
1331 void NVSetMode(ScrnInfoPtr pScrn, DisplayModePtr mode)
1332 {
1333         xf86CrtcConfigPtr   xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
1334         int i;
1335         for (i = 0; i < xf86_config->num_crtc; i++) {
1336                 if (xf86_config->crtc[i]->enabled) {
1337                         nv_crtc_mode_set(xf86_config->crtc[i], mode, NULL, 0,0);
1338                 }
1339         }
1340 }
1341
1342 static void NVCrtcWriteDacMask(xf86CrtcPtr crtc, CARD8 value)
1343 {
1344   ScrnInfoPtr pScrn = crtc->scrn;
1345   NVCrtcPrivatePtr nv_crtc = crtc->driver_private;
1346   NVPtr pNv = NVPTR(pScrn);
1347   volatile CARD8 *pDACReg = nv_crtc->crtc ? pNv->PDIO1 : pNv->PDIO0;
1348
1349   NV_WR08(pDACReg, VGA_DAC_MASK, value);
1350 }
1351
1352 static CARD8 NVCrtcReadDacMask(xf86CrtcPtr crtc)
1353 {
1354   ScrnInfoPtr pScrn = crtc->scrn;
1355   NVCrtcPrivatePtr nv_crtc = crtc->driver_private;
1356   NVPtr pNv = NVPTR(pScrn);
1357   volatile CARD8 *pDACReg = nv_crtc->crtc ? pNv->PDIO1 : pNv->PDIO0;
1358   
1359   return NV_RD08(pDACReg, VGA_DAC_MASK);
1360 }
1361
1362 static void NVCrtcWriteDacReadAddr(xf86CrtcPtr crtc, CARD8 value)
1363 {
1364   ScrnInfoPtr pScrn = crtc->scrn;
1365   NVCrtcPrivatePtr nv_crtc = crtc->driver_private;
1366   NVPtr pNv = NVPTR(pScrn);
1367   volatile CARD8 *pDACReg = nv_crtc->crtc ? pNv->PDIO1 : pNv->PDIO0;
1368
1369   NV_WR08(pDACReg, VGA_DAC_READ_ADDR, value);
1370 }
1371
1372 static void NVCrtcWriteDacWriteAddr(xf86CrtcPtr crtc, CARD8 value)
1373 {
1374   ScrnInfoPtr pScrn = crtc->scrn;
1375   NVCrtcPrivatePtr nv_crtc = crtc->driver_private;
1376   NVPtr pNv = NVPTR(pScrn);
1377   volatile CARD8 *pDACReg = nv_crtc->crtc ? pNv->PDIO1 : pNv->PDIO0;
1378
1379   NV_WR08(pDACReg, VGA_DAC_WRITE_ADDR, value);
1380 }
1381
1382 static void NVCrtcWriteDacData(xf86CrtcPtr crtc, CARD8 value)
1383 {
1384   ScrnInfoPtr pScrn = crtc->scrn;
1385   NVCrtcPrivatePtr nv_crtc = crtc->driver_private;
1386   NVPtr pNv = NVPTR(pScrn);
1387   volatile CARD8 *pDACReg = nv_crtc->crtc ? pNv->PDIO1 : pNv->PDIO0;
1388
1389   NV_WR08(pDACReg, VGA_DAC_DATA, value);
1390 }
1391
1392 static CARD8 NVCrtcReadDacData(xf86CrtcPtr crtc, CARD8 value)
1393 {
1394   ScrnInfoPtr pScrn = crtc->scrn;
1395   NVCrtcPrivatePtr nv_crtc = crtc->driver_private;
1396   NVPtr pNv = NVPTR(pScrn);
1397   volatile CARD8 *pDACReg = nv_crtc->crtc ? pNv->PDIO1 : pNv->PDIO0;
1398
1399   return NV_RD08(pDACReg, VGA_DAC_DATA);
1400 }
1401
1402 void NVCrtcLoadPalette(xf86CrtcPtr crtc)
1403 {
1404   int i;
1405   NVCrtcPrivatePtr nv_crtc = crtc->driver_private;
1406   NVCrtcRegPtr regp;
1407   ScrnInfoPtr pScrn = crtc->scrn;
1408   NVPtr pNv = NVPTR(pScrn);
1409     
1410   regp = &pNv->ModeReg.crtc_reg[nv_crtc->crtc];
1411
1412   NVWriteVgaCrtc(crtc, NV_VGA_CRTCX_OWNER, nv_crtc->crtc * 0x3);
1413   NVCrtcWriteDacMask(crtc, 0xff);
1414   NVCrtcWriteDacWriteAddr(crtc, 0x00);
1415
1416   for (i = 0; i<768; i++) {
1417     NVCrtcWriteDacData(crtc, regp->DAC[i]);
1418   }
1419   NVDisablePalette(crtc);
1420 }
1421
1422 void NVCrtcBlankScreen(xf86CrtcPtr crtc, Bool on)
1423 {
1424     NVCrtcPrivatePtr nv_crtc = crtc->driver_private;
1425     unsigned char scrn;
1426
1427     NVWriteVgaCrtc(crtc, NV_VGA_CRTCX_OWNER, nv_crtc->crtc * 0x3);
1428
1429     scrn = NVReadVgaSeq(crtc, 0x01);
1430     if (on) {
1431         scrn &= ~0x20;
1432     } else {
1433         scrn |= 0x20;
1434     }
1435
1436     NVVgaSeqReset(crtc, TRUE);
1437     NVWriteVgaSeq(crtc, 0x01, scrn);
1438     NVVgaSeqReset(crtc, FALSE);
1439 }
1440
1441 /*************************************************************************** \
1442 |*                                                                           *|
1443 |*       Copyright 1993-2003 NVIDIA, Corporation.  All rights reserved.      *|
1444 |*                                                                           *|
1445 |*     NOTICE TO USER:   The source code  is copyrighted under  U.S. and     *|
1446 |*     international laws.  Users and possessors of this source code are     *|
1447 |*     hereby granted a nonexclusive,  royalty-free copyright license to     *|
1448 |*     use this code in individual and commercial software.                  *|
1449 |*                                                                           *|
1450 |*     Any use of this source code must include,  in the user documenta-     *|
1451 |*     tion and  internal comments to the code,  notices to the end user     *|
1452 |*     as follows:                                                           *|
1453 |*                                                                           *|
1454 |*       Copyright 1993-1999 NVIDIA, Corporation.  All rights reserved.      *|
1455 |*                                                                           *|
1456 |*     NVIDIA, CORPORATION MAKES NO REPRESENTATION ABOUT THE SUITABILITY     *|
1457 |*     OF  THIS SOURCE  CODE  FOR ANY PURPOSE.  IT IS  PROVIDED  "AS IS"     *|
1458 |*     WITHOUT EXPRESS OR IMPLIED WARRANTY OF ANY KIND.  NVIDIA, CORPOR-     *|
1459 |*     ATION DISCLAIMS ALL WARRANTIES  WITH REGARD  TO THIS SOURCE CODE,     *|
1460 |*     INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGE-     *|
1461 |*     MENT,  AND FITNESS  FOR A PARTICULAR PURPOSE.   IN NO EVENT SHALL     *|
1462 |*     NVIDIA, CORPORATION  BE LIABLE FOR ANY SPECIAL,  INDIRECT,  INCI-     *|
1463 |*     DENTAL, OR CONSEQUENTIAL DAMAGES,  OR ANY DAMAGES  WHATSOEVER RE-     *|
1464 |*     SULTING FROM LOSS OF USE,  DATA OR PROFITS,  WHETHER IN AN ACTION     *|
1465 |*     OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,  ARISING OUT OF     *|
1466 |*     OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOURCE CODE.     *|
1467 |*                                                                           *|
1468 |*     U.S. Government  End  Users.   This source code  is a "commercial     *|
1469 |*     item,"  as that  term is  defined at  48 C.F.R. 2.101 (OCT 1995),     *|
1470 |*     consisting  of "commercial  computer  software"  and  "commercial     *|
1471 |*     computer  software  documentation,"  as such  terms  are  used in     *|
1472 |*     48 C.F.R. 12.212 (SEPT 1995)  and is provided to the U.S. Govern-     *|
1473 |*     ment only as  a commercial end item.   Consistent with  48 C.F.R.     *|
1474 |*     12.212 and  48 C.F.R. 227.7202-1 through  227.7202-4 (JUNE 1995),     *|
1475 |*     all U.S. Government End Users  acquire the source code  with only     *|
1476 |*     those rights set forth herein.                                        *|
1477 |*                                                                           *|
1478  \***************************************************************************/