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