Some more indenting and such.
[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 /* This should accomodate up to 65535x65535 */
759 #define NOUVEAU_RES(_h_res, _v_res) ((_h_res << 16) | _v_res)
760
761 /* These are timing modes for DFP's */
762 /* These are not neccesarily correct, just our best guess */
763 struct timing_modes {
764         uint32_t res;
765         uint8_t htiming;
766         uint8_t vtiming;
767 } known_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},
772         {0, 0, 0}
773 };
774
775
776 /**
777  * Sets up registers for the given mode/adjusted_mode pair.
778  *
779  * The clocks, CRTCs and outputs attached to this CRTC must be off.
780  *
781  * This shouldn't enable any clocks, CRTCs, or outputs, but they should
782  * be easily turned on/off after this.
783  */
784 static void
785 nv_crtc_mode_set_regs(xf86CrtcPtr crtc, DisplayModePtr mode)
786 {
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;
794         unsigned int i;
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? */
808         Bool is_fp = FALSE;
809
810         for (i = 0; i < xf86_config->num_output; i++) {
811                 xf86OutputPtr  output = xf86_config->output[i];
812                 NVOutputPrivatePtr nv_output = output->driver_private;
813
814                 if (output->crtc == crtc) {
815                         if ((nv_output->type == OUTPUT_PANEL) || 
816                                 (nv_output->type == OUTPUT_DIGITAL)) {
817
818                                 is_fp = TRUE;
819                         }
820                 }
821         }
822
823         regp = &pNv->ModeReg.crtc_reg[nv_crtc->crtc];    
824         savep = &pNv->SavedReg.crtc_reg[nv_crtc->crtc];
825
826         if(mode->Flags & V_INTERLACE) 
827                 vertTotal |= 1;
828
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) 
833                                 | SetBit(7);
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)
842                                 | SetBit(4)
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)
847                                 | SetBit(6)
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);
855
856         regp->Attribute[0x10] = 0x01;
857
858         if(pNv->Television)
859                 regp->Attribute[0x11] = 0x00;
860
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);
866
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);
871
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);
876
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);
881         } else {
882                 regp->CRTC[NV_VGA_CRTCX_INTERLACE] = 0xff;  /* interlace off */
883         }
884
885         regp->CRTC[NV_VGA_CRTCX_BUFFER] = 0xfa;
886     
887         if (is_fp) {
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;
891         } else {
892                 regp->CRTC[NV_VGA_CRTCX_LCD] = savep->CRTC[NV_VGA_CRTCX_LCD] & ~1;
893         }
894
895         /*
896         * Initialize DAC palette.
897         */
898         if(pLayout->bitsPerPixel != 8 ) {
899                 for (i = 0; i < 256; i++) {
900                         regp->DAC[i*3]     = i;
901                         regp->DAC[(i*3)+1] = i;
902                         regp->DAC[(i*3)+2] = i;
903                 }
904         }
905
906         /*
907         * Calculate the extended registers.
908         */
909
910         if(pLayout->depth < 24) {
911                 i = pLayout->depth;
912         } else {
913                 i = 32;
914         }
915
916         if(pNv->Architecture >= NV_ARCH_10) {
917                 pNv->CURSOR = (CARD32 *)pNv->Cursor->map;
918         }
919
920         ErrorF("crtc %d %d %d\n", nv_crtc->crtc, mode->CrtcHDisplay, pLayout->displayWidth);
921         nv_crtc_calc_state_ext(crtc,
922                                 i,
923                                 pLayout->displayWidth,
924                                 mode->CrtcHDisplay,
925                                 mode->CrtcVDisplay,
926                                 mode->Clock,
927                                 mode->Flags);
928
929         if (is_fp) {
930                 regp->CRTC[NV_VGA_CRTCX_PIXEL] |= (1 << 7);
931         }
932
933         regp->CRTC[NV_VGA_CRTCX_FIFO1] = savep->CRTC[NV_VGA_CRTCX_FIFO1] & ~(1<<5);
934
935         if(nv_crtc->crtc) {
936                 if (is_fp) {
937                         regp->head &= ~NV_CRTC_FSEL_FPP2;
938                         regp->head |= NV_CRTC_FSEL_FPP1;
939                 } else {
940                         regp->head &= ~NV_CRTC_FSEL_FPP1;
941                         regp->head |= NV_CRTC_FSEL_FPP2;
942                 }
943
944                 regp->crtcOwner = 3;
945         /* only enable secondary pllsel if CRTC 1 is selected on */
946         } else {
947                 /* Maybe use pNv->crtc_active[1], or is it too early for that? */
948                 if(pNv->twoHeads) {
949                         regp->head  =  savep->head | 0x00001000;
950                         if (is_fp) {
951                                 regp->head &= ~NV_CRTC_FSEL_FPP2;
952                                 regp->head |= NV_CRTC_FSEL_FPP1;
953                         } else {
954                                 regp->head &= ~NV_CRTC_FSEL_FPP1;
955                                 regp->head |= NV_CRTC_FSEL_FPP2;
956                         }
957
958                         regp->crtcOwner = 0;
959                 }
960         }
961
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;
968                 } else {
969                         regp->cursorConfig |= 0x14011000;
970                 }
971         } else {
972                 regp->cursorConfig |= 0x02000000;
973         }
974
975         regp->CRTC[NV_VGA_CRTCX_FP_HTIMING] = 0;
976         regp->CRTC[NV_VGA_CRTCX_FP_VTIMING] = 0;
977
978         regp->unk830 = mode->CrtcVDisplay - 3;
979         regp->unk834 = mode->CrtcVDisplay - 1;
980 }
981
982 /**
983  * Sets up registers for the given mode/adjusted_mode pair.
984  *
985  * The clocks, CRTCs and outputs attached to this CRTC must be off.
986  *
987  * This shouldn't enable any clocks, CRTCs, or outputs, but they should
988  * be easily turned on/off after this.
989  */
990 static void
991 nv_crtc_mode_set(xf86CrtcPtr crtc, DisplayModePtr mode,
992                  DisplayModePtr adjusted_mode,
993                  int x, int y)
994 {
995     ScrnInfoPtr pScrn = crtc->scrn;
996     NVCrtcPrivatePtr nv_crtc = crtc->driver_private;
997     NVPtr pNv = NVPTR(pScrn);
998
999     xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "Mode on CRTC %d\n", nv_crtc->crtc);
1000     xf86PrintModeline(pScrn->scrnIndex, mode);
1001     NVCrtcSetOwner(crtc);
1002
1003     nv_crtc_mode_set_vga(crtc, mode);
1004     nv_crtc_mode_set_regs(crtc, mode);
1005
1006
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);
1011
1012     NVVgaProtect(crtc, FALSE);
1013     //    NVCrtcLockUnlock(crtc, 1);
1014
1015     NVCrtcSetBase(crtc, x, y);
1016 #if X_BYTE_ORDER == X_BIG_ENDIAN
1017     /* turn on LFB swapping */
1018     {
1019         unsigned char tmp;
1020
1021         tmp = NVReadVgaCrtc(crtc, NV_VGA_CRTCX_SWAPPING);
1022         tmp |= (1 << 7);
1023         NVWriteVgaCrtc(crtc, NV_VGA_CRTCX_SWAPPING, tmp);
1024     }
1025 #endif
1026
1027 }
1028
1029 void nv_crtc_save(xf86CrtcPtr crtc)
1030 {
1031     ScrnInfoPtr pScrn = crtc->scrn;
1032     NVCrtcPrivatePtr nv_crtc = crtc->driver_private;
1033     NVPtr pNv = NVPTR(pScrn);
1034
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);
1039
1040 }
1041
1042 void nv_crtc_restore(xf86CrtcPtr crtc)
1043 {
1044     ScrnInfoPtr pScrn = crtc->scrn;
1045     NVCrtcPrivatePtr nv_crtc = crtc->driver_private;
1046     NVPtr pNv = NVPTR(pScrn);
1047
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);
1053
1054 }
1055
1056 void nv_crtc_prepare(xf86CrtcPtr crtc)
1057 {
1058     ScrnInfoPtr pScrn = crtc->scrn;
1059     NVPtr pNv = NVPTR(pScrn);
1060
1061     /* Sync the engine before adjust mode */
1062     if (pNv->EXADriverPtr) {
1063         exaMarkSync(pScrn->pScreen);
1064         exaWaitSync(pScrn->pScreen);
1065     }
1066 }
1067
1068 void nv_crtc_commit(xf86CrtcPtr crtc)
1069 {
1070
1071
1072 }
1073
1074 static Bool nv_crtc_lock(xf86CrtcPtr crtc)
1075 {
1076         return FALSE;
1077 }
1078
1079 static void nv_crtc_unlock(xf86CrtcPtr crtc)
1080 {
1081
1082 }
1083
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,
1095 };
1096
1097 void
1098 nv_crtc_init(ScrnInfoPtr pScrn, int crtc_num)
1099 {
1100     NVPtr pNv = NVPTR(pScrn);
1101     xf86CrtcPtr crtc;
1102     NVCrtcPrivatePtr nv_crtc;
1103
1104     crtc = xf86CrtcCreate (pScrn, &nv_crtc_funcs);
1105     if (crtc == NULL)
1106         return;
1107
1108     nv_crtc = xnfcalloc (sizeof (NVCrtcPrivateRec), 1);
1109     nv_crtc->crtc = crtc_num;
1110     /* This is usefull to do stuff from crtc functions */
1111     nv_crtc->pNv = pNv;
1112
1113     crtc->driver_private = nv_crtc;
1114
1115     NVCrtcLockUnlock(crtc, 0);
1116
1117 }
1118
1119 static void nv_crtc_load_state_vga(xf86CrtcPtr crtc, RIVA_HW_STATE *state)
1120 {
1121     ScrnInfoPtr pScrn = crtc->scrn;
1122     NVPtr pNv = NVPTR(pScrn);    
1123     NVCrtcPrivatePtr nv_crtc = crtc->driver_private;
1124     int i, j;
1125     CARD32 temp;
1126     NVCrtcRegPtr regp;
1127
1128     regp = &state->crtc_reg[nv_crtc->crtc];
1129
1130     NVWriteMiscOut(crtc, regp->MiscOutReg);
1131
1132     for (i = 1; i < 5; i++)
1133       NVWriteVgaSeq(crtc, i, regp->Sequencer[i]);
1134   
1135     /* Ensure CRTC registers 0-7 are unlocked by clearing bit 7 of CRTC[17] */
1136     NVWriteVgaCrtc(crtc, 17, regp->CRTC[17] & ~0x80);
1137
1138     for (i = 0; i < 25; i++)
1139       NVWriteVgaCrtc(crtc, i, regp->CRTC[i]);
1140
1141     for (i = 0; i < 9; i++)
1142       NVWriteVgaGr(crtc, i, regp->Graphics[i]);
1143     
1144     NVEnablePalette(crtc);
1145     for (i = 0; i < 21; i++)
1146       NVWriteVgaAttr(crtc, i, regp->Attribute[i]);
1147     NVDisablePalette(crtc);
1148
1149 }
1150
1151 static void nv_crtc_fix_nv40_hw_cursor(xf86CrtcPtr crtc)
1152 {
1153   /* TODO - implement this properly */
1154   ScrnInfoPtr pScrn = crtc->scrn;
1155   NVPtr pNv = NVPTR(pScrn);
1156    
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);
1160   }
1161
1162 }
1163 static void nv_crtc_load_state_ext(xf86CrtcPtr crtc, RIVA_HW_STATE *state)
1164 {
1165     ScrnInfoPtr pScrn = crtc->scrn;
1166     NVPtr pNv = NVPTR(pScrn);    
1167     NVCrtcPrivatePtr nv_crtc = crtc->driver_private;
1168     int i, j;
1169     CARD32 temp;
1170     NVCrtcRegPtr regp;
1171     
1172     regp = &state->crtc_reg[nv_crtc->crtc];
1173
1174     if(pNv->Architecture >= NV_ARCH_10) {
1175         if(pNv->twoHeads) {
1176            nvWriteCRTC(pNv, nv_crtc->crtc, NV_CRTC_FSEL, regp->head);
1177         }
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);
1185
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);
1191         
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]);
1194
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]);
1197     }
1198
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]);
1210     }
1211
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]);
1217
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);
1220
1221     pNv->CurrentState = state;
1222 }
1223
1224 static void nv_crtc_save_state_vga(xf86CrtcPtr crtc, RIVA_HW_STATE *state)
1225 {
1226     ScrnInfoPtr pScrn = crtc->scrn;
1227     NVPtr pNv = NVPTR(pScrn);    
1228     NVCrtcPrivatePtr nv_crtc = crtc->driver_private;
1229     int i;
1230     NVCrtcRegPtr regp;
1231
1232     regp = &state->crtc_reg[nv_crtc->crtc];
1233
1234     regp->MiscOutReg = NVReadMiscOut(crtc);
1235
1236     for (i = 0; i < 25; i++)
1237         regp->CRTC[i] = NVReadVgaCrtc(crtc, i);
1238
1239     NVEnablePalette(crtc);
1240     for (i = 0; i < 21; i++)
1241         regp->Attribute[i] = NVReadVgaAttr(crtc, i);
1242     NVDisablePalette(crtc);
1243
1244     for (i = 0; i < 9; i++)
1245         regp->Graphics[i] = NVReadVgaGr(crtc, i);
1246
1247     for (i = 1; i < 5; i++)
1248         regp->Sequencer[i] = NVReadVgaSeq(crtc, i);
1249   
1250 }
1251
1252 static void nv_crtc_save_state_ext(xf86CrtcPtr crtc, RIVA_HW_STATE *state)
1253 {
1254     ScrnInfoPtr pScrn = crtc->scrn;
1255     NVPtr pNv = NVPTR(pScrn);    
1256     NVCrtcPrivatePtr nv_crtc = crtc->driver_private;
1257     NVCrtcRegPtr regp;
1258     int i;
1259
1260     regp = &state->crtc_reg[nv_crtc->crtc];
1261  
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);
1270
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);
1275     }
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);
1280  
1281     regp->unk830 = nvReadCRTC(pNv, nv_crtc->crtc, NV_CRTC_0830);
1282     regp->unk834 = nvReadCRTC(pNv, nv_crtc->crtc, NV_CRTC_0834);
1283
1284     if(pNv->Architecture >= NV_ARCH_10) {
1285         if(pNv->twoHeads) {
1286            regp->head     = nvReadCRTC(pNv, nv_crtc->crtc, NV_CRTC_FSEL);
1287            regp->crtcOwner = NVReadVgaCrtc(crtc, NV_VGA_CRTCX_OWNER);
1288         }
1289         regp->CRTC[NV_VGA_CRTCX_EXTRA] = NVReadVgaCrtc(crtc, NV_VGA_CRTCX_EXTRA);
1290
1291         regp->cursorConfig = nvReadCRTC(pNv, nv_crtc->crtc, NV_CRTC_CURSOR_CONFIG);
1292
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);
1296     }
1297 }
1298
1299 void
1300 NVCrtcSetBase (xf86CrtcPtr crtc, int x, int y)
1301 {
1302     ScrnInfoPtr pScrn = crtc->scrn;
1303     NVPtr pNv = NVPTR(pScrn);    
1304     NVCrtcPrivatePtr nv_crtc = crtc->driver_private;
1305     NVFBLayout *pLayout = &pNv->CurrentLayout;
1306     CARD32 start = 0;
1307     
1308     start += ((y * pScrn->displayWidth + x) * (pLayout->bitsPerPixel/8));
1309     start += pNv->FB->offset;
1310
1311     nvWriteCRTC(pNv, nv_crtc->crtc, NV_CRTC_START, start);
1312
1313     crtc->x = x;
1314     crtc->y = y;
1315 }
1316
1317 void NVCrtcSetCursor(xf86CrtcPtr crtc, Bool state)
1318 {
1319   int current = NVReadVgaCrtc(crtc, NV_VGA_CRTCX_CURCTL1);
1320
1321   if(state) 
1322     current |= 1;
1323   else
1324     current &= ~1;
1325
1326   NVWriteVgaCrtc(crtc, NV_VGA_CRTCX_CURCTL1, current);
1327 }
1328
1329 void NVSetMode(ScrnInfoPtr pScrn, DisplayModePtr mode)
1330 {
1331         xf86CrtcConfigPtr   xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
1332         int i;
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);
1336                 }
1337         }
1338 }
1339
1340 static void NVCrtcWriteDacMask(xf86CrtcPtr crtc, CARD8 value)
1341 {
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;
1346
1347   NV_WR08(pDACReg, VGA_DAC_MASK, value);
1348 }
1349
1350 static CARD8 NVCrtcReadDacMask(xf86CrtcPtr crtc)
1351 {
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;
1356   
1357   return NV_RD08(pDACReg, VGA_DAC_MASK);
1358 }
1359
1360 static void NVCrtcWriteDacReadAddr(xf86CrtcPtr crtc, CARD8 value)
1361 {
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;
1366
1367   NV_WR08(pDACReg, VGA_DAC_READ_ADDR, value);
1368 }
1369
1370 static void NVCrtcWriteDacWriteAddr(xf86CrtcPtr crtc, CARD8 value)
1371 {
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;
1376
1377   NV_WR08(pDACReg, VGA_DAC_WRITE_ADDR, value);
1378 }
1379
1380 static void NVCrtcWriteDacData(xf86CrtcPtr crtc, CARD8 value)
1381 {
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;
1386
1387   NV_WR08(pDACReg, VGA_DAC_DATA, value);
1388 }
1389
1390 static CARD8 NVCrtcReadDacData(xf86CrtcPtr crtc, CARD8 value)
1391 {
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;
1396
1397   return NV_RD08(pDACReg, VGA_DAC_DATA);
1398 }
1399
1400 void NVCrtcLoadPalette(xf86CrtcPtr crtc)
1401 {
1402   int i;
1403   NVCrtcPrivatePtr nv_crtc = crtc->driver_private;
1404   NVCrtcRegPtr regp;
1405   ScrnInfoPtr pScrn = crtc->scrn;
1406   NVPtr pNv = NVPTR(pScrn);
1407     
1408   regp = &pNv->ModeReg.crtc_reg[nv_crtc->crtc];
1409
1410   NVWriteVgaCrtc(crtc, NV_VGA_CRTCX_OWNER, nv_crtc->crtc * 0x3);
1411   NVCrtcWriteDacMask(crtc, 0xff);
1412   NVCrtcWriteDacWriteAddr(crtc, 0x00);
1413
1414   for (i = 0; i<768; i++) {
1415     NVCrtcWriteDacData(crtc, regp->DAC[i]);
1416   }
1417   NVDisablePalette(crtc);
1418 }
1419
1420 void NVCrtcBlankScreen(xf86CrtcPtr crtc, Bool on)
1421 {
1422     NVCrtcPrivatePtr nv_crtc = crtc->driver_private;
1423     unsigned char scrn;
1424
1425     NVWriteVgaCrtc(crtc, NV_VGA_CRTCX_OWNER, nv_crtc->crtc * 0x3);
1426
1427     scrn = NVReadVgaSeq(crtc, 0x01);
1428     if (on) {
1429         scrn &= ~0x20;
1430     } else {
1431         scrn |= 0x20;
1432     }
1433
1434     NVVgaSeqReset(crtc, TRUE);
1435     NVWriteVgaSeq(crtc, 0x01, scrn);
1436     NVVgaSeqReset(crtc, FALSE);
1437 }
1438
1439 /*************************************************************************** \
1440 |*                                                                           *|
1441 |*       Copyright 1993-2003 NVIDIA, Corporation.  All rights reserved.      *|
1442 |*                                                                           *|
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.                  *|
1447 |*                                                                           *|
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     *|
1450 |*     as follows:                                                           *|
1451 |*                                                                           *|
1452 |*       Copyright 1993-1999 NVIDIA, Corporation.  All rights reserved.      *|
1453 |*                                                                           *|
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.     *|
1465 |*                                                                           *|
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.                                        *|
1475 |*                                                                           *|
1476  \***************************************************************************/