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