randr12: The last step to make lower flatpanel resolutions working.
[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 #ifdef ENABLE_RANDR12
33
34 #include <assert.h>
35 #include "xf86.h"
36 #include "os.h"
37 #include "mibank.h"
38 #include "globals.h"
39 #include "xf86.h"
40 #include "xf86Priv.h"
41 #include "xf86DDC.h"
42 #include "mipointer.h"
43 #include "windowstr.h"
44 #include <randrstr.h>
45 #include <X11/extensions/render.h>
46
47 #include "xf86Crtc.h"
48 #include "nv_include.h"
49
50 #include "vgaHW.h"
51
52 #define CRTC_INDEX 0x3d4
53 #define CRTC_DATA 0x3d5
54 #define CRTC_IN_STAT_1 0x3da
55
56 #define WHITE_VALUE 0x3F
57 #define BLACK_VALUE 0x00
58 #define OVERSCAN_VALUE 0x01
59
60 static void nv_crtc_load_state_vga(xf86CrtcPtr crtc, RIVA_HW_STATE *state);
61 static void nv_crtc_load_state_ext(xf86CrtcPtr crtc, RIVA_HW_STATE *state);
62 static void nv_crtc_save_state_ext(xf86CrtcPtr crtc, RIVA_HW_STATE *state);
63 static void nv_crtc_save_state_vga(xf86CrtcPtr crtc, RIVA_HW_STATE *state);
64
65 static void NVWriteMiscOut(xf86CrtcPtr crtc, CARD8 value)
66 {
67   ScrnInfoPtr pScrn = crtc->scrn;
68   NVCrtcPrivatePtr nv_crtc = crtc->driver_private;
69   NVPtr pNv = NVPTR(pScrn);
70
71   NV_WR08(pNv->PVIO, VGA_MISC_OUT_W, value);
72 }
73
74 static CARD8 NVReadMiscOut(xf86CrtcPtr crtc)
75 {
76   ScrnInfoPtr pScrn = crtc->scrn;
77   NVCrtcPrivatePtr nv_crtc = crtc->driver_private;
78   NVPtr pNv = NVPTR(pScrn);
79
80   return NV_RD08(pNv->PVIO, VGA_MISC_OUT_R);
81 }
82
83
84 void NVWriteVgaCrtc(xf86CrtcPtr crtc, CARD8 index, CARD8 value)
85 {
86   ScrnInfoPtr pScrn = crtc->scrn;
87   NVCrtcPrivatePtr nv_crtc = crtc->driver_private;
88   NVPtr pNv = NVPTR(pScrn);
89   volatile CARD8 *pCRTCReg = nv_crtc->head ? pNv->PCIO1 : pNv->PCIO0;
90
91   NV_WR08(pCRTCReg, CRTC_INDEX, index);
92   NV_WR08(pCRTCReg, CRTC_DATA, value);
93 }
94
95 CARD8 NVReadVgaCrtc(xf86CrtcPtr crtc, CARD8 index)
96 {
97   ScrnInfoPtr pScrn = crtc->scrn;
98   NVCrtcPrivatePtr nv_crtc = crtc->driver_private;
99   NVPtr pNv = NVPTR(pScrn);
100   volatile CARD8 *pCRTCReg = nv_crtc->head ? pNv->PCIO1 : pNv->PCIO0;
101
102   NV_WR08(pCRTCReg, CRTC_INDEX, index);
103   return NV_RD08(pCRTCReg, CRTC_DATA);
104 }
105
106 static void NVWriteVgaSeq(xf86CrtcPtr crtc, CARD8 index, CARD8 value)
107 {
108   ScrnInfoPtr pScrn = crtc->scrn;
109   NVCrtcPrivatePtr nv_crtc = crtc->driver_private;
110   NVPtr pNv = NVPTR(pScrn);
111
112   NV_WR08(pNv->PVIO, VGA_SEQ_INDEX, index);
113   NV_WR08(pNv->PVIO, VGA_SEQ_DATA, value);
114 }
115
116 static CARD8 NVReadVgaSeq(xf86CrtcPtr crtc, CARD8 index)
117 {
118   ScrnInfoPtr pScrn = crtc->scrn;
119   NVCrtcPrivatePtr nv_crtc = crtc->driver_private;
120   NVPtr pNv = NVPTR(pScrn);
121   volatile CARD8 *pVGAReg = pNv->PVIO;
122
123   NV_WR08(pNv->PVIO, VGA_SEQ_INDEX, index);
124   return NV_RD08(pNv->PVIO, VGA_SEQ_DATA);
125 }
126
127 static void NVWriteVgaGr(xf86CrtcPtr crtc, CARD8 index, CARD8 value)
128 {
129   ScrnInfoPtr pScrn = crtc->scrn;
130   NVCrtcPrivatePtr nv_crtc = crtc->driver_private;
131   NVPtr pNv = NVPTR(pScrn);
132
133   NV_WR08(pNv->PVIO, VGA_GRAPH_INDEX, index);
134   NV_WR08(pNv->PVIO, VGA_GRAPH_DATA, value);
135 }
136
137 static CARD8 NVReadVgaGr(xf86CrtcPtr crtc, CARD8 index)
138 {
139   ScrnInfoPtr pScrn = crtc->scrn;
140   NVCrtcPrivatePtr nv_crtc = crtc->driver_private;
141   NVPtr pNv = NVPTR(pScrn);
142   volatile CARD8 *pVGAReg = pNv->PVIO;
143
144   NV_WR08(pVGAReg, VGA_GRAPH_INDEX, index);
145   return NV_RD08(pVGAReg, VGA_GRAPH_DATA);
146
147
148
149 static void NVWriteVgaAttr(xf86CrtcPtr crtc, CARD8 index, CARD8 value)
150 {
151   ScrnInfoPtr pScrn = crtc->scrn;
152   NVCrtcPrivatePtr nv_crtc = crtc->driver_private;
153   NVPtr pNv = NVPTR(pScrn);
154   volatile CARD8 *pCRTCReg = nv_crtc->head ? pNv->PCIO1 : pNv->PCIO0;
155
156   NV_RD08(pCRTCReg, CRTC_IN_STAT_1);
157   if (nv_crtc->paletteEnabled)
158     index &= ~0x20;
159   else
160     index |= 0x20;
161   NV_WR08(pCRTCReg, VGA_ATTR_INDEX, index);
162   NV_WR08(pCRTCReg, VGA_ATTR_DATA_W, value);
163 }
164
165 static CARD8 NVReadVgaAttr(xf86CrtcPtr crtc, CARD8 index)
166 {
167   ScrnInfoPtr pScrn = crtc->scrn;
168   NVCrtcPrivatePtr nv_crtc = crtc->driver_private;
169   NVPtr pNv = NVPTR(pScrn);
170   volatile CARD8 *pCRTCReg = nv_crtc->head ? pNv->PCIO1 : pNv->PCIO0;
171
172   NV_RD08(pCRTCReg, CRTC_IN_STAT_1);
173   if (nv_crtc->paletteEnabled)
174     index &= ~0x20;
175   else
176     index |= 0x20;
177   NV_WR08(pCRTCReg, VGA_ATTR_INDEX, index);
178   return NV_RD08(pCRTCReg, VGA_ATTR_DATA_R);
179 }
180
181 void NVCrtcSetOwner(xf86CrtcPtr crtc)
182 {
183         NVCrtcPrivatePtr nv_crtc = crtc->driver_private;
184         ScrnInfoPtr pScrn = crtc->scrn;
185         NVPtr pNv = NVPTR(pScrn);
186         /* Non standard beheaviour required by NV11 */
187         if (pNv) {
188                 uint8_t owner = NVReadVGA0(pNv, NV_VGA_CRTCX_OWNER);
189                 ErrorF("pre-Owner: 0x%X\n", owner);
190                 if (owner == 0x04) {
191                         uint32_t pbus84 = nvReadMC(pNv, 0x1084);
192                         ErrorF("pbus84: 0x%X\n", pbus84);
193                         pbus84 &= ~(1<<28);
194                         ErrorF("pbus84: 0x%X\n", pbus84);
195                         nvWriteMC(pNv, 0x1084, pbus84);
196                 }
197                 /* The blob never writes owner to pcio1, so should we */
198                 if (pNv->NVArch == 0x11) {
199                         NVWriteVGA0(pNv, NV_VGA_CRTCX_OWNER, 0xff);
200                 }
201                 NVWriteVGA0(pNv, NV_VGA_CRTCX_OWNER, nv_crtc->crtc * 0x3);
202                 owner = NVReadVGA0(pNv, NV_VGA_CRTCX_OWNER);
203                 ErrorF("post-Owner: 0x%X\n", owner);
204         } else {
205                 ErrorF("pNv pointer is NULL\n");
206         }
207 }
208
209 static void
210 NVEnablePalette(xf86CrtcPtr crtc)
211 {
212   ScrnInfoPtr pScrn = crtc->scrn;
213   NVCrtcPrivatePtr nv_crtc = crtc->driver_private;
214   NVPtr pNv = NVPTR(pScrn);
215   volatile CARD8 *pCRTCReg = nv_crtc->head ? pNv->PCIO1 : pNv->PCIO0;
216
217   NV_RD08(pCRTCReg, CRTC_IN_STAT_1);
218   NV_WR08(pCRTCReg, VGA_ATTR_INDEX, 0);
219   nv_crtc->paletteEnabled = TRUE;
220 }
221
222 static void
223 NVDisablePalette(xf86CrtcPtr crtc)
224 {
225   ScrnInfoPtr pScrn = crtc->scrn;
226   NVCrtcPrivatePtr nv_crtc = crtc->driver_private;
227   NVPtr pNv = NVPTR(pScrn);
228   volatile CARD8 *pCRTCReg = nv_crtc->head ? pNv->PCIO1 : pNv->PCIO0;
229
230   NV_RD08(pCRTCReg, CRTC_IN_STAT_1);
231   NV_WR08(pCRTCReg, VGA_ATTR_INDEX, 0x20);
232   nv_crtc->paletteEnabled = FALSE;
233 }
234
235 static void NVWriteVgaReg(xf86CrtcPtr crtc, CARD32 reg, CARD8 value)
236 {
237  ScrnInfoPtr pScrn = crtc->scrn;
238   NVCrtcPrivatePtr nv_crtc = crtc->driver_private;
239   NVPtr pNv = NVPTR(pScrn);
240   volatile CARD8 *pCRTCReg = nv_crtc->head ? pNv->PCIO1 : pNv->PCIO0;
241
242   NV_WR08(pCRTCReg, reg, value);
243 }
244
245 /* perform a sequencer reset */
246 static void NVVgaSeqReset(xf86CrtcPtr crtc, Bool start)
247 {
248   if (start)
249     NVWriteVgaSeq(crtc, 0x00, 0x1);
250   else
251     NVWriteVgaSeq(crtc, 0x00, 0x3);
252
253 }
254 static void NVVgaProtect(xf86CrtcPtr crtc, Bool on)
255 {
256   CARD8 tmp;
257
258   if (on) {
259     tmp = NVReadVgaSeq(crtc, 0x1);
260     NVVgaSeqReset(crtc, TRUE);
261     NVWriteVgaSeq(crtc, 0x01, tmp | 0x20);
262
263     NVEnablePalette(crtc);
264   } else {
265     /*
266      * Reenable sequencer, then turn on screen.
267      */
268     tmp = NVReadVgaSeq(crtc, 0x1);
269     NVWriteVgaSeq(crtc, 0x01, tmp & ~0x20);     /* reenable display */
270     NVVgaSeqReset(crtc, FALSE);
271
272     NVDisablePalette(crtc);
273   }
274 }
275
276 void NVCrtcLockUnlock(xf86CrtcPtr crtc, Bool Lock)
277 {
278   CARD8 cr11;
279
280   NVWriteVgaCrtc(crtc, NV_VGA_CRTCX_LOCK, Lock ? 0x99 : 0x57);
281   cr11 = NVReadVgaCrtc(crtc, NV_VGA_CRTCX_VSYNCE);
282   if (Lock) cr11 |= 0x80;
283   else cr11 &= ~0x80;
284   NVWriteVgaCrtc(crtc, NV_VGA_CRTCX_VSYNCE, cr11);
285 }
286 /*
287  * Calculate the Video Clock parameters for the PLL.
288  */
289 static void CalcVClock (
290         int             clockIn,
291         int             *clockOut,
292         CARD32          *pllOut,
293         NVPtr           pNv
294 )
295 {
296         unsigned lowM, highM, highP;
297         unsigned DeltaNew, DeltaOld;
298         unsigned VClk, Freq;
299         unsigned M, N, P;
300
301         /* M: PLL reference frequency postscaler divider */
302         /* P: PLL VCO output postscaler divider */
303         /* N: PLL VCO postscaler setting */
304
305         DeltaOld = 0xFFFFFFFF;
306
307         VClk = (unsigned)clockIn;
308
309         /* Taken from Haiku, after someone with an NV28 had an issue */
310         switch(pNv->NVArch) {
311                 case 0x28:
312                         lowM = 1;
313                         highP = 32;
314                         if (VClk > 340000) {
315                                 highM = 2;
316                         } else if (VClk > 200000) {
317                                 highM = 4;
318                         } else if (VClk > 150000) {
319                                 highM = 6;
320                         } else {
321                                 highM = 14;
322                         }
323                         break;
324                 default:
325                         lowM = 1;
326                         highP = 16;
327                         if (VClk > 340000) {
328                                 highM = 2;
329                         } else if (VClk > 250000) {
330                                 highM = 6;
331                         } else {
332                                 highM = 14;
333                         }
334                         break;
335         }
336
337         for (P = 0; P <= highP; P++) {
338                 Freq = VClk << P;
339                 if ((Freq >= 128000) && (Freq <= 350000)) {
340                         for (M = lowM; M <= highM; M++) {
341                                 N = ((VClk << P) * M) / pNv->CrystalFreqKHz;
342                                 if (N <= 255) {
343                                         Freq = ((pNv->CrystalFreqKHz * N) / M) >> P;
344                                         if (Freq > VClk) {
345                                                 DeltaNew = Freq - VClk;
346                                         } else {
347                                                 DeltaNew = VClk - Freq;
348                                         }
349                                         if (DeltaNew < DeltaOld) {
350                                                 *pllOut   = (P << 16) | (N << 8) | M;
351                                                 *clockOut = Freq;
352                                                 DeltaOld  = DeltaNew;
353                                         }
354                                 }
355                         }
356                 }
357         }
358 }
359
360 static void CalcVClock2Stage (
361         int             clockIn,
362         int             *clockOut,
363         CARD32          *pllOut,
364         CARD32          *pllBOut,
365         NVPtr           pNv
366 )
367 {
368         unsigned DeltaNew, DeltaOld;
369         unsigned VClk, Freq;
370         unsigned M, N, P;
371         unsigned lowM, highM, highP;
372
373         DeltaOld = 0xFFFFFFFF;
374
375         *pllBOut = 0x80000401;  /* fixed at x4 for now */
376
377         VClk = (unsigned)clockIn;
378
379         /* Taken from Haiku, after someone with an NV28 had an issue */
380         switch(pNv->NVArch) {
381                 case 0x28:
382                         lowM = 1;
383                         highP = 32;
384                         if (VClk > 340000) {
385                                 highM = 2;
386                         } else if (VClk > 200000) {
387                                 highM = 4;
388                         } else if (VClk > 150000) {
389                                 highM = 6;
390                         } else {
391                                 highM = 14;
392                         }
393                         break;
394                 default:
395                         lowM = 1;
396                         highP = 16;
397                         if (VClk > 340000) {
398                                 highM = 2;
399                         } else if (VClk > 250000) {
400                                 highM = 6;
401                         } else {
402                                 highM = 14;
403                         }
404                         break;
405         }
406
407         for (P = 0; P <= highP; P++) {
408                 Freq = VClk << P;
409                 if ((Freq >= 400000) && (Freq <= 1000000)) {
410                         for (M = lowM; M <= highM; M++) {
411                                 N = ((VClk << P) * M) / (pNv->CrystalFreqKHz << 2);
412                                 if ((N >= 5) && (N <= 255)) {
413                                         Freq = (((pNv->CrystalFreqKHz << 2) * N) / M) >> P;
414                                         if (Freq > VClk) {
415                                                 DeltaNew = Freq - VClk;
416                                         } else {
417                                                 DeltaNew = VClk - Freq;
418                                         }
419                                         if (DeltaNew < DeltaOld) {
420                                                 *pllOut   = (P << 16) | (N << 8) | M;
421                                                 *clockOut = Freq;
422                                                 DeltaOld  = DeltaNew;
423                                         }
424                                 }
425                         }
426                 }
427         }
428 }
429
430 static void nv_crtc_save_state_pll(NVPtr pNv, RIVA_HW_STATE *state)
431 {
432         state->vpll = nvReadRAMDAC0(pNv, NV_RAMDAC_VPLL);
433         if(pNv->twoHeads) {
434                 state->vpll2 = nvReadRAMDAC0(pNv, NV_RAMDAC_VPLL2);
435         }
436         if(pNv->twoStagePLL) {
437                 state->vpllB = nvReadRAMDAC0(pNv, NV_RAMDAC_VPLL_B);
438                 state->vpll2B = nvReadRAMDAC0(pNv, NV_RAMDAC_VPLL2_B);
439         }
440         state->pllsel = nvReadRAMDAC0(pNv, NV_RAMDAC_PLL_SELECT);
441 }
442
443
444 static void nv_crtc_load_state_pll(NVPtr pNv, RIVA_HW_STATE *state)
445 {
446         nvWriteRAMDAC0(pNv, NV_RAMDAC_PLL_SELECT, state->pllsel);
447
448         ErrorF("writting vpll %08X\n", state->vpll);
449         ErrorF("writting vpll2 %08X\n", state->vpll2);
450         nvWriteRAMDAC0(pNv, NV_RAMDAC_VPLL, state->vpll);
451         if(pNv->twoHeads) {
452                 nvWriteRAMDAC0(pNv, NV_RAMDAC_VPLL2, state->vpll2);
453         }
454         if(pNv->twoStagePLL) {
455                 nvWriteRAMDAC0(pNv, NV_RAMDAC_VPLL_B, state->vpllB);
456                 nvWriteRAMDAC0(pNv, NV_RAMDAC_VPLL2_B, state->vpll2B);
457         }  
458 }
459
460 /*
461  * Calculate extended mode parameters (SVGA) and save in a 
462  * mode state structure.
463  */
464 void nv_crtc_calc_state_ext(
465         xf86CrtcPtr     crtc,
466         int                     bpp,
467         int                     DisplayWidth, /* Does this change after setting the mode? */
468         int                     CrtcHDisplay,
469         int                     CrtcVDisplay,
470         int                     dotClock,
471         int                     flags 
472 )
473 {
474         ScrnInfoPtr pScrn = crtc->scrn;
475         int pixelDepth, VClk;
476         CARD32 CursorStart;
477         NVCrtcPrivatePtr nv_crtc = crtc->driver_private;
478         xf86CrtcConfigPtr   xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
479         NVCrtcRegPtr regp;
480         NVPtr pNv = NVPTR(pScrn);    
481         RIVA_HW_STATE *state;
482         int num_crtc_enabled, i;
483
484         state = &pNv->ModeReg;
485
486         regp = &pNv->ModeReg.crtc_reg[nv_crtc->head];
487
488         /*
489          * Extended RIVA registers.
490          */
491         pixelDepth = (bpp + 1)/8;
492         if(pNv->twoStagePLL)
493                 CalcVClock2Stage(dotClock, &VClk, &state->pll, &state->pllB, pNv);
494         else
495                 CalcVClock(dotClock, &VClk, &state->pll, pNv);
496
497         switch (pNv->Architecture) {
498         case NV_ARCH_04:
499                 nv4UpdateArbitrationSettings(VClk, 
500                                                 pixelDepth * 8, 
501                                                 &(state->arbitration0),
502                                                 &(state->arbitration1),
503                                                 pNv);
504                 regp->CRTC[NV_VGA_CRTCX_CURCTL0] = 0x00;
505                 regp->CRTC[NV_VGA_CRTCX_CURCTL1] = 0xbC;
506                 if (flags & V_DBLSCAN)
507                         regp->CRTC[NV_VGA_CRTCX_CURCTL1] |= 2;
508                 regp->CRTC[NV_VGA_CRTCX_CURCTL2] = 0x00000000;
509                 state->pllsel   |= NV_RAMDAC_PLL_SELECT_VCLK_RATIO_DB2 | NV_RAMDAC_PLL_SELECT_PLL_SOURCE_ALL; 
510                 state->config   = 0x00001114;
511                 regp->CRTC[NV_VGA_CRTCX_REPAINT1] = CrtcHDisplay < 1280 ? 0x04 : 0x00;
512                 break;
513         case NV_ARCH_10:
514         case NV_ARCH_20:
515         case NV_ARCH_30:
516         default:
517                 if (((pNv->Chipset & 0xfff0) == CHIPSET_C51) ||
518                         ((pNv->Chipset & 0xfff0) == CHIPSET_C512)) {
519                         state->arbitration0 = 128; 
520                         state->arbitration1 = 0x0480; 
521                 } else if (((pNv->Chipset & 0xffff) == CHIPSET_NFORCE) ||
522                         ((pNv->Chipset & 0xffff) == CHIPSET_NFORCE2)) {
523                         nForceUpdateArbitrationSettings(VClk,
524                                                 pixelDepth * 8,
525                                                 &(state->arbitration0),
526                                                 &(state->arbitration1),
527                                                 pNv);
528                 } else if (pNv->Architecture < NV_ARCH_30) {
529                         nv10UpdateArbitrationSettings(VClk, 
530                                                 pixelDepth * 8, 
531                                                 &(state->arbitration0),
532                                                 &(state->arbitration1),
533                                                 pNv);
534                 } else {
535                         nv30UpdateArbitrationSettings(pNv,
536                                                 &(state->arbitration0),
537                                                 &(state->arbitration1));
538                 }
539
540                 CursorStart = pNv->Cursor->offset;
541
542                 regp->CRTC[NV_VGA_CRTCX_CURCTL0] = 0x80 | (CursorStart >> 17);
543                 regp->CRTC[NV_VGA_CRTCX_CURCTL1] = (CursorStart >> 11) << 2;
544                 regp->CRTC[NV_VGA_CRTCX_CURCTL2] = CursorStart >> 24;
545
546                 if (flags & V_DBLSCAN) 
547                         regp->CRTC[NV_VGA_CRTCX_CURCTL1] |= 2;
548
549                 state->config   = nvReadFB(pNv, NV_PFB_CFG0);
550                 regp->CRTC[NV_VGA_CRTCX_REPAINT1] = CrtcHDisplay < 1280 ? 0x04 : 0x00;
551                 break;
552         }
553
554         /* okay do we have 2 CRTCs running ? */
555         num_crtc_enabled = 0;
556         for (i = 0; i < xf86_config->num_crtc; i++) {
557                 if (xf86_config->crtc[i]->enabled) {
558                         num_crtc_enabled++;
559                 }
560         }
561
562         ErrorF("There are %d CRTC's enabled\n", num_crtc_enabled);
563
564         if (nv_crtc->crtc == 1) {
565                 state->vpll2 = state->pll;
566                 state->vpll2B = state->pllB;
567                 state->pllsel |= NV_RAMDAC_PLL_SELECT_VCLK2_RATIO_DB2;
568                 state->pllsel |= NV_RAMDAC_PLL_SELECT_PLL_SOURCE_CRTC1;
569         } else {
570                 state->vpll = state->pll;
571                 state->vpllB = state->pllB;
572                 state->pllsel |= NV_RAMDAC_PLL_SELECT_PLL_SOURCE_ALL;
573                 state->pllsel &= ~NV_RAMDAC_PLL_SELECT_VCLK_RATIO_DB2;
574         }
575
576         regp->CRTC[NV_VGA_CRTCX_FIFO0] = state->arbitration0;
577         regp->CRTC[NV_VGA_CRTCX_FIFO_LWM] = state->arbitration1 & 0xff;
578         if (pNv->Architecture >= NV_ARCH_30) {
579                 regp->CRTC[NV_VGA_CRTCX_FIFO_LWM_NV30] = state->arbitration1 >> 8;
580         }
581
582         regp->CRTC[NV_VGA_CRTCX_REPAINT0] = (((DisplayWidth/8) * pixelDepth) & 0x700) >> 3;
583         regp->CRTC[NV_VGA_CRTCX_PIXEL] = (pixelDepth > 2) ? 3 : pixelDepth;
584 }
585
586
587 static void
588 nv_crtc_dpms(xf86CrtcPtr crtc, int mode)
589 {
590      NVCrtcPrivatePtr nv_crtc = crtc->driver_private;
591         ScrnInfoPtr pScrn = crtc->scrn;
592         NVPtr pNv = NVPTR(pScrn);
593      unsigned char seq1 = 0, crtc17 = 0;
594      unsigned char crtc1A;
595      int ret;
596
597         ErrorF("nv_crtc_dpms is called for CRTC %d with mode %d\n", nv_crtc->crtc, mode);
598
599      NVCrtcSetOwner(crtc);
600
601      crtc1A = NVReadVgaCrtc(crtc, NV_VGA_CRTCX_REPAINT1) & ~0xC0;
602      switch(mode) {
603      case DPMSModeStandby:
604        /* Screen: Off; HSync: Off, VSync: On -- Not Supported */
605        seq1 = 0x20;
606        crtc17 = 0x80;
607        crtc1A |= 0x80;
608        break;
609      case DPMSModeSuspend:
610        /* Screen: Off; HSync: On, VSync: Off -- Not Supported */
611        seq1 = 0x20;
612        crtc17 = 0x80;
613        crtc1A |= 0x40;
614        break;
615      case DPMSModeOff:
616        /* Screen: Off; HSync: Off, VSync: Off */
617        seq1 = 0x20;
618        crtc17 = 0x00;
619        crtc1A |= 0xC0;
620        break;
621      case DPMSModeOn:
622      default:
623        /* Screen: On; HSync: On, VSync: On */
624        seq1 = 0x00;
625        crtc17 = 0x80;
626        break;
627      }
628
629         if (mode == DPMSModeOn) {
630                 pNv->crtc_active[nv_crtc->head] = TRUE;
631         } else {
632                 pNv->crtc_active[nv_crtc->head] = FALSE;
633         }
634
635      NVWriteVgaSeq(crtc, 0x00, 0x1);
636      seq1 = NVReadVgaSeq(crtc, 0x01) & ~0x20;
637      NVWriteVgaSeq(crtc, 0x1, seq1);
638      crtc17 |= NVReadVgaCrtc(crtc, NV_VGA_CRTCX_MODECTL) & ~0x80;
639      usleep(10000);
640      NVWriteVgaCrtc(crtc, NV_VGA_CRTCX_MODECTL, crtc17);
641      NVWriteVgaSeq(crtc, 0x0, 0x3);
642
643      NVWriteVgaCrtc(crtc, NV_VGA_CRTCX_REPAINT1, crtc1A);
644 }
645
646 static Bool
647 nv_crtc_mode_fixup(xf86CrtcPtr crtc, DisplayModePtr mode,
648                      DisplayModePtr adjusted_mode)
649 {
650         NVCrtcPrivatePtr nv_crtc = crtc->driver_private;
651         ErrorF("nv_crtc_mode_fixup is called for CRTC %d\n", nv_crtc->crtc);
652         return TRUE;
653 }
654
655 static void
656 nv_crtc_mode_set_vga(xf86CrtcPtr crtc, DisplayModePtr mode)
657 {
658         ScrnInfoPtr pScrn = crtc->scrn;
659         NVCrtcPrivatePtr nv_crtc = crtc->driver_private;
660         NVCrtcRegPtr regp;
661         NVPtr pNv = NVPTR(pScrn);
662         int depth = pScrn->depth;
663         unsigned int i;
664
665         regp = &pNv->ModeReg.crtc_reg[nv_crtc->head];
666
667         /*
668         * compute correct Hsync & Vsync polarity 
669         */
670         if ((mode->Flags & (V_PHSYNC | V_NHSYNC))
671                 && (mode->Flags & (V_PVSYNC | V_NVSYNC))) {
672
673                 regp->MiscOutReg = 0x23;
674                 if (mode->Flags & V_NHSYNC) regp->MiscOutReg |= 0x40;
675                 if (mode->Flags & V_NVSYNC) regp->MiscOutReg |= 0x80;
676         } else {
677                 int VDisplay = mode->VDisplay;
678                 if (mode->Flags & V_DBLSCAN)
679                         VDisplay *= 2;
680                 if (mode->VScan > 1)
681                         VDisplay *= mode->VScan;
682                 if (VDisplay < 400) {
683                         regp->MiscOutReg = 0xA3;                /* +hsync -vsync */
684                 } else if (VDisplay < 480) {
685                         regp->MiscOutReg = 0x63;                /* -hsync +vsync */
686                 } else if (VDisplay < 768) {
687                         regp->MiscOutReg = 0xE3;                /* -hsync -vsync */
688                 } else {
689                         regp->MiscOutReg = 0x23;                /* +hsync +vsync */
690                 }
691         }
692
693         regp->MiscOutReg |= (mode->ClockIndex & 0x03) << 2;
694
695         /*
696         * Time Sequencer
697         */
698         if (depth == 4) {
699                 regp->Sequencer[0] = 0x02;
700         } else {
701                 regp->Sequencer[0] = 0x00;
702         }
703         if (mode->Flags & V_CLKDIV2) {
704                 regp->Sequencer[1] = 0x09;
705         } else {
706                 regp->Sequencer[1] = 0x01;
707         }
708         if (depth == 1) {
709                 regp->Sequencer[2] = 1 << BIT_PLANE;
710         } else {
711                 regp->Sequencer[2] = 0x0F;
712                 regp->Sequencer[3] = 0x00;                     /* Font select */
713         }
714         if (depth < 8) {
715                 regp->Sequencer[4] = 0x06;                             /* Misc */
716         } else {
717                 regp->Sequencer[4] = 0x0E;                             /* Misc */
718         }
719
720         /*
721         * CRTC Controller
722         */
723         regp->CRTC[0]  = (mode->CrtcHTotal >> 3) - 5;
724         regp->CRTC[1]  = (mode->CrtcHDisplay >> 3) - 1;
725         regp->CRTC[2]  = (mode->CrtcHBlankStart >> 3) - 1;
726         regp->CRTC[3]  = (((mode->CrtcHBlankEnd >> 3) - 1) & 0x1F) | 0x80;
727         i = (((mode->CrtcHSkew << 2) + 0x10) & ~0x1F);
728         if (i < 0x80) {
729                 regp->CRTC[3] |= i;
730         }
731         regp->CRTC[4]  = (mode->CrtcHSyncStart >> 3);
732         regp->CRTC[5]  = ((((mode->CrtcHBlankEnd >> 3) - 1) & 0x20) << 2)
733         | (((mode->CrtcHSyncEnd >> 3)) & 0x1F);
734         regp->CRTC[6]  = (mode->CrtcVTotal - 2) & 0xFF;
735         regp->CRTC[7]  = (((mode->CrtcVTotal - 2) & 0x100) >> 8)
736                         | (((mode->CrtcVDisplay - 1) & 0x100) >> 7)
737                         | ((mode->CrtcVSyncStart & 0x100) >> 6)
738                         | (((mode->CrtcVBlankStart - 1) & 0x100) >> 5)
739                         | 0x10
740                         | (((mode->CrtcVTotal - 2) & 0x200)   >> 4)
741                         | (((mode->CrtcVDisplay - 1) & 0x200) >> 3)
742                         | ((mode->CrtcVSyncStart & 0x200) >> 2);
743         regp->CRTC[8]  = 0x00;
744         regp->CRTC[9]  = (((mode->CrtcVBlankStart - 1) & 0x200) >> 4) | 0x40;
745         if (mode->Flags & V_DBLSCAN) {
746                 regp->CRTC[9] |= 0x80;
747         }
748         if (mode->VScan >= 32) {
749                 regp->CRTC[9] |= 0x1F;
750         } else if (mode->VScan > 1) {
751                 regp->CRTC[9] |= mode->VScan - 1;
752         }
753         regp->CRTC[10] = 0x00;
754         regp->CRTC[11] = 0x00;
755         regp->CRTC[12] = 0x00;
756         regp->CRTC[13] = 0x00;
757         regp->CRTC[14] = 0x00;
758         regp->CRTC[15] = 0x00;
759         regp->CRTC[16] = mode->CrtcVSyncStart & 0xFF;
760         regp->CRTC[17] = (mode->CrtcVSyncEnd & 0x0F) | 0x20;
761         regp->CRTC[18] = (mode->CrtcVDisplay - 1) & 0xFF;
762         regp->CRTC[19] = mode->CrtcHDisplay >> 4;  /* just a guess */
763         regp->CRTC[20] = 0x00;
764         regp->CRTC[21] = (mode->CrtcVBlankStart - 1) & 0xFF; 
765         regp->CRTC[22] = (mode->CrtcVBlankEnd - 1) & 0xFF;
766         if (depth < 8) {
767                 regp->CRTC[23] = 0xE3;
768         } else {
769                 regp->CRTC[23] = 0xC3;
770         }
771         regp->CRTC[24] = 0xFF;
772
773         /*
774         * Theory resumes here....
775         */
776
777         /*
778         * Graphics Display Controller
779         */
780         regp->Graphics[0] = 0x00;
781         regp->Graphics[1] = 0x00;
782         regp->Graphics[2] = 0x00;
783         regp->Graphics[3] = 0x00;
784         if (depth == 1) {
785                 regp->Graphics[4] = BIT_PLANE;
786                 regp->Graphics[5] = 0x00;
787         } else {
788                 regp->Graphics[4] = 0x00;
789                 if (depth == 4) {
790                         regp->Graphics[5] = 0x02;
791                 } else {
792                         regp->Graphics[5] = 0x40;
793                 }
794         }
795         regp->Graphics[6] = 0x05;   /* only map 64k VGA memory !!!! */
796         regp->Graphics[7] = 0x0F;
797         regp->Graphics[8] = 0xFF;
798   
799         if (depth == 1) {
800                 /* Initialise the Mono map according to which bit-plane gets used */
801
802                 Bool flipPixels = xf86GetFlipPixels();
803
804                 for (i=0; i<16; i++) {
805                         if (((i & (1 << BIT_PLANE)) != 0) != flipPixels) {
806                                 regp->Attribute[i] = WHITE_VALUE;
807                         } else {
808                                 regp->Attribute[i] = BLACK_VALUE;
809                         }
810                 }
811
812         } else {
813                 regp->Attribute[0]  = 0x00; /* standard colormap translation */
814                 regp->Attribute[1]  = 0x01;
815                 regp->Attribute[2]  = 0x02;
816                 regp->Attribute[3]  = 0x03;
817                 regp->Attribute[4]  = 0x04;
818                 regp->Attribute[5]  = 0x05;
819                 regp->Attribute[6]  = 0x06;
820                 regp->Attribute[7]  = 0x07;
821                 regp->Attribute[8]  = 0x08;
822                 regp->Attribute[9]  = 0x09;
823                 regp->Attribute[10] = 0x0A;
824                 regp->Attribute[11] = 0x0B;
825                 regp->Attribute[12] = 0x0C;
826                 regp->Attribute[13] = 0x0D;
827                 regp->Attribute[14] = 0x0E;
828                 regp->Attribute[15] = 0x0F;
829                 if (depth == 4) {
830                         regp->Attribute[16] = 0x81; /* wrong for the ET4000 */
831                 } else {
832                         regp->Attribute[16] = 0x41; /* wrong for the ET4000 */
833                 }
834                 if (depth > 4) {
835                         regp->Attribute[17] = 0xff;
836                 }
837                 /* Attribute[17] (overscan) initialised in vgaHWGetHWRec() */
838         }
839         regp->Attribute[18] = 0x0F;
840         regp->Attribute[19] = 0x00;
841         regp->Attribute[20] = 0x00;
842 }
843
844 /**
845  * Sets up registers for the given mode/adjusted_mode pair.
846  *
847  * The clocks, CRTCs and outputs attached to this CRTC must be off.
848  *
849  * This shouldn't enable any clocks, CRTCs, or outputs, but they should
850  * be easily turned on/off after this.
851  */
852 static void
853 nv_crtc_mode_set_regs(xf86CrtcPtr crtc, DisplayModePtr mode)
854 {
855         ScrnInfoPtr pScrn = crtc->scrn;
856         NVPtr pNv = NVPTR(pScrn);
857         NVRegPtr state = &pNv->ModeReg;
858         xf86CrtcConfigPtr   xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
859         NVCrtcPrivatePtr nv_crtc = crtc->driver_private;
860         NVFBLayout *pLayout = &pNv->CurrentLayout;
861         NVCrtcRegPtr regp, savep;
862         unsigned int i;
863         int horizDisplay        = (mode->CrtcHDisplay/8);
864         int horizStart          = (mode->CrtcHSyncStart/8);
865         int horizEnd            = (mode->CrtcHSyncEnd/8);
866         int horizTotal          = (mode->CrtcHTotal/8) ;
867         int horizBlankStart     = (mode->CrtcHDisplay/8);
868         int horizBlankEnd       = (mode->CrtcHTotal/8);
869         int vertDisplay         =  mode->CrtcVDisplay;
870         int vertStart           =  mode->CrtcVSyncStart;
871         int vertEnd             =  mode->CrtcVSyncEnd;
872         int vertTotal           =  mode->CrtcVTotal;
873         int vertBlankStart      =  mode->CrtcVDisplay;
874         int vertBlankEnd        =  mode->CrtcVTotal;
875         int linecomp            = mode->CrtcVDisplay;
876         /* What about vsync and hsync? */
877
878         Bool is_fp = FALSE;
879
880         xf86OutputPtr  output;
881         NVOutputPrivatePtr nv_output;
882         for (i = 0; i < xf86_config->num_output; i++) {
883                 output = xf86_config->output[i];
884                 nv_output = output->driver_private;
885
886                 if (output->crtc == crtc) {
887                         if ((nv_output->type == OUTPUT_PANEL) || 
888                                 (nv_output->type == OUTPUT_DIGITAL)) {
889
890                                 is_fp = TRUE;
891                                 break;
892                         }
893                 }
894         }
895
896         /* Stuff from haiku, put here so it doesn't look messy up there */
897         horizTotal -= 5;
898         horizDisplay -= 1;
899         vertTotal -= 2;
900         vertDisplay -= 1;
901         horizBlankEnd -= 1;
902         vertBlankEnd -= 1;
903
904         ErrorF("crtc: Pre-sync workaround\n");
905         /* Reverted to what nv did, because that works for all resolutions on flatpanels */
906         if (is_fp) {
907                 vertStart = vertTotal - 3;  
908                 vertEnd = vertTotal - 2;
909                 vertBlankStart = vertStart;
910                 horizStart = horizTotal - 5;
911                 horizEnd = horizTotal - 2;   
912                 horizBlankEnd = horizTotal + 4;   
913                 if (pNv->overlayAdaptor) { 
914                         /* This reportedly works around Xv some overlay bandwidth problems*/
915                         horizTotal += 2;
916                 }
917         }
918         ErrorF("crtc: Post-sync workaround\n");
919
920         ErrorF("horizDisplay: 0x%X \n", horizDisplay);
921         ErrorF("horizStart: 0x%X \n", horizStart);
922         ErrorF("horizEnd: 0x%X \n", horizEnd);
923         ErrorF("horizTotal: 0x%X \n", horizTotal);
924         ErrorF("horizBlankStart: 0x%X \n", horizBlankStart);
925         ErrorF("horizBlankEnd: 0x%X \n", horizBlankEnd);
926         ErrorF("vertDisplay: 0x%X \n", vertDisplay);
927         ErrorF("vertStart: 0x%X \n", vertStart);
928         ErrorF("vertEnd: 0x%X \n", vertEnd);
929         ErrorF("vertTotal: 0x%X \n", vertTotal);
930         ErrorF("vertBlankStart: 0x%X \n", vertBlankStart);
931         ErrorF("vertBlankEnd: 0x%X \n", vertBlankEnd);
932
933         regp = &pNv->ModeReg.crtc_reg[nv_crtc->head];    
934         savep = &pNv->SavedReg.crtc_reg[nv_crtc->head];
935
936         if(mode->Flags & V_INTERLACE) 
937                 vertTotal |= 1;
938
939         regp->CRTC[NV_VGA_CRTCX_HTOTAL]  = Set8Bits(horizTotal);
940         regp->CRTC[NV_VGA_CRTCX_HDISPE]  = Set8Bits(horizDisplay);
941         regp->CRTC[NV_VGA_CRTCX_HBLANKS]  = Set8Bits(horizBlankStart);
942         regp->CRTC[NV_VGA_CRTCX_HBLANKE]  = SetBitField(horizBlankEnd,4:0,4:0) 
943                                 | SetBit(7);
944         regp->CRTC[NV_VGA_CRTCX_HSYNCS]  = Set8Bits(horizStart);
945         regp->CRTC[NV_VGA_CRTCX_HSYNCE]  = SetBitField(horizBlankEnd,5:5,7:7)
946                                 | SetBitField(horizEnd,4:0,4:0);
947         regp->CRTC[NV_VGA_CRTCX_VTOTAL]  = SetBitField(vertTotal,7:0,7:0);
948         regp->CRTC[NV_VGA_CRTCX_OVERFLOW]  = SetBitField(vertTotal,8:8,0:0)
949                                 | SetBitField(vertDisplay,8:8,1:1)
950                                 | SetBitField(vertStart,8:8,2:2)
951                                 | SetBitField(vertBlankStart,8:8,3:3)
952                                 | SetBitField(linecomp,8:8,4:4)
953                                 | SetBitField(vertTotal,9:9,5:5)
954                                 | SetBitField(vertDisplay,9:9,6:6)
955                                 | SetBitField(vertStart,9:9,7:7);
956         regp->CRTC[NV_VGA_CRTCX_MAXSCLIN]  = SetBitField(vertBlankStart,9:9,5:5)
957                                 | SetBit(6)
958                                 | ((mode->Flags & V_DBLSCAN) ? 0x80 : 0x00);
959         regp->CRTC[NV_VGA_CRTCX_VSYNCS] = Set8Bits(vertStart);
960         regp->CRTC[NV_VGA_CRTCX_VSYNCE] = SetBitField(vertEnd,3:0,3:0) | SetBit(5);
961         regp->CRTC[NV_VGA_CRTCX_VDISPE] = Set8Bits(vertDisplay);
962         regp->CRTC[NV_VGA_CRTCX_PITCHL] = ((pScrn->displayWidth/8)*(pLayout->bitsPerPixel/8));
963         regp->CRTC[NV_VGA_CRTCX_VBLANKS] = Set8Bits(vertBlankStart);
964         regp->CRTC[NV_VGA_CRTCX_VBLANKE] = Set8Bits(vertBlankEnd);
965         /* Not an extended register */
966         regp->CRTC[NV_VGA_CRTCX_LINECOMP] = Set8Bits(linecomp);
967
968         regp->Attribute[0x10] = 0x01;
969
970         if(pNv->Television)
971                 regp->Attribute[0x11] = 0x00;
972
973         regp->CRTC[NV_VGA_CRTCX_LSR] = SetBitField(horizBlankEnd,6:6,4:4)
974                                 | SetBitField(vertBlankStart,10:10,3:3)
975                                 | SetBitField(vertStart,10:10,2:2)
976                                 | SetBitField(vertDisplay,10:10,1:1)
977                                 | SetBitField(vertTotal,10:10,0:0);
978
979         regp->CRTC[NV_VGA_CRTCX_HEB] = SetBitField(horizTotal,8:8,0:0) 
980                                 | SetBitField(horizDisplay,8:8,1:1)
981                                 | SetBitField(horizBlankStart,8:8,2:2)
982                                 | SetBitField(horizStart,8:8,3:3);
983
984         regp->CRTC[NV_VGA_CRTCX_EXTRA] = SetBitField(vertTotal,11:11,0:0)
985                                 | SetBitField(vertDisplay,11:11,2:2)
986                                 | SetBitField(vertStart,11:11,4:4)
987                                 | SetBitField(vertBlankStart,11:11,6:6);
988
989         if(mode->Flags & V_INTERLACE) {
990                 horizTotal = (horizTotal >> 1) & ~1;
991                 regp->CRTC[NV_VGA_CRTCX_INTERLACE] = Set8Bits(horizTotal);
992                 regp->CRTC[NV_VGA_CRTCX_HEB] |= SetBitField(horizTotal,8:8,4:4);
993         } else {
994                 regp->CRTC[NV_VGA_CRTCX_INTERLACE] = 0xff;  /* interlace off */
995         }
996
997         regp->CRTC[NV_VGA_CRTCX_BUFFER] = 0xfa;
998
999         if (is_fp) {
1000                 /* Maybe we need more to enable DFP screens, haiku has some info on this register */
1001                 regp->CRTC[NV_VGA_CRTCX_LCD] = (1 << 3) | (1 << 0);
1002         } else {
1003                 regp->CRTC[NV_VGA_CRTCX_LCD] = 0;
1004         }
1005
1006         /* I'm trusting haiku driver on this one, they say it enables an external TDMS clock */
1007         if (is_fp) {
1008                 regp->CRTC[NV_VGA_CRTCX_59] = 0x1;
1009         } else {
1010                 regp->CRTC[NV_VGA_CRTCX_59] = 0x0;
1011         }
1012
1013         /*
1014         * Initialize DAC palette.
1015         */
1016         if(pLayout->bitsPerPixel != 8 ) {
1017                 for (i = 0; i < 256; i++) {
1018                         regp->DAC[i*3]     = i;
1019                         regp->DAC[(i*3)+1] = i;
1020                         regp->DAC[(i*3)+2] = i;
1021                 }
1022         }
1023
1024         /*
1025         * Calculate the extended registers.
1026         */
1027
1028         if(pLayout->depth < 24) {
1029                 i = pLayout->depth;
1030         } else {
1031                 i = 32;
1032         }
1033
1034         if(pNv->Architecture >= NV_ARCH_10) {
1035                 pNv->CURSOR = (CARD32 *)pNv->Cursor->map;
1036         }
1037
1038         ErrorF("crtc %d %d %d\n", nv_crtc->crtc, mode->CrtcHDisplay, pScrn->displayWidth);
1039         nv_crtc_calc_state_ext(crtc,
1040                                 i,
1041                                 pScrn->displayWidth,
1042                                 mode->CrtcHDisplay,
1043                                 mode->CrtcVDisplay,
1044                                 mode->Clock,
1045                                 mode->Flags);
1046
1047         if (is_fp) {
1048                 regp->CRTC[NV_VGA_CRTCX_PIXEL] |= (1 << 7);
1049         }
1050
1051         regp->CRTC[NV_VGA_CRTCX_FIFO1] = savep->CRTC[NV_VGA_CRTCX_FIFO1] & ~(1<<5);
1052
1053         /* NV40's don't set FPP units, unless in special conditions (then they set both) */
1054         /* But what are those special conditions? */
1055         if (pNv->Architecture <= NV_ARCH_30) {
1056                 if (is_fp) {
1057                         if(nv_crtc->head == 1) {
1058                                 regp->head |= NV_CRTC_FSEL_FPP1;
1059                         } else if (pNv->twoHeads) {
1060                                 regp->head |= NV_CRTC_FSEL_FPP2;
1061                         }
1062                 }
1063         }
1064
1065         /* In some situations I2C is also enabled on head 1, even when head 1 is not used */
1066         /* Seems to be in "crosswired" tmds situations as far as i can tell (only one known case) */
1067         if (nv_crtc->head == 0) {
1068                 regp->head |= NV_CRTC_FSEL_I2C;
1069                 if (pNv->overlayAdaptor) {
1070                         regp->head |= NV_CRTC_FSEL_OVERLAY;
1071                 }
1072         }
1073
1074         regp->cursorConfig = 0x00000100;
1075         if(mode->Flags & V_DBLSCAN)
1076                 regp->cursorConfig |= (1 << 4);
1077         if(pNv->alphaCursor) {
1078                 if((pNv->Chipset & 0x0ff0) != CHIPSET_NV11) {
1079                         regp->cursorConfig |= 0x04011000;
1080                 } else {
1081                         regp->cursorConfig |= 0x14011000;
1082                 }
1083         } else {
1084                 regp->cursorConfig |= 0x02000000;
1085         }
1086
1087         regp->CRTC[NV_VGA_CRTCX_FP_HTIMING] = 0;
1088         regp->CRTC[NV_VGA_CRTCX_FP_VTIMING] = 0;
1089
1090         /* 0x20 seems to be enabled and 0x14 disabled */
1091         regp->CRTC[NV_VGA_CRTCX_26] = 0x20;
1092
1093         /* 0x00 is disabled, 0x22 crt and 0x88 dfp */
1094         /* 0x11 is LVDS? */
1095         if (is_fp) {
1096                 regp->CRTC[NV_VGA_CRTCX_3B] = 0x88;
1097         } else {
1098                 regp->CRTC[NV_VGA_CRTCX_3B] = 0x22;
1099         }
1100
1101         /* These values seem to vary */
1102         regp->CRTC[NV_VGA_CRTCX_3C] = savep->CRTC[NV_VGA_CRTCX_3C];
1103
1104         /* 0x80 seems to be used very often, if not always */
1105         regp->CRTC[NV_VGA_CRTCX_45] = 0x80;
1106
1107         /* These values seem to vary */
1108         /* 0x01, 0x10, 0x11 for example */
1109         regp->CRTC[NV_VGA_CRTCX_56] = savep->CRTC[NV_VGA_CRTCX_56];
1110
1111         /* bit0: Seems to be mostly used on crtc1 */
1112         /* bit1: 1=crtc1, 0=crtc, but i'm unsure about this */
1113         /* 0x7E (crtc0, only seen in one dump) and 0x7F (crtc1) seem to be some kind of disable setting */
1114         /* This is likely to be incomplete */
1115         /* This is a very strange register, changed very often by the blob */
1116         regp->CRTC[NV_VGA_CRTCX_58] = 0x0;
1117
1118         /* The blob seems to take the current value from crtc 0, add 4 to that and reuse the old value for crtc 1*/
1119         if (nv_crtc->head == 1) {
1120                 regp->CRTC[NV_VGA_CRTCX_52] = pNv->misc_info.crtc_0_reg_52;
1121         } else {
1122                 regp->CRTC[NV_VGA_CRTCX_52] = pNv->misc_info.crtc_0_reg_52 + 4;
1123         }
1124
1125         /* The exact purpose of this register is unknown, but we copy value from crtc0 */
1126         regp->unk81c = nvReadCRTC0(pNv, NV_CRTC_081C);
1127
1128         regp->unk830 = mode->CrtcVDisplay - 3;
1129         regp->unk834 = mode->CrtcVDisplay - 1;
1130 }
1131
1132 /**
1133  * Sets up registers for the given mode/adjusted_mode pair.
1134  *
1135  * The clocks, CRTCs and outputs attached to this CRTC must be off.
1136  *
1137  * This shouldn't enable any clocks, CRTCs, or outputs, but they should
1138  * be easily turned on/off after this.
1139  */
1140 static void
1141 nv_crtc_mode_set(xf86CrtcPtr crtc, DisplayModePtr mode,
1142                  DisplayModePtr adjusted_mode,
1143                  int x, int y)
1144 {
1145     ScrnInfoPtr pScrn = crtc->scrn;
1146     NVCrtcPrivatePtr nv_crtc = crtc->driver_private;
1147     NVPtr pNv = NVPTR(pScrn);
1148
1149         ErrorF("nv_crtc_mode_set is called for CRTC %d\n", nv_crtc->crtc);
1150
1151     xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "Mode on CRTC %d\n", nv_crtc->crtc);
1152     xf86PrintModeline(pScrn->scrnIndex, mode);
1153     NVCrtcSetOwner(crtc);
1154
1155     nv_crtc_mode_set_vga(crtc, mode);
1156     nv_crtc_mode_set_regs(crtc, mode);
1157
1158
1159     NVVgaProtect(crtc, TRUE);
1160     nv_crtc_load_state_ext(crtc, &pNv->ModeReg);
1161     nv_crtc_load_state_vga(crtc, &pNv->ModeReg);
1162     nv_crtc_load_state_pll(pNv, &pNv->ModeReg);
1163
1164     NVVgaProtect(crtc, FALSE);
1165     //    NVCrtcLockUnlock(crtc, 1);
1166
1167     NVCrtcSetBase(crtc, x, y);
1168
1169         pNv->crtc_active[nv_crtc->head] = TRUE;
1170 #if X_BYTE_ORDER == X_BIG_ENDIAN
1171     /* turn on LFB swapping */
1172     {
1173         unsigned char tmp;
1174
1175         tmp = NVReadVgaCrtc(crtc, NV_VGA_CRTCX_SWAPPING);
1176         tmp |= (1 << 7);
1177         NVWriteVgaCrtc(crtc, NV_VGA_CRTCX_SWAPPING, tmp);
1178     }
1179 #endif
1180
1181 }
1182
1183 void nv_crtc_save(xf86CrtcPtr crtc)
1184 {
1185     ScrnInfoPtr pScrn = crtc->scrn;
1186     NVCrtcPrivatePtr nv_crtc = crtc->driver_private;
1187     NVPtr pNv = NVPTR(pScrn);
1188
1189         ErrorF("nv_crtc_save is called for CRTC %d\n", nv_crtc->crtc);
1190
1191     NVCrtcSetOwner(crtc);
1192     nv_crtc_save_state_pll(pNv, &pNv->SavedReg);
1193     nv_crtc_save_state_vga(crtc, &pNv->SavedReg);
1194     nv_crtc_save_state_ext(crtc, &pNv->SavedReg);
1195 }
1196
1197 void nv_crtc_restore(xf86CrtcPtr crtc)
1198 {
1199     ScrnInfoPtr pScrn = crtc->scrn;
1200     NVCrtcPrivatePtr nv_crtc = crtc->driver_private;
1201     NVPtr pNv = NVPTR(pScrn);
1202
1203         ErrorF("nv_crtc_restore is called for CRTC %d\n", nv_crtc->crtc);
1204
1205     NVCrtcSetOwner(crtc);    
1206     nv_crtc_load_state_ext(crtc, &pNv->SavedReg);
1207     nv_crtc_load_state_vga(crtc, &pNv->SavedReg);
1208     nv_crtc_load_state_pll(pNv, &pNv->SavedReg);
1209     nvWriteVGA(pNv, NV_VGA_CRTCX_OWNER, pNv->vtOWNER);
1210 }
1211
1212 void nv_crtc_prepare(xf86CrtcPtr crtc)
1213 {
1214     ScrnInfoPtr pScrn = crtc->scrn;
1215     NVPtr pNv = NVPTR(pScrn);
1216         NVCrtcPrivatePtr nv_crtc = crtc->driver_private;
1217
1218         ErrorF("nv_crtc_prepare is called for CRTC %d\n", nv_crtc->crtc);
1219
1220     /* Sync the engine before adjust mode */
1221     if (pNv->EXADriverPtr) {
1222         exaMarkSync(pScrn->pScreen);
1223         exaWaitSync(pScrn->pScreen);
1224     }
1225 }
1226
1227 void nv_crtc_commit(xf86CrtcPtr crtc)
1228 {
1229         NVCrtcPrivatePtr nv_crtc = crtc->driver_private;
1230         ErrorF("nv_crtc_commit for CRTC %d\n", nv_crtc->crtc);
1231 }
1232
1233 static Bool nv_crtc_lock(xf86CrtcPtr crtc)
1234 {
1235         NVCrtcPrivatePtr nv_crtc = crtc->driver_private;
1236         ErrorF("nv_crtc_lock is called for CRTC %d\n", nv_crtc->crtc);
1237
1238         return FALSE;
1239 }
1240
1241 static void nv_crtc_unlock(xf86CrtcPtr crtc)
1242 {
1243         NVCrtcPrivatePtr nv_crtc = crtc->driver_private;
1244         ErrorF("nv_crtc_unlock is called for CRTC %d\n", nv_crtc->crtc);
1245 }
1246
1247 /* NV04-NV10 doesn't support alpha cursors */
1248 static const xf86CrtcFuncsRec nv_crtc_funcs = {
1249         .dpms = nv_crtc_dpms,
1250         .save = nv_crtc_save, /* XXX */
1251         .restore = nv_crtc_restore, /* XXX */
1252         .mode_fixup = nv_crtc_mode_fixup,
1253         .mode_set = nv_crtc_mode_set,
1254         .prepare = nv_crtc_prepare,
1255         .commit = nv_crtc_commit,
1256         .destroy = NULL, /* XXX */
1257         .lock = nv_crtc_lock,
1258         .unlock = nv_crtc_unlock,
1259         .set_cursor_colors = nv_crtc_set_cursor_colors,
1260         .set_cursor_position = nv_crtc_set_cursor_position,
1261         .show_cursor = nv_crtc_show_cursor,
1262         .hide_cursor = nv_crtc_hide_cursor,
1263         .load_cursor_image = nv_crtc_load_cursor_image,
1264 };
1265
1266 /* NV11 and up has support for alpha cursors. */ 
1267 /* Due to different maximum sizes we cannot allow it to use normal cursors */
1268 static const xf86CrtcFuncsRec nv11_crtc_funcs = {
1269         .dpms = nv_crtc_dpms,
1270         .save = nv_crtc_save, /* XXX */
1271         .restore = nv_crtc_restore, /* XXX */
1272         .mode_fixup = nv_crtc_mode_fixup,
1273         .mode_set = nv_crtc_mode_set,
1274         .prepare = nv_crtc_prepare,
1275         .commit = nv_crtc_commit,
1276         .destroy = NULL, /* XXX */
1277         .lock = nv_crtc_lock,
1278         .unlock = nv_crtc_unlock,
1279         .set_cursor_colors = nv_crtc_set_cursor_colors,
1280         .set_cursor_position = nv_crtc_set_cursor_position,
1281         .show_cursor = nv_crtc_show_cursor,
1282         .hide_cursor = nv_crtc_hide_cursor,
1283         .load_cursor_argb = nv_crtc_load_cursor_argb,
1284 };
1285
1286
1287 void
1288 nv_crtc_init(ScrnInfoPtr pScrn, int crtc_num)
1289 {
1290         NVPtr pNv = NVPTR(pScrn);
1291         xf86CrtcPtr crtc;
1292         NVCrtcPrivatePtr nv_crtc;
1293
1294         if (pNv->NVArch >= 0x11) {
1295                 crtc = xf86CrtcCreate (pScrn, &nv11_crtc_funcs);
1296         } else {
1297                 crtc = xf86CrtcCreate (pScrn, &nv_crtc_funcs);
1298         }
1299         if (crtc == NULL)
1300                 return;
1301
1302         nv_crtc = xnfcalloc (sizeof (NVCrtcPrivateRec), 1);
1303         nv_crtc->crtc = crtc_num;
1304         nv_crtc->head = crtc_num;
1305
1306         crtc->driver_private = nv_crtc;
1307
1308         NVCrtcLockUnlock(crtc, 0);
1309 }
1310
1311 static void nv_crtc_load_state_vga(xf86CrtcPtr crtc, RIVA_HW_STATE *state)
1312 {
1313     ScrnInfoPtr pScrn = crtc->scrn;
1314     NVPtr pNv = NVPTR(pScrn);    
1315     NVCrtcPrivatePtr nv_crtc = crtc->driver_private;
1316     int i, j;
1317     CARD32 temp;
1318     NVCrtcRegPtr regp;
1319
1320     regp = &state->crtc_reg[nv_crtc->head];
1321
1322     NVWriteMiscOut(crtc, regp->MiscOutReg);
1323
1324     for (i = 1; i < 5; i++)
1325       NVWriteVgaSeq(crtc, i, regp->Sequencer[i]);
1326   
1327     /* Ensure CRTC registers 0-7 are unlocked by clearing bit 7 of CRTC[17] */
1328     NVWriteVgaCrtc(crtc, 17, regp->CRTC[17] & ~0x80);
1329
1330     for (i = 0; i < 25; i++)
1331       NVWriteVgaCrtc(crtc, i, regp->CRTC[i]);
1332
1333     for (i = 0; i < 9; i++)
1334       NVWriteVgaGr(crtc, i, regp->Graphics[i]);
1335     
1336     NVEnablePalette(crtc);
1337     for (i = 0; i < 21; i++)
1338       NVWriteVgaAttr(crtc, i, regp->Attribute[i]);
1339     NVDisablePalette(crtc);
1340
1341 }
1342
1343 static void nv_crtc_fix_nv40_hw_cursor(xf86CrtcPtr crtc)
1344 {
1345   /* TODO - implement this properly */
1346   ScrnInfoPtr pScrn = crtc->scrn;
1347   NVPtr pNv = NVPTR(pScrn);
1348    
1349   if(pNv->Architecture == NV_ARCH_40) {  /* HW bug */
1350     volatile CARD32 curpos = nvReadCurRAMDAC(pNv, NV_RAMDAC_CURSOR_POS);
1351     nvWriteCurRAMDAC(pNv, NV_RAMDAC_CURSOR_POS, curpos);
1352   }
1353
1354 }
1355 static void nv_crtc_load_state_ext(xf86CrtcPtr crtc, RIVA_HW_STATE *state)
1356 {
1357     ScrnInfoPtr pScrn = crtc->scrn;
1358     NVPtr pNv = NVPTR(pScrn);    
1359     NVCrtcPrivatePtr nv_crtc = crtc->driver_private;
1360     int i, j;
1361     CARD32 temp;
1362     NVCrtcRegPtr regp;
1363     
1364     regp = &state->crtc_reg[nv_crtc->head];
1365
1366     if(pNv->Architecture >= NV_ARCH_10) {
1367         if(pNv->twoHeads) {
1368            nvWriteCRTC(pNv, nv_crtc->head, NV_CRTC_FSEL, regp->head);
1369         }
1370         nvWriteVIDEO(pNv, NV_PVIDEO_STOP, 1);
1371         nvWriteVIDEO(pNv, NV_PVIDEO_INTR_EN, 0);
1372         nvWriteVIDEO(pNv, NV_PVIDEO_OFFSET_BUFF(0), 0);
1373         nvWriteVIDEO(pNv, NV_PVIDEO_OFFSET_BUFF(1), 0);
1374         nvWriteVIDEO(pNv, NV_PVIDEO_LIMIT(0), pNv->VRAMPhysicalSize - 1);
1375         nvWriteVIDEO(pNv, NV_PVIDEO_LIMIT(1), pNv->VRAMPhysicalSize - 1);
1376         nvWriteMC(pNv, 0x1588, 0);
1377
1378         NVWriteVgaCrtc(crtc, NV_VGA_CRTCX_BUFFER, 0xff);
1379         NVWriteVgaCrtc(crtc, NV_VGA_CRTCX_BUFFER, regp->CRTC[NV_VGA_CRTCX_BUFFER]);
1380         nvWriteCRTC(pNv, nv_crtc->head, NV_CRTC_CURSOR_CONFIG, regp->cursorConfig);
1381         nvWriteCRTC(pNv, nv_crtc->head, NV_CRTC_0830, regp->unk830);
1382         nvWriteCRTC(pNv, nv_crtc->head, NV_CRTC_0834, regp->unk834);
1383         nvWriteCRTC(pNv, nv_crtc->head, NV_CRTC_081C, regp->unk81c);
1384         
1385         NVWriteVgaCrtc(crtc, NV_VGA_CRTCX_FP_HTIMING, regp->CRTC[NV_VGA_CRTCX_FP_HTIMING]);
1386         NVWriteVgaCrtc(crtc, NV_VGA_CRTCX_FP_VTIMING, regp->CRTC[NV_VGA_CRTCX_FP_VTIMING]);
1387
1388         NVWriteVgaCrtc(crtc, NV_VGA_CRTCX_26, regp->CRTC[NV_VGA_CRTCX_26]);
1389         NVWriteVgaCrtc(crtc, NV_VGA_CRTCX_3B, regp->CRTC[NV_VGA_CRTCX_3B]);
1390         NVWriteVgaCrtc(crtc, NV_VGA_CRTCX_3C, regp->CRTC[NV_VGA_CRTCX_3C]);
1391         NVWriteVgaCrtc(crtc, NV_VGA_CRTCX_45, regp->CRTC[NV_VGA_CRTCX_45]);
1392         NVWriteVgaCrtc(crtc, NV_VGA_CRTCX_52, regp->CRTC[NV_VGA_CRTCX_52]);
1393         NVWriteVgaCrtc(crtc, NV_VGA_CRTCX_56, regp->CRTC[NV_VGA_CRTCX_56]);
1394         NVWriteVgaCrtc(crtc, NV_VGA_CRTCX_58, regp->CRTC[NV_VGA_CRTCX_58]);
1395         NVWriteVgaCrtc(crtc, NV_VGA_CRTCX_59, regp->CRTC[NV_VGA_CRTCX_59]);
1396         NVWriteVgaCrtc(crtc, NV_VGA_CRTCX_EXTRA, regp->CRTC[NV_VGA_CRTCX_EXTRA]);
1397     }
1398
1399     NVWriteVgaCrtc(crtc, NV_VGA_CRTCX_REPAINT0, regp->CRTC[NV_VGA_CRTCX_REPAINT0]);
1400     NVWriteVgaCrtc(crtc, NV_VGA_CRTCX_REPAINT1, regp->CRTC[NV_VGA_CRTCX_REPAINT1]);
1401     NVWriteVgaCrtc(crtc, NV_VGA_CRTCX_LSR, regp->CRTC[NV_VGA_CRTCX_LSR]);
1402     NVWriteVgaCrtc(crtc, NV_VGA_CRTCX_PIXEL, regp->CRTC[NV_VGA_CRTCX_PIXEL]);
1403     NVWriteVgaCrtc(crtc, NV_VGA_CRTCX_LCD, regp->CRTC[NV_VGA_CRTCX_LCD]);
1404     NVWriteVgaCrtc(crtc, NV_VGA_CRTCX_HEB, regp->CRTC[NV_VGA_CRTCX_HEB]);
1405     NVWriteVgaCrtc(crtc, NV_VGA_CRTCX_FIFO1, regp->CRTC[NV_VGA_CRTCX_FIFO1]);
1406     NVWriteVgaCrtc(crtc, NV_VGA_CRTCX_FIFO0, regp->CRTC[NV_VGA_CRTCX_FIFO0]);
1407     NVWriteVgaCrtc(crtc, NV_VGA_CRTCX_FIFO_LWM, regp->CRTC[NV_VGA_CRTCX_FIFO_LWM]);
1408     if(pNv->Architecture >= NV_ARCH_30) {
1409       NVWriteVgaCrtc(crtc, NV_VGA_CRTCX_FIFO_LWM_NV30, regp->CRTC[NV_VGA_CRTCX_FIFO_LWM_NV30]);
1410     }
1411
1412     NVWriteVgaCrtc(crtc, NV_VGA_CRTCX_CURCTL0, regp->CRTC[NV_VGA_CRTCX_CURCTL0]);
1413     NVWriteVgaCrtc(crtc, NV_VGA_CRTCX_CURCTL1, regp->CRTC[NV_VGA_CRTCX_CURCTL1]);
1414     nv_crtc_fix_nv40_hw_cursor(crtc);
1415     NVWriteVgaCrtc(crtc, NV_VGA_CRTCX_CURCTL2, regp->CRTC[NV_VGA_CRTCX_CURCTL2]);
1416     NVWriteVgaCrtc(crtc, NV_VGA_CRTCX_INTERLACE, regp->CRTC[NV_VGA_CRTCX_INTERLACE]);
1417
1418     nvWriteCRTC(pNv, nv_crtc->head, NV_CRTC_INTR_EN_0, 0);
1419     nvWriteCRTC(pNv, nv_crtc->head, NV_CRTC_INTR_0, NV_CRTC_INTR_VBLANK);
1420
1421     pNv->CurrentState = state;
1422 }
1423
1424 static void nv_crtc_save_state_vga(xf86CrtcPtr crtc, RIVA_HW_STATE *state)
1425 {
1426     ScrnInfoPtr pScrn = crtc->scrn;
1427     NVPtr pNv = NVPTR(pScrn);    
1428     NVCrtcPrivatePtr nv_crtc = crtc->driver_private;
1429     int i;
1430     NVCrtcRegPtr regp;
1431
1432     regp = &state->crtc_reg[nv_crtc->head];
1433
1434     regp->MiscOutReg = NVReadMiscOut(crtc);
1435
1436     for (i = 0; i < 25; i++)
1437         regp->CRTC[i] = NVReadVgaCrtc(crtc, i);
1438
1439     NVEnablePalette(crtc);
1440     for (i = 0; i < 21; i++)
1441         regp->Attribute[i] = NVReadVgaAttr(crtc, i);
1442     NVDisablePalette(crtc);
1443
1444     for (i = 0; i < 9; i++)
1445         regp->Graphics[i] = NVReadVgaGr(crtc, i);
1446
1447     for (i = 1; i < 5; i++)
1448         regp->Sequencer[i] = NVReadVgaSeq(crtc, i);
1449   
1450 }
1451
1452 static void nv_crtc_save_state_ext(xf86CrtcPtr crtc, RIVA_HW_STATE *state)
1453 {
1454     ScrnInfoPtr pScrn = crtc->scrn;
1455     NVPtr pNv = NVPTR(pScrn);    
1456     NVCrtcPrivatePtr nv_crtc = crtc->driver_private;
1457     NVCrtcRegPtr regp;
1458     int i;
1459
1460     regp = &state->crtc_reg[nv_crtc->head];
1461  
1462     regp->CRTC[NV_VGA_CRTCX_LCD] = NVReadVgaCrtc(crtc, NV_VGA_CRTCX_LCD);
1463     regp->CRTC[NV_VGA_CRTCX_REPAINT0] = NVReadVgaCrtc(crtc, NV_VGA_CRTCX_REPAINT0);
1464     regp->CRTC[NV_VGA_CRTCX_REPAINT1] = NVReadVgaCrtc(crtc, NV_VGA_CRTCX_REPAINT1);
1465     regp->CRTC[NV_VGA_CRTCX_LSR] = NVReadVgaCrtc(crtc, NV_VGA_CRTCX_LSR);
1466     regp->CRTC[NV_VGA_CRTCX_PIXEL] = NVReadVgaCrtc(crtc, NV_VGA_CRTCX_PIXEL);
1467     regp->CRTC[NV_VGA_CRTCX_HEB] = NVReadVgaCrtc(crtc, NV_VGA_CRTCX_HEB);
1468     regp->CRTC[NV_VGA_CRTCX_FIFO1] = NVReadVgaCrtc(crtc, NV_VGA_CRTCX_FIFO1);
1469
1470     regp->CRTC[NV_VGA_CRTCX_FIFO0] = NVReadVgaCrtc(crtc, NV_VGA_CRTCX_FIFO0);
1471     regp->CRTC[NV_VGA_CRTCX_FIFO_LWM] = NVReadVgaCrtc(crtc, NV_VGA_CRTCX_FIFO_LWM);
1472     if(pNv->Architecture >= NV_ARCH_30) {
1473          regp->CRTC[NV_VGA_CRTCX_FIFO_LWM_NV30] = NVReadVgaCrtc(crtc, NV_VGA_CRTCX_FIFO_LWM_NV30);
1474     }
1475     regp->CRTC[NV_VGA_CRTCX_CURCTL0] = NVReadVgaCrtc(crtc, NV_VGA_CRTCX_CURCTL0);
1476     regp->CRTC[NV_VGA_CRTCX_CURCTL1] = NVReadVgaCrtc(crtc, NV_VGA_CRTCX_CURCTL1);
1477     regp->CRTC[NV_VGA_CRTCX_CURCTL2] = NVReadVgaCrtc(crtc, NV_VGA_CRTCX_CURCTL2);
1478     regp->CRTC[NV_VGA_CRTCX_INTERLACE] = NVReadVgaCrtc(crtc, NV_VGA_CRTCX_INTERLACE);
1479  
1480     regp->unk830 = nvReadCRTC(pNv, nv_crtc->head, NV_CRTC_0830);
1481     regp->unk834 = nvReadCRTC(pNv, nv_crtc->head, NV_CRTC_0834);
1482     regp->unk81c = nvReadCRTC(pNv, nv_crtc->head, NV_CRTC_081C);
1483
1484     if(pNv->Architecture >= NV_ARCH_10) {
1485         if(pNv->twoHeads) {
1486            regp->head     = nvReadCRTC(pNv, nv_crtc->head, NV_CRTC_FSEL);
1487            regp->crtcOwner = NVReadVgaCrtc(crtc, NV_VGA_CRTCX_OWNER);
1488         }
1489         regp->CRTC[NV_VGA_CRTCX_EXTRA] = NVReadVgaCrtc(crtc, NV_VGA_CRTCX_EXTRA);
1490
1491         regp->cursorConfig = nvReadCRTC(pNv, nv_crtc->head, NV_CRTC_CURSOR_CONFIG);
1492
1493         regp->CRTC[NV_VGA_CRTCX_26] = NVReadVgaCrtc(crtc, NV_VGA_CRTCX_26);
1494         regp->CRTC[NV_VGA_CRTCX_3B] = NVReadVgaCrtc(crtc, NV_VGA_CRTCX_3B);
1495         regp->CRTC[NV_VGA_CRTCX_3C] = NVReadVgaCrtc(crtc, NV_VGA_CRTCX_3C);
1496         regp->CRTC[NV_VGA_CRTCX_45] = NVReadVgaCrtc(crtc, NV_VGA_CRTCX_45);
1497         regp->CRTC[NV_VGA_CRTCX_52] = NVReadVgaCrtc(crtc, NV_VGA_CRTCX_52);
1498         regp->CRTC[NV_VGA_CRTCX_56] = NVReadVgaCrtc(crtc, NV_VGA_CRTCX_56);
1499         regp->CRTC[NV_VGA_CRTCX_58] = NVReadVgaCrtc(crtc, NV_VGA_CRTCX_58);
1500         regp->CRTC[NV_VGA_CRTCX_59] = NVReadVgaCrtc(crtc, NV_VGA_CRTCX_59);
1501         regp->CRTC[NV_VGA_CRTCX_BUFFER] = NVReadVgaCrtc(crtc, NV_VGA_CRTCX_BUFFER);
1502         regp->CRTC[NV_VGA_CRTCX_FP_HTIMING] = NVReadVgaCrtc(crtc, NV_VGA_CRTCX_FP_HTIMING);
1503         regp->CRTC[NV_VGA_CRTCX_FP_VTIMING] = NVReadVgaCrtc(crtc, NV_VGA_CRTCX_FP_VTIMING);
1504     }
1505 }
1506
1507 void
1508 NVCrtcSetBase (xf86CrtcPtr crtc, int x, int y)
1509 {
1510     ScrnInfoPtr pScrn = crtc->scrn;
1511     NVPtr pNv = NVPTR(pScrn);    
1512     NVCrtcPrivatePtr nv_crtc = crtc->driver_private;
1513     NVFBLayout *pLayout = &pNv->CurrentLayout;
1514     CARD32 start = 0;
1515
1516         ErrorF("NVCrtcSetBase: x: %d y: %d\n", x, y);
1517
1518     start += ((y * pScrn->displayWidth + x) * (pLayout->bitsPerPixel/8));
1519     start += pNv->FB->offset;
1520
1521     nvWriteCRTC(pNv, nv_crtc->head, NV_CRTC_START, start);
1522
1523     crtc->x = x;
1524     crtc->y = y;
1525 }
1526
1527 static void NVCrtcWriteDacMask(xf86CrtcPtr crtc, CARD8 value)
1528 {
1529   ScrnInfoPtr pScrn = crtc->scrn;
1530   NVCrtcPrivatePtr nv_crtc = crtc->driver_private;
1531   NVPtr pNv = NVPTR(pScrn);
1532   volatile CARD8 *pDACReg = nv_crtc->head ? pNv->PDIO1 : pNv->PDIO0;
1533
1534   NV_WR08(pDACReg, VGA_DAC_MASK, value);
1535 }
1536
1537 static CARD8 NVCrtcReadDacMask(xf86CrtcPtr crtc)
1538 {
1539   ScrnInfoPtr pScrn = crtc->scrn;
1540   NVCrtcPrivatePtr nv_crtc = crtc->driver_private;
1541   NVPtr pNv = NVPTR(pScrn);
1542   volatile CARD8 *pDACReg = nv_crtc->head ? pNv->PDIO1 : pNv->PDIO0;
1543   
1544   return NV_RD08(pDACReg, VGA_DAC_MASK);
1545 }
1546
1547 static void NVCrtcWriteDacReadAddr(xf86CrtcPtr crtc, CARD8 value)
1548 {
1549   ScrnInfoPtr pScrn = crtc->scrn;
1550   NVCrtcPrivatePtr nv_crtc = crtc->driver_private;
1551   NVPtr pNv = NVPTR(pScrn);
1552   volatile CARD8 *pDACReg = nv_crtc->head ? pNv->PDIO1 : pNv->PDIO0;
1553
1554   NV_WR08(pDACReg, VGA_DAC_READ_ADDR, value);
1555 }
1556
1557 static void NVCrtcWriteDacWriteAddr(xf86CrtcPtr crtc, CARD8 value)
1558 {
1559   ScrnInfoPtr pScrn = crtc->scrn;
1560   NVCrtcPrivatePtr nv_crtc = crtc->driver_private;
1561   NVPtr pNv = NVPTR(pScrn);
1562   volatile CARD8 *pDACReg = nv_crtc->head ? pNv->PDIO1 : pNv->PDIO0;
1563
1564   NV_WR08(pDACReg, VGA_DAC_WRITE_ADDR, value);
1565 }
1566
1567 static void NVCrtcWriteDacData(xf86CrtcPtr crtc, CARD8 value)
1568 {
1569   ScrnInfoPtr pScrn = crtc->scrn;
1570   NVCrtcPrivatePtr nv_crtc = crtc->driver_private;
1571   NVPtr pNv = NVPTR(pScrn);
1572   volatile CARD8 *pDACReg = nv_crtc->head ? pNv->PDIO1 : pNv->PDIO0;
1573
1574   NV_WR08(pDACReg, VGA_DAC_DATA, value);
1575 }
1576
1577 static CARD8 NVCrtcReadDacData(xf86CrtcPtr crtc, CARD8 value)
1578 {
1579   ScrnInfoPtr pScrn = crtc->scrn;
1580   NVCrtcPrivatePtr nv_crtc = crtc->driver_private;
1581   NVPtr pNv = NVPTR(pScrn);
1582   volatile CARD8 *pDACReg = nv_crtc->head ? pNv->PDIO1 : pNv->PDIO0;
1583
1584   return NV_RD08(pDACReg, VGA_DAC_DATA);
1585 }
1586
1587 void NVCrtcLoadPalette(xf86CrtcPtr crtc)
1588 {
1589   int i;
1590   NVCrtcPrivatePtr nv_crtc = crtc->driver_private;
1591   NVCrtcRegPtr regp;
1592   ScrnInfoPtr pScrn = crtc->scrn;
1593   NVPtr pNv = NVPTR(pScrn);
1594     
1595   regp = &pNv->ModeReg.crtc_reg[nv_crtc->head];
1596
1597   NVCrtcSetOwner(crtc);
1598   NVCrtcWriteDacMask(crtc, 0xff);
1599   NVCrtcWriteDacWriteAddr(crtc, 0x00);
1600
1601   for (i = 0; i<768; i++) {
1602     NVCrtcWriteDacData(crtc, regp->DAC[i]);
1603   }
1604   NVDisablePalette(crtc);
1605 }
1606
1607 void NVCrtcBlankScreen(xf86CrtcPtr crtc, Bool on)
1608 {
1609     NVCrtcPrivatePtr nv_crtc = crtc->driver_private;
1610     unsigned char scrn;
1611
1612     NVCrtcSetOwner(crtc);
1613
1614     scrn = NVReadVgaSeq(crtc, 0x01);
1615     if (on) {
1616         scrn &= ~0x20;
1617     } else {
1618         scrn |= 0x20;
1619     }
1620
1621     NVVgaSeqReset(crtc, TRUE);
1622     NVWriteVgaSeq(crtc, 0x01, scrn);
1623     NVVgaSeqReset(crtc, FALSE);
1624 }
1625
1626 #endif /* ENABLE_RANDR12 */
1627
1628 /*************************************************************************** \
1629 |*                                                                           *|
1630 |*       Copyright 1993-2003 NVIDIA, Corporation.  All rights reserved.      *|
1631 |*                                                                           *|
1632 |*     NOTICE TO USER:   The source code  is copyrighted under  U.S. and     *|
1633 |*     international laws.  Users and possessors of this source code are     *|
1634 |*     hereby granted a nonexclusive,  royalty-free copyright license to     *|
1635 |*     use this code in individual and commercial software.                  *|
1636 |*                                                                           *|
1637 |*     Any use of this source code must include,  in the user documenta-     *|
1638 |*     tion and  internal comments to the code,  notices to the end user     *|
1639 |*     as follows:                                                           *|
1640 |*                                                                           *|
1641 |*       Copyright 1993-1999 NVIDIA, Corporation.  All rights reserved.      *|
1642 |*                                                                           *|
1643 |*     NVIDIA, CORPORATION MAKES NO REPRESENTATION ABOUT THE SUITABILITY     *|
1644 |*     OF  THIS SOURCE  CODE  FOR ANY PURPOSE.  IT IS  PROVIDED  "AS IS"     *|
1645 |*     WITHOUT EXPRESS OR IMPLIED WARRANTY OF ANY KIND.  NVIDIA, CORPOR-     *|
1646 |*     ATION DISCLAIMS ALL WARRANTIES  WITH REGARD  TO THIS SOURCE CODE,     *|
1647 |*     INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGE-     *|
1648 |*     MENT,  AND FITNESS  FOR A PARTICULAR PURPOSE.   IN NO EVENT SHALL     *|
1649 |*     NVIDIA, CORPORATION  BE LIABLE FOR ANY SPECIAL,  INDIRECT,  INCI-     *|
1650 |*     DENTAL, OR CONSEQUENTIAL DAMAGES,  OR ANY DAMAGES  WHATSOEVER RE-     *|
1651 |*     SULTING FROM LOSS OF USE,  DATA OR PROFITS,  WHETHER IN AN ACTION     *|
1652 |*     OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,  ARISING OUT OF     *|
1653 |*     OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOURCE CODE.     *|
1654 |*                                                                           *|
1655 |*     U.S. Government  End  Users.   This source code  is a "commercial     *|
1656 |*     item,"  as that  term is  defined at  48 C.F.R. 2.101 (OCT 1995),     *|
1657 |*     consisting  of "commercial  computer  software"  and  "commercial     *|
1658 |*     computer  software  documentation,"  as such  terms  are  used in     *|
1659 |*     48 C.F.R. 12.212 (SEPT 1995)  and is provided to the U.S. Govern-     *|
1660 |*     ment only as  a commercial end item.   Consistent with  48 C.F.R.     *|
1661 |*     12.212 and  48 C.F.R. 227.7202-1 through  227.7202-4 (JUNE 1995),     *|
1662 |*     all U.S. Government End Users  acquire the source code  with only     *|
1663 |*     those rights set forth herein.                                        *|
1664 |*                                                                           *|
1665  \***************************************************************************/