Merge branch 'randr-1.2' into nv50-branch
[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
526      NVCrtcSetOwner(crtc);
527
528      crtc1A = NVReadVgaCrtc(crtc, NV_VGA_CRTCX_REPAINT1) & ~0xC0;
529      switch(mode) {
530      case DPMSModeStandby:
531        /* Screen: Off; HSync: Off, VSync: On -- Not Supported */
532        seq1 = 0x20;
533        crtc17 = 0x80;
534        crtc1A |= 0x80;
535        break;
536      case DPMSModeSuspend:
537        /* Screen: Off; HSync: On, VSync: Off -- Not Supported */
538        seq1 = 0x20;
539        crtc17 = 0x80;
540        crtc1A |= 0x40;
541        break;
542      case DPMSModeOff:
543        /* Screen: Off; HSync: Off, VSync: Off */
544        seq1 = 0x20;
545        crtc17 = 0x00;
546        crtc1A |= 0xC0;
547        break;
548      case DPMSModeOn:
549      default:
550        /* Screen: On; HSync: On, VSync: On */
551        seq1 = 0x00;
552        crtc17 = 0x80;
553        break;
554      }
555
556      NVWriteVgaSeq(crtc, 0x00, 0x1);
557      seq1 = NVReadVgaSeq(crtc, 0x01) & ~0x20;
558      NVWriteVgaSeq(crtc, 0x1, seq1);
559      crtc17 |= NVReadVgaCrtc(crtc, NV_VGA_CRTCX_MODECTL) & ~0x80;
560      usleep(10000);
561      NVWriteVgaCrtc(crtc, NV_VGA_CRTCX_MODECTL, crtc17);
562      NVWriteVgaSeq(crtc, 0x0, 0x3);
563
564      NVWriteVgaCrtc(crtc, NV_VGA_CRTCX_REPAINT1, crtc1A);
565
566 }
567
568 static Bool
569 nv_crtc_mode_fixup(xf86CrtcPtr crtc, DisplayModePtr mode,
570                      DisplayModePtr adjusted_mode)
571 {
572     return TRUE;
573 }
574
575 static void
576 nv_crtc_mode_set_vga(xf86CrtcPtr crtc, DisplayModePtr mode)
577 {
578     ScrnInfoPtr pScrn = crtc->scrn;
579    NVCrtcPrivatePtr nv_crtc = crtc->driver_private;
580    NVCrtcRegPtr regp;
581    NVPtr pNv = NVPTR(pScrn);
582    int depth = pScrn->depth;
583    unsigned int i;
584
585    regp = &pNv->ModeReg.crtc_reg[nv_crtc->crtc];
586
587
588    /*
589     * compute correct Hsync & Vsync polarity 
590     */
591    if ((mode->Flags & (V_PHSYNC | V_NHSYNC))
592        && (mode->Flags & (V_PVSYNC | V_NVSYNC)))
593    {
594        regp->MiscOutReg = 0x23;
595        if (mode->Flags & V_NHSYNC) regp->MiscOutReg |= 0x40;
596        if (mode->Flags & V_NVSYNC) regp->MiscOutReg |= 0x80;
597    }
598    else
599    {
600        int VDisplay = mode->VDisplay;
601        if (mode->Flags & V_DBLSCAN)
602            VDisplay *= 2;
603        if (mode->VScan > 1)
604            VDisplay *= mode->VScan;
605        if      (VDisplay < 400)
606            regp->MiscOutReg = 0xA3;             /* +hsync -vsync */
607        else if (VDisplay < 480)
608            regp->MiscOutReg = 0x63;             /* -hsync +vsync */
609        else if (VDisplay < 768)
610            regp->MiscOutReg = 0xE3;             /* -hsync -vsync */
611        else
612            regp->MiscOutReg = 0x23;             /* +hsync +vsync */
613    }
614    
615    regp->MiscOutReg |= (mode->ClockIndex & 0x03) << 2;
616    
617    /*
618     * Time Sequencer
619     */
620     if (depth == 4)
621         regp->Sequencer[0] = 0x02;
622     else
623         regp->Sequencer[0] = 0x00;
624     if (mode->Flags & V_CLKDIV2) 
625         regp->Sequencer[1] = 0x09;
626     else
627         regp->Sequencer[1] = 0x01;
628     if (depth == 1)
629         regp->Sequencer[2] = 1 << BIT_PLANE;
630     else
631         regp->Sequencer[2] = 0x0F;
632     regp->Sequencer[3] = 0x00;                             /* Font select */
633     if (depth < 8)
634         regp->Sequencer[4] = 0x06;                             /* Misc */
635     else
636         regp->Sequencer[4] = 0x0E;                             /* Misc */
637
638     /*
639      * CRTC Controller
640      */
641     regp->CRTC[0]  = (mode->CrtcHTotal >> 3) - 5;
642     regp->CRTC[1]  = (mode->CrtcHDisplay >> 3) - 1;
643     regp->CRTC[2]  = (mode->CrtcHBlankStart >> 3) - 1;
644     regp->CRTC[3]  = (((mode->CrtcHBlankEnd >> 3) - 1) & 0x1F) | 0x80;
645     i = (((mode->CrtcHSkew << 2) + 0x10) & ~0x1F);
646     if (i < 0x80)
647         regp->CRTC[3] |= i;
648     regp->CRTC[4]  = (mode->CrtcHSyncStart >> 3);
649     regp->CRTC[5]  = ((((mode->CrtcHBlankEnd >> 3) - 1) & 0x20) << 2)
650         | (((mode->CrtcHSyncEnd >> 3)) & 0x1F);
651     regp->CRTC[6]  = (mode->CrtcVTotal - 2) & 0xFF;
652     regp->CRTC[7]  = (((mode->CrtcVTotal - 2) & 0x100) >> 8)
653         | (((mode->CrtcVDisplay - 1) & 0x100) >> 7)
654         | ((mode->CrtcVSyncStart & 0x100) >> 6)
655         | (((mode->CrtcVBlankStart - 1) & 0x100) >> 5)
656         | 0x10
657         | (((mode->CrtcVTotal - 2) & 0x200)   >> 4)
658         | (((mode->CrtcVDisplay - 1) & 0x200) >> 3)
659         | ((mode->CrtcVSyncStart & 0x200) >> 2);
660     regp->CRTC[8]  = 0x00;
661     regp->CRTC[9]  = (((mode->CrtcVBlankStart - 1) & 0x200) >> 4) | 0x40;
662     if (mode->Flags & V_DBLSCAN)
663         regp->CRTC[9] |= 0x80;
664     if (mode->VScan >= 32)
665         regp->CRTC[9] |= 0x1F;
666     else if (mode->VScan > 1)
667         regp->CRTC[9] |= mode->VScan - 1;
668     regp->CRTC[10] = 0x00;
669     regp->CRTC[11] = 0x00;
670     regp->CRTC[12] = 0x00;
671     regp->CRTC[13] = 0x00;
672     regp->CRTC[14] = 0x00;
673     regp->CRTC[15] = 0x00;
674     regp->CRTC[16] = mode->CrtcVSyncStart & 0xFF;
675     regp->CRTC[17] = (mode->CrtcVSyncEnd & 0x0F) | 0x20;
676     regp->CRTC[18] = (mode->CrtcVDisplay - 1) & 0xFF;
677     regp->CRTC[19] = mode->CrtcHDisplay >> 4;  /* just a guess */
678     regp->CRTC[20] = 0x00;
679     regp->CRTC[21] = (mode->CrtcVBlankStart - 1) & 0xFF; 
680     regp->CRTC[22] = (mode->CrtcVBlankEnd - 1) & 0xFF;
681     if (depth < 8)
682         regp->CRTC[23] = 0xE3;
683     else
684         regp->CRTC[23] = 0xC3;
685     regp->CRTC[24] = 0xFF;
686
687     /*
688      * Theory resumes here....
689      */
690
691     /*
692      * Graphics Display Controller
693      */
694     regp->Graphics[0] = 0x00;
695     regp->Graphics[1] = 0x00;
696     regp->Graphics[2] = 0x00;
697     regp->Graphics[3] = 0x00;
698     if (depth == 1) {
699         regp->Graphics[4] = BIT_PLANE;
700         regp->Graphics[5] = 0x00;
701     } else {
702         regp->Graphics[4] = 0x00;
703         if (depth == 4)
704             regp->Graphics[5] = 0x02;
705         else
706             regp->Graphics[5] = 0x40;
707     }
708     regp->Graphics[6] = 0x05;   /* only map 64k VGA memory !!!! */
709     regp->Graphics[7] = 0x0F;
710     regp->Graphics[8] = 0xFF;
711   
712     if (depth == 1) {
713         /* Initialise the Mono map according to which bit-plane gets used */
714
715         Bool flipPixels = xf86GetFlipPixels();
716
717         for (i=0; i<16; i++)
718             if (((i & (1 << BIT_PLANE)) != 0) != flipPixels)
719                 regp->Attribute[i] = WHITE_VALUE;
720             else
721                 regp->Attribute[i] = BLACK_VALUE;
722
723     } else {
724         regp->Attribute[0]  = 0x00; /* standard colormap translation */
725         regp->Attribute[1]  = 0x01;
726         regp->Attribute[2]  = 0x02;
727         regp->Attribute[3]  = 0x03;
728         regp->Attribute[4]  = 0x04;
729         regp->Attribute[5]  = 0x05;
730         regp->Attribute[6]  = 0x06;
731         regp->Attribute[7]  = 0x07;
732         regp->Attribute[8]  = 0x08;
733         regp->Attribute[9]  = 0x09;
734         regp->Attribute[10] = 0x0A;
735         regp->Attribute[11] = 0x0B;
736         regp->Attribute[12] = 0x0C;
737         regp->Attribute[13] = 0x0D;
738         regp->Attribute[14] = 0x0E;
739         regp->Attribute[15] = 0x0F;
740         if (depth == 4)
741             regp->Attribute[16] = 0x81; /* wrong for the ET4000 */
742         else
743             regp->Attribute[16] = 0x41; /* wrong for the ET4000 */
744         if (depth > 4)
745           regp->Attribute[17] = 0xff;
746         /* Attribute[17] (overscan) initialised in vgaHWGetHWRec() */
747     }
748     regp->Attribute[18] = 0x0F;
749     regp->Attribute[19] = 0x00;
750     regp->Attribute[20] = 0x00;
751
752 }
753
754
755
756 /**
757  * Sets up registers for the given mode/adjusted_mode pair.
758  *
759  * The clocks, CRTCs and outputs attached to this CRTC must be off.
760  *
761  * This shouldn't enable any clocks, CRTCs, or outputs, but they should
762  * be easily turned on/off after this.
763  */
764 static void
765 nv_crtc_mode_set_regs(xf86CrtcPtr crtc, DisplayModePtr mode)
766 {
767     ScrnInfoPtr pScrn = crtc->scrn;
768     NVPtr pNv = NVPTR(pScrn);
769     NVRegPtr state = &pNv->ModeReg;
770     xf86CrtcConfigPtr   xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
771     NVCrtcPrivatePtr nv_crtc = crtc->driver_private;
772     NVFBLayout *pLayout = &pNv->CurrentLayout;
773     NVCrtcRegPtr regp, savep;
774     unsigned int i;
775     int horizDisplay    = (mode->CrtcHDisplay/8)   - 1;
776     int horizStart      = (mode->CrtcHSyncStart/8) - 1;
777     int horizEnd        = (mode->CrtcHSyncEnd/8)   - 1;
778     int horizTotal      = (mode->CrtcHTotal/8)     - 5;
779     int horizBlankStart = (mode->CrtcHDisplay/8)   - 1;
780     int horizBlankEnd   = (mode->CrtcHTotal/8)     - 1;
781     int vertDisplay     =  mode->CrtcVDisplay      - 1;
782     int vertStart       =  mode->CrtcVSyncStart    - 1;
783     int vertEnd         =  mode->CrtcVSyncEnd      - 1;
784     int vertTotal       =  mode->CrtcVTotal        - 2;
785     int vertBlankStart  =  mode->CrtcVDisplay      - 1;
786     int vertBlankEnd    =  mode->CrtcVTotal        - 1;
787     Bool is_fp = FALSE;
788
789     for (i = 0; i < xf86_config->num_output; i++) {
790         xf86OutputPtr  output = xf86_config->output[i];
791         NVOutputPrivatePtr nv_output = output->driver_private;
792
793         if (output->crtc == crtc)
794           if ((nv_output->type == OUTPUT_PANEL) || 
795               (nv_output->type == OUTPUT_DIGITAL))
796                 is_fp = TRUE;
797         
798     }
799
800     regp = &pNv->ModeReg.crtc_reg[nv_crtc->crtc];    
801     savep = &pNv->SavedReg.crtc_reg[nv_crtc->crtc];
802
803     if(mode->Flags & V_INTERLACE) 
804         vertTotal |= 1;
805
806     regp->CRTC[NV_VGA_CRTCX_HTOTAL]  = Set8Bits(horizTotal);
807     regp->CRTC[NV_VGA_CRTCX_HDISPE]  = Set8Bits(horizDisplay);
808     regp->CRTC[NV_VGA_CRTCX_HBLANKS]  = Set8Bits(horizBlankStart);
809     regp->CRTC[NV_VGA_CRTCX_HBLANKE]  = SetBitField(horizBlankEnd,4:0,4:0) 
810                        | SetBit(7);
811     regp->CRTC[NV_VGA_CRTCX_HSYNCS]  = Set8Bits(horizStart);
812     regp->CRTC[NV_VGA_CRTCX_HSYNCE]  = SetBitField(horizBlankEnd,5:5,7:7)
813                        | SetBitField(horizEnd,4:0,4:0);
814     regp->CRTC[NV_VGA_CRTCX_VTOTAL]  = SetBitField(vertTotal,7:0,7:0);
815     regp->CRTC[NV_VGA_CRTCX_OVERFLOW]  = SetBitField(vertTotal,8:8,0:0)
816                        | SetBitField(vertDisplay,8:8,1:1)
817                        | SetBitField(vertStart,8:8,2:2)
818                        | SetBitField(vertBlankStart,8:8,3:3)
819                        | SetBit(4)
820                        | SetBitField(vertTotal,9:9,5:5)
821                        | SetBitField(vertDisplay,9:9,6:6)
822                        | SetBitField(vertStart,9:9,7:7);
823     regp->CRTC[NV_VGA_CRTCX_MAXSCLIN]  = SetBitField(vertBlankStart,9:9,5:5)
824                        | SetBit(6)
825                        | ((mode->Flags & V_DBLSCAN) ? 0x80 : 0x00);
826     regp->CRTC[NV_VGA_CRTCX_VSYNCS] = Set8Bits(vertStart);
827     regp->CRTC[NV_VGA_CRTCX_VSYNCE] = SetBitField(vertEnd,3:0,3:0) | SetBit(5);
828     regp->CRTC[NV_VGA_CRTCX_VDISPE] = Set8Bits(vertDisplay);
829     regp->CRTC[NV_VGA_CRTCX_PITCHL] = ((pLayout->displayWidth/8)*(pLayout->bitsPerPixel/8));
830     regp->CRTC[NV_VGA_CRTCX_VBLANKS] = Set8Bits(vertBlankStart);
831     regp->CRTC[NV_VGA_CRTCX_VBLANKE] = Set8Bits(vertBlankEnd);
832
833     regp->Attribute[0x10] = 0x01;
834
835     if(pNv->Television)
836        regp->Attribute[0x11] = 0x00;
837
838     regp->CRTC[NV_VGA_CRTCX_LSR] = SetBitField(horizBlankEnd,6:6,4:4)
839                   | SetBitField(vertBlankStart,10:10,3:3)
840                   | SetBitField(vertStart,10:10,2:2)
841                   | SetBitField(vertDisplay,10:10,1:1)
842                   | SetBitField(vertTotal,10:10,0:0);
843
844     regp->CRTC[NV_VGA_CRTCX_HEB] = SetBitField(horizTotal,8:8,0:0) 
845                   | SetBitField(horizDisplay,8:8,1:1)
846                   | SetBitField(horizBlankStart,8:8,2:2)
847                   | SetBitField(horizStart,8:8,3:3);
848
849     regp->CRTC[NV_VGA_CRTCX_EXTRA] = SetBitField(vertTotal,11:11,0:0)
850                     | SetBitField(vertDisplay,11:11,2:2)
851                     | SetBitField(vertStart,11:11,4:4)
852                     | SetBitField(vertBlankStart,11:11,6:6);
853
854     if(mode->Flags & V_INTERLACE) {
855        horizTotal = (horizTotal >> 1) & ~1;
856        regp->CRTC[NV_VGA_CRTCX_INTERLACE] = Set8Bits(horizTotal);
857        regp->CRTC[NV_VGA_CRTCX_HEB] |= SetBitField(horizTotal,8:8,4:4);
858     } else {
859         regp->CRTC[NV_VGA_CRTCX_INTERLACE] = 0xff;  /* interlace off */
860     }
861
862     regp->CRTC[NV_VGA_CRTCX_BUFFER] = 0xfa;
863     
864     if (is_fp) {
865             regp->CRTC[NV_VGA_CRTCX_LCD] = savep->CRTC[NV_VGA_CRTCX_LCD] | 1;
866             /* this turns on the DFP on nv28 outputs */
867             regp->CRTC[NV_VGA_CRTCX_59] = savep->CRTC[NV_VGA_CRTCX_59] | 1;
868     } else {
869             regp->CRTC[NV_VGA_CRTCX_LCD] = savep->CRTC[NV_VGA_CRTCX_LCD] & ~1;
870     }
871
872     /*
873      * Initialize DAC palette.
874      */
875     if(pLayout->bitsPerPixel != 8 )
876     {
877         for (i = 0; i < 256; i++)
878         {
879             regp->DAC[i*3]     = i;
880             regp->DAC[(i*3)+1] = i;
881             regp->DAC[(i*3)+2] = i;
882         }
883     }
884     
885     /*
886      * Calculate the extended registers.
887      */
888
889     if(pLayout->depth < 24) 
890         i = pLayout->depth;
891     else i = 32;
892
893     if(pNv->Architecture >= NV_ARCH_10)
894         pNv->CURSOR = (CARD32 *)pNv->Cursor->map;
895
896     ErrorF("crtc %d %d %d\n", nv_crtc->crtc, mode->CrtcHDisplay, pLayout->displayWidth);
897     nv_crtc_calc_state_ext(crtc,
898                            i,
899                            pLayout->displayWidth,
900                            mode->CrtcHDisplay,
901                            mode->CrtcVDisplay,
902                            mode->Clock,
903                            mode->Flags);
904
905     if (is_fp)
906       regp->CRTC[NV_VGA_CRTCX_PIXEL] |= (1 << 7);
907
908     regp->CRTC[NV_VGA_CRTCX_FIFO1] = savep->CRTC[NV_VGA_CRTCX_FIFO1] & ~(1<<5);
909
910     if(nv_crtc->crtc) {
911        if (is_fp) {
912                regp->head &= ~NV_CRTC_FSEL_FPP2;
913                regp->head |= NV_CRTC_FSEL_FPP1;
914        } else {
915                regp->head &= ~NV_CRTC_FSEL_FPP1;
916                regp->head |= NV_CRTC_FSEL_FPP2;
917        }
918
919        regp->crtcOwner = 3;
920        /* only enable secondary pllsel if CRTC 1 is selected on */
921
922     } else {
923       if(pNv->twoHeads) {
924         regp->head  =  savep->head | 0x00001000;
925         if (is_fp) {
926                 regp->head &= ~NV_CRTC_FSEL_FPP2;
927                 regp->head |= NV_CRTC_FSEL_FPP1;
928         } else {
929                 regp->head &= ~NV_CRTC_FSEL_FPP1;
930                 regp->head |= NV_CRTC_FSEL_FPP2;
931         }
932
933         regp->crtcOwner = 0;
934       }
935     }
936
937     regp->cursorConfig = 0x00000100;
938     if(mode->Flags & V_DBLSCAN)
939        regp->cursorConfig |= (1 << 4);
940     if(pNv->alphaCursor) {
941         if((pNv->Chipset & 0x0ff0) != CHIPSET_NV11) 
942            regp->cursorConfig |= 0x04011000;
943         else
944            regp->cursorConfig |= 0x14011000;
945     } else
946        regp->cursorConfig |= 0x02000000;
947
948     regp->CRTC[NV_VGA_CRTCX_FP_HTIMING] = 0;
949     regp->CRTC[NV_VGA_CRTCX_FP_VTIMING] = 0;
950
951     regp->unk830 = mode->CrtcVDisplay - 3;
952     regp->unk834 = mode->CrtcVDisplay - 1;
953 }
954
955 /**
956  * Sets up registers for the given mode/adjusted_mode pair.
957  *
958  * The clocks, CRTCs and outputs attached to this CRTC must be off.
959  *
960  * This shouldn't enable any clocks, CRTCs, or outputs, but they should
961  * be easily turned on/off after this.
962  */
963 static void
964 nv_crtc_mode_set(xf86CrtcPtr crtc, DisplayModePtr mode,
965                  DisplayModePtr adjusted_mode,
966                  int x, int y)
967 {
968     ScrnInfoPtr pScrn = crtc->scrn;
969     NVCrtcPrivatePtr nv_crtc = crtc->driver_private;
970     NVPtr pNv = NVPTR(pScrn);
971
972     xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "Mode on CRTC %d\n", nv_crtc->crtc);
973     xf86PrintModeline(pScrn->scrnIndex, mode);
974     NVCrtcSetOwner(crtc);
975
976     nv_crtc_mode_set_vga(crtc, mode);
977     nv_crtc_mode_set_regs(crtc, mode);
978
979
980     NVVgaProtect(crtc, TRUE);
981     nv_crtc_load_state_ext(crtc, &pNv->ModeReg);
982     nv_crtc_load_state_vga(crtc, &pNv->ModeReg);
983     nv_crtc_load_state_pll(pNv, &pNv->ModeReg);
984
985     NVVgaProtect(crtc, FALSE);
986     //    NVCrtcLockUnlock(crtc, 1);
987
988     NVCrtcSetBase(crtc, x, y);
989 #if X_BYTE_ORDER == X_BIG_ENDIAN
990     /* turn on LFB swapping */
991     {
992         unsigned char tmp;
993
994         tmp = NVReadVgaCrtc(crtc, NV_VGA_CRTCX_SWAPPING);
995         tmp |= (1 << 7);
996         NVWriteVgaCrtc(crtc, NV_VGA_CRTCX_SWAPPING, tmp);
997     }
998 #endif
999
1000 }
1001
1002 void nv_crtc_save(xf86CrtcPtr crtc)
1003 {
1004     ScrnInfoPtr pScrn = crtc->scrn;
1005     NVCrtcPrivatePtr nv_crtc = crtc->driver_private;
1006     NVPtr pNv = NVPTR(pScrn);
1007
1008     NVCrtcSetOwner(crtc);
1009     nv_crtc_save_state_pll(pNv, &pNv->SavedReg);
1010     nv_crtc_save_state_vga(crtc, &pNv->SavedReg);
1011     nv_crtc_save_state_ext(crtc, &pNv->SavedReg);
1012
1013 }
1014
1015 void nv_crtc_restore(xf86CrtcPtr crtc)
1016 {
1017     ScrnInfoPtr pScrn = crtc->scrn;
1018     NVCrtcPrivatePtr nv_crtc = crtc->driver_private;
1019     NVPtr pNv = NVPTR(pScrn);
1020
1021     NVCrtcSetOwner(crtc);    
1022     nv_crtc_load_state_ext(crtc, &pNv->SavedReg);
1023     nv_crtc_load_state_vga(crtc, &pNv->SavedReg);
1024     nv_crtc_load_state_pll(pNv, &pNv->SavedReg);
1025     nvWriteVGA(pNv, NV_VGA_CRTCX_OWNER, pNv->vtOWNER);
1026
1027 }
1028
1029 void nv_crtc_prepare(xf86CrtcPtr crtc)
1030 {
1031     ScrnInfoPtr pScrn = crtc->scrn;
1032         NVPtr pNv = NVPTR(pScrn);
1033   /* Sync the engine before adjust mode */
1034 if (pNv->AccelInfoRec && pNv->AccelInfoRec->NeedToSync) {
1035     (*pNv->AccelInfoRec->Sync)(pScrn);
1036     pNv->AccelInfoRec->NeedToSync = FALSE;
1037 }
1038
1039 }
1040
1041 void nv_crtc_commit(xf86CrtcPtr crtc)
1042 {
1043
1044
1045 }
1046
1047 static Bool nv_crtc_lock(xf86CrtcPtr crtc)
1048 {
1049         return FALSE;
1050 }
1051
1052 static void nv_crtc_unlock(xf86CrtcPtr crtc)
1053 {
1054
1055 }
1056
1057 static const xf86CrtcFuncsRec nv_crtc_funcs = {
1058     .dpms = nv_crtc_dpms,
1059     .save = nv_crtc_save, /* XXX */
1060     .restore = nv_crtc_restore, /* XXX */
1061     .mode_fixup = nv_crtc_mode_fixup,
1062     .mode_set = nv_crtc_mode_set,
1063     .prepare = nv_crtc_prepare,
1064     .commit = nv_crtc_commit,
1065     .destroy = NULL, /* XXX */
1066     .lock = nv_crtc_lock,
1067     .unlock = nv_crtc_unlock,
1068 };
1069
1070 void
1071 nv_crtc_init(ScrnInfoPtr pScrn, int crtc_num)
1072 {
1073     NVPtr pNv = NVPTR(pScrn);
1074     xf86CrtcPtr crtc;
1075     NVCrtcPrivatePtr nv_crtc;
1076
1077     crtc = xf86CrtcCreate (pScrn, &nv_crtc_funcs);
1078     if (crtc == NULL)
1079         return;
1080
1081     nv_crtc = xnfcalloc (sizeof (NVCrtcPrivateRec), 1);
1082     nv_crtc->crtc = crtc_num;
1083
1084     crtc->driver_private = nv_crtc;
1085
1086     NVCrtcLockUnlock(crtc, 0);
1087
1088 }
1089
1090 static void nv_crtc_load_state_vga(xf86CrtcPtr crtc, RIVA_HW_STATE *state)
1091 {
1092     ScrnInfoPtr pScrn = crtc->scrn;
1093     NVPtr pNv = NVPTR(pScrn);    
1094     NVCrtcPrivatePtr nv_crtc = crtc->driver_private;
1095     int i, j;
1096     CARD32 temp;
1097     NVCrtcRegPtr regp;
1098
1099     regp = &state->crtc_reg[nv_crtc->crtc];
1100
1101     NVWriteMiscOut(crtc, regp->MiscOutReg);
1102
1103     for (i = 1; i < 5; i++)
1104       NVWriteVgaSeq(crtc, i, regp->Sequencer[i]);
1105   
1106     /* Ensure CRTC registers 0-7 are unlocked by clearing bit 7 of CRTC[17] */
1107     NVWriteVgaCrtc(crtc, 17, regp->CRTC[17] & ~0x80);
1108
1109     for (i = 0; i < 25; i++)
1110       NVWriteVgaCrtc(crtc, i, regp->CRTC[i]);
1111
1112     for (i = 0; i < 9; i++)
1113       NVWriteVgaGr(crtc, i, regp->Graphics[i]);
1114     
1115     NVEnablePalette(crtc);
1116     for (i = 0; i < 21; i++)
1117       NVWriteVgaAttr(crtc, i, regp->Attribute[i]);
1118     NVDisablePalette(crtc);
1119
1120 }
1121
1122 static void nv_crtc_fix_nv40_hw_cursor(xf86CrtcPtr crtc)
1123 {
1124   /* TODO - implement this properly */
1125   ScrnInfoPtr pScrn = crtc->scrn;
1126   NVPtr pNv = NVPTR(pScrn);
1127    
1128   if(pNv->Architecture == NV_ARCH_40) {  /* HW bug */
1129     volatile CARD32 curpos = nvReadCurRAMDAC(pNv, NV_RAMDAC_CURSOR_POS);
1130     nvWriteCurRAMDAC(pNv, NV_RAMDAC_CURSOR_POS, curpos);
1131   }
1132
1133 }
1134 static void nv_crtc_load_state_ext(xf86CrtcPtr crtc, RIVA_HW_STATE *state)
1135 {
1136     ScrnInfoPtr pScrn = crtc->scrn;
1137     NVPtr pNv = NVPTR(pScrn);    
1138     NVCrtcPrivatePtr nv_crtc = crtc->driver_private;
1139     int i, j;
1140     CARD32 temp;
1141     NVCrtcRegPtr regp;
1142     
1143     regp = &state->crtc_reg[nv_crtc->crtc];
1144
1145     if (!pNv->IRQ)
1146         nvWriteMC(pNv, 0x140, 0);
1147
1148     if(pNv->Architecture >= NV_ARCH_10) {
1149         if(pNv->twoHeads) {
1150            nvWriteCRTC(pNv, nv_crtc->crtc, NV_CRTC_FSEL, regp->head);
1151         }
1152         nvWriteVIDEO(pNv, NV_PVIDEO_STOP, 1);
1153         nvWriteVIDEO(pNv, NV_PVIDEO_INTR_EN, 0);
1154         nvWriteVIDEO(pNv, NV_PVIDEO_OFFSET_BUFF(0), 0);
1155         nvWriteVIDEO(pNv, NV_PVIDEO_OFFSET_BUFF(1), 0);
1156         nvWriteVIDEO(pNv, NV_PVIDEO_LIMIT(0), pNv->VRAMPhysicalSize - 1);
1157         nvWriteVIDEO(pNv, NV_PVIDEO_LIMIT(1), pNv->VRAMPhysicalSize - 1);
1158         nvWriteMC(pNv, 0x1588, 0);
1159
1160         NVWriteVgaCrtc(crtc, NV_VGA_CRTCX_BUFFER, 0xff);
1161         NVWriteVgaCrtc(crtc, NV_VGA_CRTCX_BUFFER, regp->CRTC[NV_VGA_CRTCX_BUFFER]);
1162         nvWriteCRTC(pNv, nv_crtc->crtc, NV_CRTC_CURSOR_CONFIG, regp->cursorConfig);
1163         nvWriteCRTC(pNv, nv_crtc->crtc, NV_CRTC_0830, regp->unk830);
1164         nvWriteCRTC(pNv, nv_crtc->crtc, NV_CRTC_0834, regp->unk834);
1165         
1166         NVWriteVgaCrtc(crtc, NV_VGA_CRTCX_FP_HTIMING, regp->CRTC[NV_VGA_CRTCX_FP_HTIMING]);
1167         NVWriteVgaCrtc(crtc, NV_VGA_CRTCX_FP_VTIMING, regp->CRTC[NV_VGA_CRTCX_FP_VTIMING]);
1168
1169         NVWriteVgaCrtc(crtc, NV_VGA_CRTCX_59, regp->CRTC[NV_VGA_CRTCX_59]);
1170         NVWriteVgaCrtc(crtc, NV_VGA_CRTCX_EXTRA, regp->CRTC[NV_VGA_CRTCX_EXTRA]);
1171     }
1172
1173     NVWriteVgaCrtc(crtc, NV_VGA_CRTCX_REPAINT0, regp->CRTC[NV_VGA_CRTCX_REPAINT0]);
1174     NVWriteVgaCrtc(crtc, NV_VGA_CRTCX_REPAINT1, regp->CRTC[NV_VGA_CRTCX_REPAINT1]);
1175     NVWriteVgaCrtc(crtc, NV_VGA_CRTCX_LSR, regp->CRTC[NV_VGA_CRTCX_LSR]);
1176     NVWriteVgaCrtc(crtc, NV_VGA_CRTCX_PIXEL, regp->CRTC[NV_VGA_CRTCX_PIXEL]);
1177     NVWriteVgaCrtc(crtc, NV_VGA_CRTCX_LCD, regp->CRTC[NV_VGA_CRTCX_LCD]);
1178     NVWriteVgaCrtc(crtc, NV_VGA_CRTCX_HEB, regp->CRTC[NV_VGA_CRTCX_HEB]);
1179     NVWriteVgaCrtc(crtc, NV_VGA_CRTCX_FIFO1, regp->CRTC[NV_VGA_CRTCX_FIFO1]);
1180     NVWriteVgaCrtc(crtc, NV_VGA_CRTCX_FIFO0, regp->CRTC[NV_VGA_CRTCX_FIFO0]);
1181     NVWriteVgaCrtc(crtc, NV_VGA_CRTCX_FIFO_LWM, regp->CRTC[NV_VGA_CRTCX_FIFO_LWM]);
1182     if(pNv->Architecture >= NV_ARCH_30) {
1183       NVWriteVgaCrtc(crtc, NV_VGA_CRTCX_FIFO_LWM_NV30, regp->CRTC[NV_VGA_CRTCX_FIFO_LWM_NV30]);
1184     }
1185
1186     NVWriteVgaCrtc(crtc, NV_VGA_CRTCX_CURCTL0, regp->CRTC[NV_VGA_CRTCX_CURCTL0]);
1187     NVWriteVgaCrtc(crtc, NV_VGA_CRTCX_CURCTL1, regp->CRTC[NV_VGA_CRTCX_CURCTL1]);
1188     nv_crtc_fix_nv40_hw_cursor(crtc);
1189     NVWriteVgaCrtc(crtc, NV_VGA_CRTCX_CURCTL2, regp->CRTC[NV_VGA_CRTCX_CURCTL2]);
1190     NVWriteVgaCrtc(crtc, NV_VGA_CRTCX_INTERLACE, regp->CRTC[NV_VGA_CRTCX_INTERLACE]);
1191
1192     nvWriteCRTC(pNv, nv_crtc->crtc, NV_CRTC_INTR_EN_0, 0);
1193     nvWriteCRTC(pNv, nv_crtc->crtc, NV_CRTC_INTR_0, NV_CRTC_INTR_VBLANK);
1194
1195     pNv->CurrentState = state;
1196 }
1197
1198 static void nv_crtc_save_state_vga(xf86CrtcPtr crtc, RIVA_HW_STATE *state)
1199 {
1200     ScrnInfoPtr pScrn = crtc->scrn;
1201     NVPtr pNv = NVPTR(pScrn);    
1202     NVCrtcPrivatePtr nv_crtc = crtc->driver_private;
1203     int i;
1204     NVCrtcRegPtr regp;
1205
1206     regp = &state->crtc_reg[nv_crtc->crtc];
1207
1208     regp->MiscOutReg = NVReadMiscOut(crtc);
1209
1210     for (i = 0; i < 25; i++)
1211         regp->CRTC[i] = NVReadVgaCrtc(crtc, i);
1212
1213     NVEnablePalette(crtc);
1214     for (i = 0; i < 21; i++)
1215         regp->Attribute[i] = NVReadVgaAttr(crtc, i);
1216     NVDisablePalette(crtc);
1217
1218     for (i = 0; i < 9; i++)
1219         regp->Graphics[i] = NVReadVgaGr(crtc, i);
1220
1221     for (i = 1; i < 5; i++)
1222         regp->Sequencer[i] = NVReadVgaSeq(crtc, i);
1223   
1224 }
1225
1226 static void nv_crtc_save_state_ext(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     NVCrtcRegPtr regp;
1232     int i;
1233
1234     regp = &state->crtc_reg[nv_crtc->crtc];
1235  
1236     regp->CRTC[NV_VGA_CRTCX_59] = NVReadVgaCrtc(crtc, NV_VGA_CRTCX_59);
1237     regp->CRTC[NV_VGA_CRTCX_LCD] = NVReadVgaCrtc(crtc, NV_VGA_CRTCX_LCD);
1238     regp->CRTC[NV_VGA_CRTCX_REPAINT0] = NVReadVgaCrtc(crtc, NV_VGA_CRTCX_REPAINT0);
1239     regp->CRTC[NV_VGA_CRTCX_REPAINT1] = NVReadVgaCrtc(crtc, NV_VGA_CRTCX_REPAINT1);
1240     regp->CRTC[NV_VGA_CRTCX_LSR] = NVReadVgaCrtc(crtc, NV_VGA_CRTCX_LSR);
1241     regp->CRTC[NV_VGA_CRTCX_PIXEL] = NVReadVgaCrtc(crtc, NV_VGA_CRTCX_PIXEL);
1242     regp->CRTC[NV_VGA_CRTCX_HEB] = NVReadVgaCrtc(crtc, NV_VGA_CRTCX_HEB);
1243     regp->CRTC[NV_VGA_CRTCX_FIFO1] = NVReadVgaCrtc(crtc, NV_VGA_CRTCX_FIFO1);
1244
1245     regp->CRTC[NV_VGA_CRTCX_FIFO0] = NVReadVgaCrtc(crtc, NV_VGA_CRTCX_FIFO0);
1246     regp->CRTC[NV_VGA_CRTCX_FIFO_LWM] = NVReadVgaCrtc(crtc, NV_VGA_CRTCX_FIFO_LWM);
1247     if(pNv->Architecture >= NV_ARCH_30) {
1248          regp->CRTC[NV_VGA_CRTCX_FIFO_LWM_NV30] = NVReadVgaCrtc(crtc, NV_VGA_CRTCX_FIFO_LWM_NV30);
1249     }
1250     regp->CRTC[NV_VGA_CRTCX_CURCTL0] = NVReadVgaCrtc(crtc, NV_VGA_CRTCX_CURCTL0);
1251     regp->CRTC[NV_VGA_CRTCX_CURCTL1] = NVReadVgaCrtc(crtc, NV_VGA_CRTCX_CURCTL1);
1252     regp->CRTC[NV_VGA_CRTCX_CURCTL2] = NVReadVgaCrtc(crtc, NV_VGA_CRTCX_CURCTL2);
1253     regp->CRTC[NV_VGA_CRTCX_INTERLACE] = NVReadVgaCrtc(crtc, NV_VGA_CRTCX_INTERLACE);
1254  
1255     regp->unk830 = nvReadCRTC(pNv, nv_crtc->crtc, NV_CRTC_0830);
1256     regp->unk834 = nvReadCRTC(pNv, nv_crtc->crtc, NV_CRTC_0834);
1257
1258     if(pNv->Architecture >= NV_ARCH_10) {
1259         if(pNv->twoHeads) {
1260            regp->head     = nvReadCRTC(pNv, nv_crtc->crtc, NV_CRTC_FSEL);
1261            regp->crtcOwner = NVReadVgaCrtc(crtc, NV_VGA_CRTCX_OWNER);
1262         }
1263         regp->CRTC[NV_VGA_CRTCX_EXTRA] = NVReadVgaCrtc(crtc, NV_VGA_CRTCX_EXTRA);
1264
1265         regp->cursorConfig = nvReadCRTC(pNv, nv_crtc->crtc, NV_CRTC_CURSOR_CONFIG);
1266
1267         regp->CRTC[NV_VGA_CRTCX_BUFFER] = NVReadVgaCrtc(crtc, NV_VGA_CRTCX_BUFFER);
1268         regp->CRTC[NV_VGA_CRTCX_FP_HTIMING] = NVReadVgaCrtc(crtc, NV_VGA_CRTCX_FP_HTIMING);
1269         regp->CRTC[NV_VGA_CRTCX_FP_VTIMING] = NVReadVgaCrtc(crtc, NV_VGA_CRTCX_FP_VTIMING);
1270     }
1271 }
1272
1273 void
1274 NVCrtcSetBase (xf86CrtcPtr crtc, int x, int y)
1275 {
1276     ScrnInfoPtr pScrn = crtc->scrn;
1277     NVPtr pNv = NVPTR(pScrn);    
1278     NVCrtcPrivatePtr nv_crtc = crtc->driver_private;
1279     NVFBLayout *pLayout = &pNv->CurrentLayout;
1280     CARD32 start = 0;
1281     
1282     start += ((y * pScrn->displayWidth + x) * (pLayout->bitsPerPixel/8));
1283     start += pNv->FB->offset;
1284
1285     nvWriteCRTC(pNv, nv_crtc->crtc, NV_CRTC_START, start);
1286
1287     crtc->x = x;
1288     crtc->y = y;
1289 }
1290
1291 void NVCrtcSetCursor(xf86CrtcPtr crtc, Bool state)
1292 {
1293   int current = NVReadVgaCrtc(crtc, NV_VGA_CRTCX_CURCTL1);
1294
1295   if(state) 
1296     current |= 1;
1297   else
1298     current &= ~1;
1299
1300   NVWriteVgaCrtc(crtc, NV_VGA_CRTCX_CURCTL1, current);
1301 }
1302
1303 static void NVCrtcWriteDacMask(xf86CrtcPtr crtc, CARD8 value)
1304 {
1305   ScrnInfoPtr pScrn = crtc->scrn;
1306   NVCrtcPrivatePtr nv_crtc = crtc->driver_private;
1307   NVPtr pNv = NVPTR(pScrn);
1308   volatile CARD8 *pDACReg = nv_crtc->crtc ? pNv->PDIO1 : pNv->PDIO0;
1309
1310   NV_WR08(pDACReg, VGA_DAC_MASK, value);
1311 }
1312
1313 static CARD8 NVCrtcReadDacMask(xf86CrtcPtr crtc)
1314 {
1315   ScrnInfoPtr pScrn = crtc->scrn;
1316   NVCrtcPrivatePtr nv_crtc = crtc->driver_private;
1317   NVPtr pNv = NVPTR(pScrn);
1318   volatile CARD8 *pDACReg = nv_crtc->crtc ? pNv->PDIO1 : pNv->PDIO0;
1319   
1320   return NV_RD08(pDACReg, VGA_DAC_MASK);
1321 }
1322
1323 static void NVCrtcWriteDacReadAddr(xf86CrtcPtr crtc, CARD8 value)
1324 {
1325   ScrnInfoPtr pScrn = crtc->scrn;
1326   NVCrtcPrivatePtr nv_crtc = crtc->driver_private;
1327   NVPtr pNv = NVPTR(pScrn);
1328   volatile CARD8 *pDACReg = nv_crtc->crtc ? pNv->PDIO1 : pNv->PDIO0;
1329
1330   NV_WR08(pDACReg, VGA_DAC_READ_ADDR, value);
1331 }
1332
1333 static void NVCrtcWriteDacWriteAddr(xf86CrtcPtr crtc, CARD8 value)
1334 {
1335   ScrnInfoPtr pScrn = crtc->scrn;
1336   NVCrtcPrivatePtr nv_crtc = crtc->driver_private;
1337   NVPtr pNv = NVPTR(pScrn);
1338   volatile CARD8 *pDACReg = nv_crtc->crtc ? pNv->PDIO1 : pNv->PDIO0;
1339
1340   NV_WR08(pDACReg, VGA_DAC_WRITE_ADDR, value);
1341 }
1342
1343 static void NVCrtcWriteDacData(xf86CrtcPtr crtc, CARD8 value)
1344 {
1345   ScrnInfoPtr pScrn = crtc->scrn;
1346   NVCrtcPrivatePtr nv_crtc = crtc->driver_private;
1347   NVPtr pNv = NVPTR(pScrn);
1348   volatile CARD8 *pDACReg = nv_crtc->crtc ? pNv->PDIO1 : pNv->PDIO0;
1349
1350   NV_WR08(pDACReg, VGA_DAC_DATA, value);
1351 }
1352
1353 static CARD8 NVCrtcReadDacData(xf86CrtcPtr crtc, CARD8 value)
1354 {
1355   ScrnInfoPtr pScrn = crtc->scrn;
1356   NVCrtcPrivatePtr nv_crtc = crtc->driver_private;
1357   NVPtr pNv = NVPTR(pScrn);
1358   volatile CARD8 *pDACReg = nv_crtc->crtc ? pNv->PDIO1 : pNv->PDIO0;
1359
1360   return NV_RD08(pDACReg, VGA_DAC_DATA);
1361 }
1362
1363 void NVCrtcLoadPalette(xf86CrtcPtr crtc)
1364 {
1365   int i;
1366   NVCrtcPrivatePtr nv_crtc = crtc->driver_private;
1367   NVCrtcRegPtr regp;
1368   ScrnInfoPtr pScrn = crtc->scrn;
1369   NVPtr pNv = NVPTR(pScrn);
1370     
1371   regp = &pNv->ModeReg.crtc_reg[nv_crtc->crtc];
1372
1373   NVWriteVgaCrtc(crtc, NV_VGA_CRTCX_OWNER, nv_crtc->crtc * 0x3);
1374   NVCrtcWriteDacMask(crtc, 0xff);
1375   NVCrtcWriteDacWriteAddr(crtc, 0x00);
1376
1377   for (i = 0; i<768; i++) {
1378     NVCrtcWriteDacData(crtc, regp->DAC[i]);
1379   }
1380   NVDisablePalette(crtc);
1381 }
1382
1383 void NVCrtcBlankScreen(xf86CrtcPtr crtc, Bool on)
1384 {
1385     NVCrtcPrivatePtr nv_crtc = crtc->driver_private;
1386     unsigned char scrn;
1387
1388     NVWriteVgaCrtc(crtc, NV_VGA_CRTCX_OWNER, nv_crtc->crtc * 0x3);
1389
1390     scrn = NVReadVgaSeq(crtc, 0x01);
1391     if (on) {
1392         scrn &= ~0x20;
1393     } else {
1394         scrn |= 0x20;
1395     }
1396
1397     NVVgaSeqReset(crtc, TRUE);
1398     NVWriteVgaSeq(crtc, 0x01, scrn);
1399     NVVgaSeqReset(crtc, FALSE);
1400 }
1401
1402 /*************************************************************************** \
1403 |*                                                                           *|
1404 |*       Copyright 1993-2003 NVIDIA, Corporation.  All rights reserved.      *|
1405 |*                                                                           *|
1406 |*     NOTICE TO USER:   The source code  is copyrighted under  U.S. and     *|
1407 |*     international laws.  Users and possessors of this source code are     *|
1408 |*     hereby granted a nonexclusive,  royalty-free copyright license to     *|
1409 |*     use this code in individual and commercial software.                  *|
1410 |*                                                                           *|
1411 |*     Any use of this source code must include,  in the user documenta-     *|
1412 |*     tion and  internal comments to the code,  notices to the end user     *|
1413 |*     as follows:                                                           *|
1414 |*                                                                           *|
1415 |*       Copyright 1993-1999 NVIDIA, Corporation.  All rights reserved.      *|
1416 |*                                                                           *|
1417 |*     NVIDIA, CORPORATION MAKES NO REPRESENTATION ABOUT THE SUITABILITY     *|
1418 |*     OF  THIS SOURCE  CODE  FOR ANY PURPOSE.  IT IS  PROVIDED  "AS IS"     *|
1419 |*     WITHOUT EXPRESS OR IMPLIED WARRANTY OF ANY KIND.  NVIDIA, CORPOR-     *|
1420 |*     ATION DISCLAIMS ALL WARRANTIES  WITH REGARD  TO THIS SOURCE CODE,     *|
1421 |*     INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGE-     *|
1422 |*     MENT,  AND FITNESS  FOR A PARTICULAR PURPOSE.   IN NO EVENT SHALL     *|
1423 |*     NVIDIA, CORPORATION  BE LIABLE FOR ANY SPECIAL,  INDIRECT,  INCI-     *|
1424 |*     DENTAL, OR CONSEQUENTIAL DAMAGES,  OR ANY DAMAGES  WHATSOEVER RE-     *|
1425 |*     SULTING FROM LOSS OF USE,  DATA OR PROFITS,  WHETHER IN AN ACTION     *|
1426 |*     OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,  ARISING OUT OF     *|
1427 |*     OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOURCE CODE.     *|
1428 |*                                                                           *|
1429 |*     U.S. Government  End  Users.   This source code  is a "commercial     *|
1430 |*     item,"  as that  term is  defined at  48 C.F.R. 2.101 (OCT 1995),     *|
1431 |*     consisting  of "commercial  computer  software"  and  "commercial     *|
1432 |*     computer  software  documentation,"  as such  terms  are  used in     *|
1433 |*     48 C.F.R. 12.212 (SEPT 1995)  and is provided to the U.S. Govern-     *|
1434 |*     ment only as  a commercial end item.   Consistent with  48 C.F.R.     *|
1435 |*     12.212 and  48 C.F.R. 227.7202-1 through  227.7202-4 (JUNE 1995),     *|
1436 |*     all U.S. Government End Users  acquire the source code  with only     *|
1437 |*     those rights set forth herein.                                        *|
1438 |*                                                                           *|
1439  \***************************************************************************/