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