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