randr12: fix dpms, detect, destroy, save and restore for multiple encoders per connector
[nouveau] / src / nv_hw.c
1 /*
2  * Copyright 1993-2003 NVIDIA, Corporation
3  * Copyright 2008 Stuart Bennett
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 shall be included in
13  * all copies or substantial portions of the Software.
14  *
15  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
18  * THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
19  * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
20  * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21  * SOFTWARE.
22  */
23
24 #include "nv_include.h"
25 #include "nv_local.h"
26 #include "compiler.h"
27
28 uint32_t NVRead(NVPtr pNv, uint32_t reg)
29 {
30         DDXMMIOW("NVRead: reg %08x val %08x\n", reg, (uint32_t)NV_RD32(pNv->REGS, reg));
31         return NV_RD32(pNv->REGS, reg);
32 }
33
34 void NVWrite(NVPtr pNv, uint32_t reg, uint32_t val)
35 {
36         DDXMMIOW("NVWrite: reg %08x val %08x\n", reg, NV_WR32(pNv->REGS, reg, val));
37 }
38
39 uint32_t NVReadCRTC(NVPtr pNv, int head, uint32_t reg)
40 {
41         if (head)
42                 reg += NV_PCRTC0_SIZE;
43         DDXMMIOH("NVReadCRTC: head %d reg %08x val %08x\n", head, reg, (uint32_t)NV_RD32(pNv->REGS, reg));
44         return NV_RD32(pNv->REGS, reg);
45 }
46
47 void NVWriteCRTC(NVPtr pNv, int head, uint32_t reg, uint32_t val)
48 {
49         if (head)
50                 reg += NV_PCRTC0_SIZE;
51         DDXMMIOH("NVWriteCRTC: head %d reg %08x val %08x\n", head, reg, val);
52         NV_WR32(pNv->REGS, reg, val);
53 }
54
55 uint32_t NVReadRAMDAC(NVPtr pNv, int head, uint32_t reg)
56 {
57         if (head)
58                 reg += NV_PRAMDAC0_SIZE;
59         DDXMMIOH("NVReadRamdac: head %d reg %08x val %08x\n", head, reg, (uint32_t)NV_RD32(pNv->REGS, reg));
60         return NV_RD32(pNv->REGS, reg);
61 }
62
63 void NVWriteRAMDAC(NVPtr pNv, int head, uint32_t reg, uint32_t val)
64 {
65         if (head)
66                 reg += NV_PRAMDAC0_SIZE;
67         DDXMMIOH("NVWriteRamdac: head %d reg %08x val %08x\n", head, reg, val);
68         NV_WR32(pNv->REGS, reg, val);
69 }
70
71 uint8_t nv_read_tmds(NVPtr pNv, int or, int dl, uint8_t address)
72 {
73         int ramdac = (or & OUTPUT_C) >> 2;
74
75         NVWriteRAMDAC(pNv, ramdac, NV_RAMDAC_FP_TMDS_CONTROL + dl * 8,
76                       NV_RAMDAC_FP_TMDS_CONTROL_WRITE_DISABLE | address);
77         return NVReadRAMDAC(pNv, ramdac, NV_RAMDAC_FP_TMDS_DATA + dl * 8);
78 }
79
80 int nv_get_digital_bound_head(NVPtr pNv, int or)
81 {
82         /* special case of nv_read_tmds to find crtc associated with an output.
83          * this does not give a correct answer for off-chip dvi, but there's no
84          * use for such an answer anyway
85          */
86         int ramdac = (or & OUTPUT_C) >> 2;
87
88         NVWriteRAMDAC(pNv, ramdac, NV_RAMDAC_FP_TMDS_CONTROL,
89                       NV_RAMDAC_FP_TMDS_CONTROL_WRITE_DISABLE | 0x4);
90         return (((NVReadRAMDAC(pNv, ramdac, NV_RAMDAC_FP_TMDS_DATA) & 0x8) >> 3) ^ ramdac);
91 }
92
93 void nv_write_tmds(NVPtr pNv, int or, int dl, uint8_t address, uint8_t data)
94 {
95         int ramdac = (or & OUTPUT_C) >> 2;
96
97         NVWriteRAMDAC(pNv, ramdac, NV_RAMDAC_FP_TMDS_DATA + dl * 8, data);
98         NVWriteRAMDAC(pNv, ramdac, NV_RAMDAC_FP_TMDS_CONTROL + dl * 8, address);
99 }
100
101 void NVWriteVgaCrtc(NVPtr pNv, int head, uint8_t index, uint8_t value)
102 {
103         uint32_t mmiobase = head ? NV_PCIO1_OFFSET : NV_PCIO0_OFFSET;
104
105         DDXMMIOH("NVWriteVgaCrtc: head %d index 0x%02x data 0x%02x\n", head, index, value);
106         NV_WR08(pNv->REGS, CRTC_INDEX_COLOR + mmiobase, index);
107         NV_WR08(pNv->REGS, CRTC_DATA_COLOR + mmiobase, value);
108 }
109
110 uint8_t NVReadVgaCrtc(NVPtr pNv, int head, uint8_t index)
111 {
112         uint32_t mmiobase = head ? NV_PCIO1_OFFSET : NV_PCIO0_OFFSET;
113
114         NV_WR08(pNv->REGS, CRTC_INDEX_COLOR + mmiobase, index);
115         DDXMMIOH("NVReadVgaCrtc: head %d index 0x%02x data 0x%02x\n", head, index, NV_RD08(pNv->REGS, CRTC_DATA_COLOR + mmiobase));
116         return NV_RD08(pNv->REGS, CRTC_DATA_COLOR + mmiobase);
117 }
118
119 /* CR57 and CR58 are a fun pair of regs. CR57 provides an index (0-0xf) for CR58
120  * I suspect they in fact do nothing, but are merely a way to carry useful
121  * per-head variables around
122  *
123  * Known uses:
124  * CR57         CR58
125  * 0x00         index to the appropriate dcb entry (or 7f for inactive)
126  * 0x02         dcb entry's "or" value (or 00 for inactive)
127  * 0x03         bit0 set for dual link (LVDS, possibly elsewhere too)
128  * 0x08 or 0x09 pxclk in MHz
129  * 0x0f         laptop panel info -     low nibble for PEXTDEV_BOOT_0 strap
130  *                                      high nibble for xlat strap value
131  */
132
133 void NVWriteVgaCrtc5758(NVPtr pNv, int head, uint8_t index, uint8_t value)
134 {
135         NVWriteVgaCrtc(pNv, head, 0x57, index);
136         NVWriteVgaCrtc(pNv, head, 0x58, value);
137 }
138
139 uint8_t NVReadVgaCrtc5758(NVPtr pNv, int head, uint8_t index)
140 {
141         NVWriteVgaCrtc(pNv, head, 0x57, index);
142         return NVReadVgaCrtc(pNv, head, 0x58);
143 }
144
145 uint8_t NVReadPVIO(NVPtr pNv, int head, uint16_t port)
146 {
147         /* Only NV4x have two pvio ranges */
148         uint32_t mmiobase = (head && pNv->Architecture == NV_ARCH_40) ? NV_PVIO1_OFFSET : NV_PVIO0_OFFSET;
149
150         DDXMMIOH("NVReadPVIO: head %d reg %08x val %02x\n", head, port + mmiobase, NV_RD08(pNv->REGS, port + mmiobase));
151         return NV_RD08(pNv->REGS, port + mmiobase);
152 }
153
154 void NVWritePVIO(NVPtr pNv, int head, uint16_t port, uint8_t value)
155 {
156         /* Only NV4x have two pvio ranges */
157         uint32_t mmiobase = (head && pNv->Architecture == NV_ARCH_40) ? NV_PVIO1_OFFSET : NV_PVIO0_OFFSET;
158
159         DDXMMIOH("NVWritePVIO: head %d reg %08x val %02x\n", head, port + mmiobase, value);
160         NV_WR08(pNv->REGS, port + mmiobase, value);
161 }
162
163 void NVWriteVgaSeq(NVPtr pNv, int head, uint8_t index, uint8_t value)
164 {
165         NVWritePVIO(pNv, head, VGA_SEQ_INDEX, index);
166         NVWritePVIO(pNv, head, VGA_SEQ_DATA, value);
167 }
168
169 uint8_t NVReadVgaSeq(NVPtr pNv, int head, uint8_t index)
170 {
171         NVWritePVIO(pNv, head, VGA_SEQ_INDEX, index);
172         return NVReadPVIO(pNv, head, VGA_SEQ_DATA);
173 }
174
175 void NVWriteVgaGr(NVPtr pNv, int head, uint8_t index, uint8_t value)
176 {
177         NVWritePVIO(pNv, head, VGA_GRAPH_INDEX, index);
178         NVWritePVIO(pNv, head, VGA_GRAPH_DATA, value);
179 }
180
181 uint8_t NVReadVgaGr(NVPtr pNv, int head, uint8_t index)
182 {
183         NVWritePVIO(pNv, head, VGA_GRAPH_INDEX, index);
184         return NVReadPVIO(pNv, head, VGA_GRAPH_DATA);
185 }
186
187 #define CRTC_IN_STAT_1 0x3da
188
189 void NVSetEnablePalette(NVPtr pNv, int head, bool enable)
190 {
191         uint32_t mmiobase = head ? NV_PCIO1_OFFSET : NV_PCIO0_OFFSET;
192
193         VGA_RD08(pNv->REGS, CRTC_IN_STAT_1 + mmiobase);
194         VGA_WR08(pNv->REGS, VGA_ATTR_INDEX + mmiobase, enable ? 0 : 0x20);
195 }
196
197 static bool NVGetEnablePalette(NVPtr pNv, int head)
198 {
199         uint32_t mmiobase = head ? NV_PCIO1_OFFSET : NV_PCIO0_OFFSET;
200
201         VGA_RD08(pNv->REGS, CRTC_IN_STAT_1 + mmiobase);
202         return !(VGA_RD08(pNv->REGS, VGA_ATTR_INDEX + mmiobase) & 0x20);
203 }
204
205 void NVWriteVgaAttr(NVPtr pNv, int head, uint8_t index, uint8_t value)
206 {
207         uint32_t mmiobase = head ? NV_PCIO1_OFFSET : NV_PCIO0_OFFSET;
208
209         if (NVGetEnablePalette(pNv, head))
210                 index &= ~0x20;
211         else
212                 index |= 0x20;
213
214         NV_RD08(pNv->REGS, CRTC_IN_STAT_1 + mmiobase);
215         DDXMMIOH("NVWriteVgaAttr: head %d index 0x%02x data 0x%02x\n", head, index, value);
216         NV_WR08(pNv->REGS, VGA_ATTR_INDEX + mmiobase, index);
217         NV_WR08(pNv->REGS, VGA_ATTR_DATA_W + mmiobase, value);
218 }
219
220 uint8_t NVReadVgaAttr(NVPtr pNv, int head, uint8_t index)
221 {
222         uint32_t mmiobase = head ? NV_PCIO1_OFFSET : NV_PCIO0_OFFSET;
223
224         if (NVGetEnablePalette(pNv, head))
225                 index &= ~0x20;
226         else
227                 index |= 0x20;
228
229         NV_RD08(pNv->REGS, CRTC_IN_STAT_1 + mmiobase);
230         NV_WR08(pNv->REGS, VGA_ATTR_INDEX + mmiobase, index);
231         DDXMMIOH("NVReadVgaAttr: head %d index 0x%02x data 0x%02x\n", head, index, NV_RD08(pNv->REGS, VGA_ATTR_DATA_R + mmiobase));
232         return NV_RD08(pNv->REGS, VGA_ATTR_DATA_R + mmiobase);
233 }
234
235 void NVVgaSeqReset(NVPtr pNv, int head, bool start)
236 {
237         NVWriteVgaSeq(pNv, head, 0x0, start ? 0x1 : 0x3);
238 }
239
240 void NVVgaProtect(NVPtr pNv, int head, bool protect)
241 {
242         uint8_t seq1 = NVReadVgaSeq(pNv, head, 0x1);
243
244         if (protect) {
245                 NVVgaSeqReset(pNv, head, true);
246                 NVWriteVgaSeq(pNv, head, 0x01, seq1 | 0x20);
247         } else {
248                 /* Reenable sequencer, then turn on screen */
249                 NVWriteVgaSeq(pNv, head, 0x01, seq1 & ~0x20);   /* reenable display */
250                 NVVgaSeqReset(pNv, head, false);
251         }
252         NVSetEnablePalette(pNv, head, protect);
253 }
254
255 void NVSetOwner(ScrnInfoPtr pScrn, int head)
256 {
257         NVPtr pNv = NVPTR(pScrn);
258         /* CRTCX_OWNER is always changed on CRTC0 */
259         NVWriteVgaCrtc(pNv, 0, NV_VGA_CRTCX_OWNER, head * 0x3);
260
261         xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Setting owner: 0x%X.\n", head * 0x3);
262 }
263
264 void NVLockVgaCrtc(NVPtr pNv, int head, bool lock)
265 {
266         uint8_t cr11;
267
268         NVWriteVgaCrtc(pNv, head, NV_VGA_CRTCX_LOCK, lock ? 0x99 : 0x57);
269
270         cr11 = NVReadVgaCrtc(pNv, head, NV_VGA_CRTCX_VSYNCE);
271         if (lock)
272                 cr11 |= 0x80;
273         else
274                 cr11 &= ~0x80;
275         NVWriteVgaCrtc(pNv, head, NV_VGA_CRTCX_VSYNCE, cr11);
276 }
277
278 void NVBlankScreen(ScrnInfoPtr pScrn, int head, bool blank)
279 {
280         unsigned char seq1;
281         NVPtr pNv = NVPTR(pScrn);
282
283         if (pNv->twoHeads)
284                 NVSetOwner(pScrn, head);
285
286         seq1 = NVReadVgaSeq(pNv, head, 0x1);
287
288         NVVgaSeqReset(pNv, head, TRUE);
289         if (blank)
290                 NVWriteVgaSeq(pNv, head, 0x1, seq1 | 0x20);
291         else
292                 NVWriteVgaSeq(pNv, head, 0x1, seq1 & ~0x20);
293         NVVgaSeqReset(pNv, head, FALSE);
294 }
295
296 int nv_decode_pll_highregs(NVPtr pNv, uint32_t pll1, uint32_t pll2, bool force_single, int refclk)
297 {
298         int M1, N1, M2 = 1, N2 = 1, log2P;
299
300         M1 = pll1 & 0xff;
301         N1 = (pll1 >> 8) & 0xff;
302         log2P = (pll1 >> 16) & 0x7; /* never more than 6, and nv30/35 only uses 3 bits */
303         if (pNv->twoStagePLL && pll2 & NV31_RAMDAC_ENABLE_VCO2 && !force_single) {
304                 M2 = pll2 & 0xff;
305                 N2 = (pll2 >> 8) & 0xff;
306         } else if (pNv->NVArch == 0x30 || pNv->NVArch == 0x35) {
307                 M1 &= 0xf; /* only 4 bits */
308                 if (pll1 & NV30_RAMDAC_ENABLE_VCO2) {
309                         M2 = (pll1 >> 4) & 0x7;
310                         N2 = ((pll2 >> 21) & 0x18) | ((pll2 >> 19) & 0x7);
311                 }
312         }
313
314         /* Avoid divide by zero if called at an inappropriate time */
315         if (!M1 || !M2)
316                 return 0;
317
318         return (N1 * N2 * refclk / (M1 * M2)) >> log2P;
319 }
320
321 static int nv_decode_pll_lowregs(uint32_t Pval, uint32_t NMNM, int refclk)
322 {
323         int M1, N1, M2 = 1, N2 = 1, log2P;
324
325         log2P = (Pval >> 16) & 0x7;
326
327         M1 = NMNM & 0xff;
328         N1 = (NMNM >> 8) & 0xff;
329         /* NVPLL and VPLLs use 1 << 8 to indicate single stage mode, MPLL uses 1 << 12 */
330         if (!(Pval & (1 << 8) || Pval & (1 << 12))) {
331                 M2 = (NMNM >> 16) & 0xff;
332                 N2 = (NMNM >> 24) & 0xff;
333         }
334
335         /* Avoid divide by zero if called at an inappropriate time */
336         if (!M1 || !M2)
337                 return 0;
338
339         return (N1 * N2 * refclk / (M1 * M2)) >> log2P;
340 }
341
342
343 static int nv_get_clock(NVPtr pNv, enum pll_types plltype)
344 {
345         const uint32_t nv04_regs[MAX_PLL_TYPES] = { NV_RAMDAC_NVPLL, NV_RAMDAC_MPLL, NV_RAMDAC_VPLL, NV_RAMDAC_VPLL2 };
346         const uint32_t nv40_regs[MAX_PLL_TYPES] = { 0x4000, 0x4020, NV_RAMDAC_VPLL, NV_RAMDAC_VPLL2 };
347         uint32_t reg1;
348         struct pll_lims pll_lim;
349
350         if (pNv->Architecture < NV_ARCH_40)
351                 reg1 = nv04_regs[plltype];
352         else
353                 reg1 = nv40_regs[plltype];
354
355         /* XXX no pScrn. CrystalFreqKHz is good enough for current nv_get_clock users though
356         if (!get_pll_limits(pScrn, plltype, &pll_lim))
357                 return 0;
358         */
359         pll_lim.refclk = pNv->CrystalFreqKHz;
360
361         if (reg1 <= 0x405c)
362                 return nv_decode_pll_lowregs(nvReadMC(pNv, reg1), nvReadMC(pNv, reg1 + 4), pll_lim.refclk);
363         if (pNv->twoStagePLL) {
364                 bool nv40_single = pNv->Architecture == 0x40 && ((plltype == VPLL1 && NVReadRAMDAC(pNv, 0, NV_RAMDAC_580) & NV_RAMDAC_580_VPLL1_ACTIVE) || (plltype == VPLL2 && NVReadRAMDAC(pNv, 0, NV_RAMDAC_580) & NV_RAMDAC_580_VPLL2_ACTIVE));
365
366                 return nv_decode_pll_highregs(pNv, nvReadMC(pNv, reg1), nvReadMC(pNv, reg1 + ((reg1 == NV_RAMDAC_VPLL2) ? 0x5c : 0x70)), nv40_single, pll_lim.refclk);
367         }
368         return nv_decode_pll_highregs(pNv, nvReadMC(pNv, reg1), 0, false, pll_lim.refclk);
369 }
370
371 /****************************************************************************\
372 *                                                                            *
373 * The video arbitration routines calculate some "magic" numbers.  Fixes      *
374 * the snow seen when accessing the framebuffer without it.                   *
375 * It just works (I hope).                                                    *
376 *                                                                            *
377 \****************************************************************************/
378
379 typedef struct {
380   int graphics_lwm;
381   int video_lwm;
382   int graphics_burst_size;
383   int video_burst_size;
384   int valid;
385 } nv4_fifo_info;
386
387 typedef struct {
388   int pclk_khz;
389   int mclk_khz;
390   int nvclk_khz;
391   char mem_page_miss;
392   char mem_latency;
393   int memory_width;
394   char enable_video;
395   char gr_during_vid;
396   char pix_bpp;
397   char mem_aligned;
398   char enable_mp;
399 } nv4_sim_state;
400
401 typedef struct {
402   int graphics_lwm;
403   int video_lwm;
404   int graphics_burst_size;
405   int video_burst_size;
406   int valid;
407 } nv10_fifo_info;
408
409 typedef struct {
410   uint32_t pclk_khz;
411   uint32_t mclk_khz;
412   uint32_t nvclk_khz;
413   uint8_t mem_page_miss;
414   uint8_t mem_latency;
415   uint32_t memory_type;
416   uint32_t memory_width;
417   uint8_t enable_video;
418   uint8_t gr_during_vid;
419   uint8_t pix_bpp;
420   uint8_t mem_aligned;
421   uint8_t enable_mp;
422 } nv10_sim_state;
423
424 static void nv4CalcArbitration (
425     nv4_fifo_info *fifo,
426     nv4_sim_state *arb
427 )
428 {
429     int data, pagemiss, cas,width, video_enable, bpp;
430     int nvclks, mclks, pclks, vpagemiss, crtpagemiss, vbs;
431     int found, mclk_extra, mclk_loop, cbs, m1, p1;
432     int mclk_freq, pclk_freq, nvclk_freq, mp_enable;
433     int us_m, us_n, us_p, video_drain_rate, crtc_drain_rate;
434     int vpm_us, us_video, vlwm, video_fill_us, cpm_us, us_crt,clwm;
435
436     fifo->valid = 1;
437     pclk_freq = arb->pclk_khz;
438     mclk_freq = arb->mclk_khz;
439     nvclk_freq = arb->nvclk_khz;
440     pagemiss = arb->mem_page_miss;
441     cas = arb->mem_latency;
442     width = arb->memory_width >> 6;
443     video_enable = arb->enable_video;
444     bpp = arb->pix_bpp;
445     mp_enable = arb->enable_mp;
446     clwm = 0;
447     vlwm = 0;
448     cbs = 128;
449     pclks = 2;
450     nvclks = 2;
451     nvclks += 2;
452     nvclks += 1;
453     mclks = 5;
454     mclks += 3;
455     mclks += 1;
456     mclks += cas;
457     mclks += 1;
458     mclks += 1;
459     mclks += 1;
460     mclks += 1;
461     mclk_extra = 3;
462     nvclks += 2;
463     nvclks += 1;
464     nvclks += 1;
465     nvclks += 1;
466     if (mp_enable)
467         mclks+=4;
468     nvclks += 0;
469     pclks += 0;
470     found = 0;
471     vbs = 0;
472     while (found != 1)
473     {
474         fifo->valid = 1;
475         found = 1;
476         mclk_loop = mclks+mclk_extra;
477         us_m = mclk_loop *1000*1000 / mclk_freq;
478         us_n = nvclks*1000*1000 / nvclk_freq;
479         us_p = nvclks*1000*1000 / pclk_freq;
480         if (video_enable)
481         {
482             video_drain_rate = pclk_freq * 2;
483             crtc_drain_rate = pclk_freq * bpp/8;
484             vpagemiss = 2;
485             vpagemiss += 1;
486             crtpagemiss = 2;
487             vpm_us = (vpagemiss * pagemiss)*1000*1000/mclk_freq;
488             if (nvclk_freq * 2 > mclk_freq * width)
489                 video_fill_us = cbs*1000*1000 / 16 / nvclk_freq ;
490             else
491                 video_fill_us = cbs*1000*1000 / (8 * width) / mclk_freq;
492             us_video = vpm_us + us_m + us_n + us_p + video_fill_us;
493             vlwm = us_video * video_drain_rate/(1000*1000);
494             vlwm++;
495             vbs = 128;
496             if (vlwm > 128) vbs = 64;
497             if (vlwm > (256-64)) vbs = 32;
498             if (nvclk_freq * 2 > mclk_freq * width)
499                 video_fill_us = vbs *1000*1000/ 16 / nvclk_freq ;
500             else
501                 video_fill_us = vbs*1000*1000 / (8 * width) / mclk_freq;
502             cpm_us = crtpagemiss  * pagemiss *1000*1000/ mclk_freq;
503             us_crt =
504             us_video
505             +video_fill_us
506             +cpm_us
507             +us_m + us_n +us_p
508             ;
509             clwm = us_crt * crtc_drain_rate/(1000*1000);
510             clwm++;
511         }
512         else
513         {
514             crtc_drain_rate = pclk_freq * bpp/8;
515             crtpagemiss = 2;
516             crtpagemiss += 1;
517             cpm_us = crtpagemiss  * pagemiss *1000*1000/ mclk_freq;
518             us_crt =  cpm_us + us_m + us_n + us_p ;
519             clwm = us_crt * crtc_drain_rate/(1000*1000);
520             clwm++;
521         }
522         m1 = clwm + cbs - 512;
523         p1 = m1 * pclk_freq / mclk_freq;
524         p1 = p1 * bpp / 8;
525         if ((p1 < m1) && (m1 > 0))
526         {
527             fifo->valid = 0;
528             found = 0;
529             if (mclk_extra ==0)   found = 1;
530             mclk_extra--;
531         }
532         else if (video_enable)
533         {
534             if ((clwm > 511) || (vlwm > 255))
535             {
536                 fifo->valid = 0;
537                 found = 0;
538                 if (mclk_extra ==0)   found = 1;
539                 mclk_extra--;
540             }
541         }
542         else
543         {
544             if (clwm > 519)
545             {
546                 fifo->valid = 0;
547                 found = 0;
548                 if (mclk_extra ==0)   found = 1;
549                 mclk_extra--;
550             }
551         }
552         if (clwm < 384) clwm = 384;
553         if (vlwm < 128) vlwm = 128;
554         data = (int)(clwm);
555         fifo->graphics_lwm = data;
556         fifo->graphics_burst_size = 128;
557         data = (int)((vlwm+15));
558         fifo->video_lwm = data;
559         fifo->video_burst_size = vbs;
560     }
561 }
562
563 void nv4UpdateArbitrationSettings (
564     unsigned      VClk, 
565     unsigned      pixelDepth, 
566     unsigned     *burst,
567     unsigned     *lwm,
568     NVPtr        pNv
569 )
570 {
571     nv4_fifo_info fifo_data;
572     nv4_sim_state sim_data;
573     unsigned int MClk, NVClk, cfg1;
574
575         MClk = nv_get_clock(pNv, MPLL);
576         NVClk = nv_get_clock(pNv, NVPLL);
577
578     cfg1 = nvReadFB(pNv, NV_PFB_CFG1);
579     sim_data.pix_bpp        = (char)pixelDepth;
580     sim_data.enable_video   = 0;
581     sim_data.enable_mp      = 0;
582     sim_data.memory_width   = (nvReadEXTDEV(pNv, NV_PEXTDEV_BOOT_0) & 0x10) ? 128 : 64;
583     sim_data.mem_latency    = (char)cfg1 & 0x0F;
584     sim_data.mem_aligned    = 1;
585     sim_data.mem_page_miss  = (char)(((cfg1 >> 4) &0x0F) + ((cfg1 >> 31) & 0x01));
586     sim_data.gr_during_vid  = 0;
587     sim_data.pclk_khz       = VClk;
588     sim_data.mclk_khz       = MClk;
589     sim_data.nvclk_khz      = NVClk;
590     nv4CalcArbitration(&fifo_data, &sim_data);
591     if (fifo_data.valid)
592     {
593         int  b = fifo_data.graphics_burst_size >> 4;
594         *burst = 0;
595         while (b >>= 1) (*burst)++;
596         *lwm   = fifo_data.graphics_lwm >> 3;
597     }
598 }
599
600 static void nv10CalcArbitration (
601     nv10_fifo_info *fifo,
602     nv10_sim_state *arb
603 )
604 {
605     int data, pagemiss, width, video_enable, bpp;
606     int nvclks, mclks, pclks, vpagemiss, crtpagemiss;
607     int nvclk_fill;
608     int found, mclk_extra, mclk_loop, cbs, m1;
609     int mclk_freq, pclk_freq, nvclk_freq, mp_enable;
610     int us_m, us_m_min, us_n, us_p, crtc_drain_rate;
611     int vus_m;
612     int vpm_us, us_video, cpm_us, us_crt,clwm;
613     int clwm_rnd_down;
614     int m2us, us_pipe_min, p1clk, p2;
615     int min_mclk_extra;
616     int us_min_mclk_extra;
617
618     fifo->valid = 1;
619     pclk_freq = arb->pclk_khz; /* freq in KHz */
620     mclk_freq = arb->mclk_khz;
621     nvclk_freq = arb->nvclk_khz;
622     pagemiss = arb->mem_page_miss;
623     width = arb->memory_width/64;
624     video_enable = arb->enable_video;
625     bpp = arb->pix_bpp;
626     mp_enable = arb->enable_mp;
627     clwm = 0;
628
629     cbs = 512;
630
631     pclks = 4; /* lwm detect. */
632
633     nvclks = 3; /* lwm -> sync. */
634     nvclks += 2; /* fbi bus cycles (1 req + 1 busy) */
635
636     mclks  = 1;   /* 2 edge sync.  may be very close to edge so just put one. */
637
638     mclks += 1;   /* arb_hp_req */
639     mclks += 5;   /* ap_hp_req   tiling pipeline */
640
641     mclks += 2;    /* tc_req     latency fifo */
642     mclks += 2;    /* fb_cas_n_  memory request to fbio block */
643     mclks += 7;    /* sm_d_rdv   data returned from fbio block */
644
645     /* fb.rd.d.Put_gc   need to accumulate 256 bits for read */
646     if (arb->memory_type == 0)
647       if (arb->memory_width == 64) /* 64 bit bus */
648         mclks += 4;
649       else
650         mclks += 2;
651     else
652       if (arb->memory_width == 64) /* 64 bit bus */
653         mclks += 2;
654       else
655         mclks += 1;
656
657     if ((!video_enable) && (arb->memory_width == 128))
658     {  
659       mclk_extra = (bpp == 32) ? 31 : 42; /* Margin of error */
660       min_mclk_extra = 17;
661     }
662     else
663     {
664       mclk_extra = (bpp == 32) ? 8 : 4; /* Margin of error */
665       /* mclk_extra = 4; */ /* Margin of error */
666       min_mclk_extra = 18;
667     }
668
669     nvclks += 1; /* 2 edge sync.  may be very close to edge so just put one. */
670     nvclks += 1; /* fbi_d_rdv_n */
671     nvclks += 1; /* Fbi_d_rdata */
672     nvclks += 1; /* crtfifo load */
673
674     if(mp_enable)
675       mclks+=4; /* Mp can get in with a burst of 8. */
676     /* Extra clocks determined by heuristics */
677
678     nvclks += 0;
679     pclks += 0;
680     found = 0;
681     while(found != 1) {
682       fifo->valid = 1;
683       found = 1;
684       mclk_loop = mclks+mclk_extra;
685       us_m = mclk_loop *1000*1000 / mclk_freq; /* Mclk latency in us */
686       us_m_min = mclks * 1000*1000 / mclk_freq; /* Minimum Mclk latency in us */
687       us_min_mclk_extra = min_mclk_extra *1000*1000 / mclk_freq;
688       us_n = nvclks*1000*1000 / nvclk_freq;/* nvclk latency in us */
689       us_p = pclks*1000*1000 / pclk_freq;/* nvclk latency in us */
690       us_pipe_min = us_m_min + us_n + us_p;
691
692       vus_m = mclk_loop *1000*1000 / mclk_freq; /* Mclk latency in us */
693
694       if(video_enable) {
695         crtc_drain_rate = pclk_freq * bpp/8; /* MB/s */
696
697         vpagemiss = 1; /* self generating page miss */
698         vpagemiss += 1; /* One higher priority before */
699
700         crtpagemiss = 2; /* self generating page miss */
701         if(mp_enable)
702             crtpagemiss += 1; /* if MA0 conflict */
703
704         vpm_us = (vpagemiss * pagemiss)*1000*1000/mclk_freq;
705
706         us_video = vpm_us + vus_m; /* Video has separate read return path */
707
708         cpm_us = crtpagemiss  * pagemiss *1000*1000/ mclk_freq;
709         us_crt =
710           us_video  /* Wait for video */
711           +cpm_us /* CRT Page miss */
712           +us_m + us_n +us_p /* other latency */
713           ;
714
715         clwm = us_crt * crtc_drain_rate/(1000*1000);
716         clwm++; /* fixed point <= float_point - 1.  Fixes that */
717       } else {
718         crtc_drain_rate = pclk_freq * bpp/8; /* bpp * pclk/8 */
719
720         crtpagemiss = 1; /* self generating page miss */
721         crtpagemiss += 1; /* MA0 page miss */
722         if(mp_enable)
723             crtpagemiss += 1; /* if MA0 conflict */
724         cpm_us = crtpagemiss  * pagemiss *1000*1000/ mclk_freq;
725         us_crt =  cpm_us + us_m + us_n + us_p ;
726         clwm = us_crt * crtc_drain_rate/(1000*1000);
727         clwm++; /* fixed point <= float_point - 1.  Fixes that */
728
729           /* Finally, a heuristic check when width == 64 bits */
730           if(width == 1){
731               nvclk_fill = nvclk_freq * 8;
732               if(crtc_drain_rate * 100 >= nvclk_fill * 102)
733                       clwm = 0xfff; /*Large number to fail */
734
735               else if(crtc_drain_rate * 100  >= nvclk_fill * 98) {
736                   clwm = 1024;
737                   cbs = 512;
738               }
739           }
740       }
741
742
743       /*
744         Overfill check:
745
746         */
747
748       clwm_rnd_down = ((int)clwm/8)*8;
749       if (clwm_rnd_down < clwm)
750           clwm += 8;
751
752       m1 = clwm + cbs -  1024; /* Amount of overfill */
753       m2us = us_pipe_min + us_min_mclk_extra;
754
755       /* pclk cycles to drain */
756       p1clk = m2us * pclk_freq/(1000*1000); 
757       p2 = p1clk * bpp / 8; /* bytes drained. */
758
759       if((p2 < m1) && (m1 > 0)) {
760           fifo->valid = 0;
761           found = 0;
762           if(min_mclk_extra == 0)   {
763             if(cbs <= 32) {
764               found = 1; /* Can't adjust anymore! */
765             } else {
766               cbs = cbs/2;  /* reduce the burst size */
767             }
768           } else {
769             min_mclk_extra--;
770           }
771       } else {
772         if (clwm > 1023){ /* Have some margin */
773           fifo->valid = 0;
774           found = 0;
775           if(min_mclk_extra == 0)   
776               found = 1; /* Can't adjust anymore! */
777           else 
778               min_mclk_extra--;
779         }
780       }
781
782       if(clwm < (1024-cbs+8)) clwm = 1024-cbs+8;
783       data = (int)(clwm);
784       /*  printf("CRT LWM: %f bytes, prog: 0x%x, bs: 256\n", clwm, data ); */
785       fifo->graphics_lwm = data;   fifo->graphics_burst_size = cbs;
786
787       fifo->video_lwm = 1024;  fifo->video_burst_size = 512;
788     }
789 }
790
791 void nv10UpdateArbitrationSettings (
792     unsigned      VClk, 
793     unsigned      pixelDepth, 
794     unsigned     *burst,
795     unsigned     *lwm,
796     NVPtr        pNv
797 )
798 {
799     nv10_fifo_info fifo_data;
800     nv10_sim_state sim_data;
801     unsigned int MClk, NVClk, cfg1;
802
803         MClk = nv_get_clock(pNv, MPLL);
804         NVClk = nv_get_clock(pNv, NVPLL);
805
806     cfg1 = nvReadFB(pNv, NV_PFB_CFG1);
807     sim_data.pix_bpp        = (char)pixelDepth;
808     sim_data.enable_video   = 1;
809     sim_data.enable_mp      = 0;
810     sim_data.memory_type    = (nvReadFB(pNv, NV_PFB_CFG0) & 0x01) ? 1 : 0;
811     sim_data.memory_width   = (nvReadEXTDEV(pNv, NV_PEXTDEV_BOOT_0) & 0x10) ? 128 : 64;
812     sim_data.mem_latency    = (char)cfg1 & 0x0F;
813     sim_data.mem_aligned    = 1;
814     sim_data.mem_page_miss  = (char)(((cfg1>>4) &0x0F) + ((cfg1>>31) & 0x01));
815     sim_data.gr_during_vid  = 0;
816     sim_data.pclk_khz       = VClk;
817     sim_data.mclk_khz       = MClk;
818     sim_data.nvclk_khz      = NVClk;
819     nv10CalcArbitration(&fifo_data, &sim_data);
820     if (fifo_data.valid) {
821         int  b = fifo_data.graphics_burst_size >> 4;
822         *burst = 0;
823         while (b >>= 1) (*burst)++;
824         *lwm   = fifo_data.graphics_lwm >> 3;
825     }
826 }
827
828
829 void nv30UpdateArbitrationSettings (NVPtr pNv,
830                                     unsigned     *burst,
831                                     unsigned     *lwm)   
832 {
833     unsigned int fifo_size, burst_size, graphics_lwm;
834
835     fifo_size = 2048;
836     burst_size = 512;
837     graphics_lwm = fifo_size - burst_size;
838
839     *burst = 0;
840     burst_size >>= 5;
841     while(burst_size >>= 1) (*burst)++;
842     *lwm = graphics_lwm >> 3;
843 }
844
845 #ifdef XSERVER_LIBPCIACCESS
846
847 struct pci_device GetDeviceByPCITAG(uint32_t bus, uint32_t dev, uint32_t func)
848 {
849         const struct pci_slot_match match[] = { {0, bus, dev, func, 0} };
850         struct pci_device_iterator *iterator;
851         struct pci_device *device;
852         
853         /* assume one device to exist */
854         iterator = pci_slot_match_iterator_create(match);
855         device = pci_device_next(iterator);
856
857         return *device;
858 }
859
860 #endif /* XSERVER_LIBPCIACCESS */
861
862 void nForceUpdateArbitrationSettings (unsigned VClk,
863                                       unsigned      pixelDepth,
864                                       unsigned     *burst,
865                                       unsigned     *lwm,
866                                       NVPtr        pNv
867 )
868 {
869     nv10_fifo_info fifo_data;
870     nv10_sim_state sim_data;
871     unsigned int MClk, NVClk, memctrl;
872
873 #ifdef XSERVER_LIBPCIACCESS
874         struct pci_device tmp;
875 #endif /* XSERVER_LIBPCIACCESS */
876
877     if((pNv->Chipset & 0x0FF0) == CHIPSET_NFORCE) {
878        unsigned int uMClkPostDiv;
879
880 #ifdef XSERVER_LIBPCIACCESS
881         tmp = GetDeviceByPCITAG(0, 0, 3);
882         PCI_DEV_READ_LONG(&tmp, 0x6C, &(uMClkPostDiv));
883         uMClkPostDiv = (uMClkPostDiv >> 8) & 0xf;
884 #else
885         uMClkPostDiv = (pciReadLong(pciTag(0, 0, 3), 0x6C) >> 8) & 0xf;
886 #endif /* XSERVER_LIBPCIACCESS */
887        if(!uMClkPostDiv) uMClkPostDiv = 4; 
888        MClk = 400000 / uMClkPostDiv;
889     } else {
890 #ifdef XSERVER_LIBPCIACCESS
891         tmp = GetDeviceByPCITAG(0, 0, 5);
892         PCI_DEV_READ_LONG(&tmp, 0x4C, &(MClk));
893         MClk /= 1000;
894 #else
895         MClk = pciReadLong(pciTag(0, 0, 5), 0x4C) / 1000;
896 #endif /* XSERVER_LIBPCIACCESS */
897     }
898
899         NVClk = nv_get_clock(pNv, NVPLL);
900     sim_data.pix_bpp        = (char)pixelDepth;
901     sim_data.enable_video   = 0;
902     sim_data.enable_mp      = 0;
903 #ifdef XSERVER_LIBPCIACCESS
904         tmp = GetDeviceByPCITAG(0, 0, 1);
905         PCI_DEV_READ_LONG(&tmp, 0x7C, &(sim_data.memory_type));
906         sim_data.memory_type = (sim_data.memory_type >> 12) & 1;
907 #else
908         sim_data.memory_type = (pciReadLong(pciTag(0, 0, 1), 0x7C) >> 12) & 1;
909 #endif /* XSERVER_LIBPCIACCESS */
910     sim_data.memory_width   = 64;
911
912 #ifdef XSERVER_LIBPCIACCESS
913         /* This offset is 0, is this even usefull? */
914         tmp = GetDeviceByPCITAG(0, 0, 3);
915         PCI_DEV_READ_LONG(&tmp, 0x00, &(memctrl));
916         memctrl >>= 16;
917 #else
918         memctrl = pciReadLong(pciTag(0, 0, 3), 0x00) >> 16;
919 #endif /* XSERVER_LIBPCIACCESS */
920
921     if((memctrl == 0x1A9) || (memctrl == 0x1AB) || (memctrl == 0x1ED)) {
922         uint32_t dimm[3];
923 #ifdef XSERVER_LIBPCIACCESS
924         tmp = GetDeviceByPCITAG(0, 0, 2);
925         PCI_DEV_READ_LONG(&tmp, 0x40, &(dimm[0]));
926         PCI_DEV_READ_LONG(&tmp, 0x44, &(dimm[1]));
927         PCI_DEV_READ_LONG(&tmp, 0x48, &(dimm[2]));
928         int i;
929         for (i = 0; i < 3; i++) {
930                 dimm[i] = (dimm[i] >> 8) & 0x4F;
931         }
932 #else
933         dimm[0] = (pciReadLong(pciTag(0, 0, 2), 0x40) >> 8) & 0x4F;
934         dimm[1] = (pciReadLong(pciTag(0, 0, 2), 0x44) >> 8) & 0x4F;
935         dimm[2] = (pciReadLong(pciTag(0, 0, 2), 0x48) >> 8) & 0x4F;
936 #endif
937
938         if((dimm[0] + dimm[1]) != dimm[2]) {
939              ErrorF("WARNING: "
940               "your nForce DIMMs are not arranged in optimal banks!\n");
941         } 
942     }
943
944     sim_data.mem_latency    = 3;
945     sim_data.mem_aligned    = 1;
946     sim_data.mem_page_miss  = 10;
947     sim_data.gr_during_vid  = 0;
948     sim_data.pclk_khz       = VClk;
949     sim_data.mclk_khz       = MClk;
950     sim_data.nvclk_khz      = NVClk;
951     nv10CalcArbitration(&fifo_data, &sim_data);
952     if (fifo_data.valid)
953     {
954         int  b = fifo_data.graphics_burst_size >> 4;
955         *burst = 0;
956         while (b >>= 1) (*burst)++;
957         *lwm   = fifo_data.graphics_lwm >> 3;
958     }
959 }
960
961
962 /****************************************************************************\
963 *                                                                            *
964 *                          RIVA Mode State Routines                          *
965 *                                                                            *
966 \****************************************************************************/
967
968 /*
969  * Calculate the Video Clock parameters for the PLL.
970  */
971 static void CalcVClock (
972     int           clockIn,
973     int          *clockOut,
974     CARD32         *pllOut,
975     NVPtr        pNv
976 )
977 {
978     unsigned lowM, highM;
979     unsigned DeltaNew, DeltaOld;
980     unsigned VClk, Freq;
981     unsigned M, N, P;
982     
983     DeltaOld = 0xFFFFFFFF;
984
985     VClk = (unsigned)clockIn;
986     
987     if (pNv->CrystalFreqKHz == 13500) {
988         lowM  = 7;
989         highM = 13;
990     } else {
991         lowM  = 8;
992         highM = 14;
993     }
994
995     for (P = 0; P <= 4; P++) {
996         Freq = VClk << P;
997         if ((Freq >= 128000) && (Freq <= 350000)) {
998             for (M = lowM; M <= highM; M++) {
999                 N = ((VClk << P) * M) / pNv->CrystalFreqKHz;
1000                 if(N <= 255) {
1001                     Freq = ((pNv->CrystalFreqKHz * N) / M) >> P;
1002                     if (Freq > VClk)
1003                         DeltaNew = Freq - VClk;
1004                     else
1005                         DeltaNew = VClk - Freq;
1006                     if (DeltaNew < DeltaOld) {
1007                         *pllOut   = (P << 16) | (N << 8) | M;
1008                         *clockOut = Freq;
1009                         DeltaOld  = DeltaNew;
1010                     }
1011                 }
1012             }
1013         }
1014     }
1015 }
1016
1017 static void CalcVClock2Stage (
1018     int           clockIn,
1019     int          *clockOut,
1020     CARD32         *pllOut,
1021     CARD32         *pllBOut,
1022     NVPtr        pNv
1023 )
1024 {
1025     unsigned DeltaNew, DeltaOld;
1026     unsigned VClk, Freq;
1027     unsigned M, N, P;
1028
1029     DeltaOld = 0xFFFFFFFF;
1030
1031     *pllBOut = 0x80000401;  /* fixed at x4 for now */
1032
1033     VClk = (unsigned)clockIn;
1034
1035     for (P = 0; P <= 6; P++) {
1036         Freq = VClk << P;
1037         if ((Freq >= 400000) && (Freq <= 1000000)) {
1038             for (M = 1; M <= 13; M++) {
1039                 N = ((VClk << P) * M) / (pNv->CrystalFreqKHz << 2);
1040                 if((N >= 5) && (N <= 255)) {
1041                     Freq = (((pNv->CrystalFreqKHz << 2) * N) / M) >> P;
1042                     if (Freq > VClk)
1043                         DeltaNew = Freq - VClk;
1044                     else
1045                         DeltaNew = VClk - Freq;
1046                     if (DeltaNew < DeltaOld) {
1047                         *pllOut   = (P << 16) | (N << 8) | M;
1048                         *clockOut = Freq;
1049                         DeltaOld  = DeltaNew;
1050                     }
1051                 }
1052             }
1053         }
1054     }
1055 }
1056
1057 /*
1058  * Calculate extended mode parameters (SVGA) and save in a 
1059  * mode state structure.
1060  */
1061 void NVCalcStateExt (
1062     NVPtr pNv,
1063     RIVA_HW_STATE *state,
1064     int            bpp,
1065     int            width,
1066     int            hDisplaySize,
1067     int            height,
1068     int            dotClock,
1069     int            flags 
1070 )
1071 {
1072     int pixelDepth, VClk = 0;
1073         CARD32 CursorStart;
1074
1075     /*
1076      * Save mode parameters.
1077      */
1078     state->bpp    = bpp;    /* this is not bitsPerPixel, it's 8,15,16,32 */
1079     state->width  = width;
1080     state->height = height;
1081     /*
1082      * Extended RIVA registers.
1083      */
1084     pixelDepth = (bpp + 1)/8;
1085     if(pNv->twoStagePLL)
1086         CalcVClock2Stage(dotClock, &VClk, &state->pll, &state->pllB, pNv);
1087     else
1088         CalcVClock(dotClock, &VClk, &state->pll, pNv);
1089
1090     switch (pNv->Architecture)
1091     {
1092         case NV_ARCH_04:
1093             nv4UpdateArbitrationSettings(VClk, 
1094                                          pixelDepth * 8, 
1095                                         &(state->arbitration0),
1096                                         &(state->arbitration1),
1097                                          pNv);
1098             state->cursor0  = 0x00;
1099             state->cursor1  = 0xbC;
1100             if (flags & V_DBLSCAN)
1101                 state->cursor1 |= 2;
1102             state->cursor2  = 0x00000000;
1103             state->pllsel   = 0x10000700;
1104             state->general  = bpp == 16 ? 0x00101100 : 0x00100100;
1105             state->repaint1 = hDisplaySize < 1280 ? 0x04 : 0x00;
1106             break;
1107         case NV_ARCH_10:
1108         case NV_ARCH_20:
1109         case NV_ARCH_30:
1110         default:
1111             if(((pNv->Chipset & 0xfff0) == CHIPSET_C51) ||
1112                ((pNv->Chipset & 0xfff0) == CHIPSET_C512))
1113             {
1114                 state->arbitration0 = 128; 
1115                 state->arbitration1 = 0x0480; 
1116             } else
1117             if(((pNv->Chipset & 0xffff) == CHIPSET_NFORCE) ||
1118                ((pNv->Chipset & 0xffff) == CHIPSET_NFORCE2))
1119             {
1120                 nForceUpdateArbitrationSettings(VClk,
1121                                           pixelDepth * 8,
1122                                          &(state->arbitration0),
1123                                          &(state->arbitration1),
1124                                           pNv);
1125             } else if(pNv->Architecture < NV_ARCH_30) {
1126                 nv10UpdateArbitrationSettings(VClk, 
1127                                           pixelDepth * 8, 
1128                                          &(state->arbitration0),
1129                                          &(state->arbitration1),
1130                                           pNv);
1131             } else {
1132                 nv30UpdateArbitrationSettings(pNv,
1133                                          &(state->arbitration0),
1134                                          &(state->arbitration1));
1135             }
1136             CursorStart = pNv->Cursor->offset;
1137             state->cursor0  = 0x80 | (CursorStart >> 17);
1138             state->cursor1  = (CursorStart >> 11) << 2;
1139             state->cursor2  = CursorStart >> 24;
1140             if (flags & V_DBLSCAN) 
1141                 state->cursor1 |= 2;
1142             state->pllsel   = 0x10000700;
1143             state->general  = bpp == 16 ? 0x00101100 : 0x00100100;
1144             state->repaint1 = hDisplaySize < 1280 ? 0x04 : 0x00;
1145             break;
1146     }
1147
1148     if(bpp != 8) /* DirectColor */
1149         state->general |= 0x00000030;
1150
1151     state->repaint0 = (((width / 8) * pixelDepth) & 0x700) >> 3;
1152     state->pixel    = (pixelDepth > 2) ? 3 : pixelDepth;
1153 }
1154
1155
1156 void NVLoadStateExt (
1157     ScrnInfoPtr pScrn,
1158     RIVA_HW_STATE *state
1159 )
1160 {
1161     NVPtr pNv = NVPTR(pScrn);
1162     CARD32 temp;
1163
1164     if(pNv->Architecture >= NV_ARCH_40) {
1165         switch(pNv->Chipset & 0xfff0) {
1166         case CHIPSET_NV44:
1167         case CHIPSET_NV44A:
1168         case CHIPSET_C51:
1169         case CHIPSET_G70:
1170         case CHIPSET_G71:
1171         case CHIPSET_G72:
1172         case CHIPSET_G73:
1173         case CHIPSET_C512:
1174              temp = nvReadCurRAMDAC(pNv, NV_RAMDAC_TEST_CONTROL);
1175              nvWriteCurRAMDAC(pNv, NV_RAMDAC_TEST_CONTROL, temp | 0x00100000);
1176              break;
1177         default:
1178              break;
1179         };
1180     }
1181
1182     if(pNv->Architecture >= NV_ARCH_10) {
1183         if(pNv->twoHeads) {
1184            NVWriteCRTC(pNv, 0, NV_CRTC_FSEL, state->head);
1185            NVWriteCRTC(pNv, 1, NV_CRTC_FSEL, state->head2);
1186         }
1187         temp = nvReadCurRAMDAC(pNv, NV_RAMDAC_NV10_CURSYNC);
1188         nvWriteCurRAMDAC(pNv, NV_RAMDAC_NV10_CURSYNC, temp | (1 << 25));
1189     
1190         nvWriteVIDEO(pNv, NV_PVIDEO_STOP, 1);
1191         nvWriteVIDEO(pNv, NV_PVIDEO_INTR_EN, 0);
1192         nvWriteVIDEO(pNv, NV_PVIDEO_OFFSET_BUFF(0), 0);
1193         nvWriteVIDEO(pNv, NV_PVIDEO_OFFSET_BUFF(1), 0);
1194         nvWriteVIDEO(pNv, NV_PVIDEO_LIMIT(0), pNv->VRAMPhysicalSize - 1);
1195         nvWriteVIDEO(pNv, NV_PVIDEO_LIMIT(1), pNv->VRAMPhysicalSize - 1);
1196         nvWriteVIDEO(pNv, NV_PVIDEO_UVPLANE_LIMIT(0), pNv->VRAMPhysicalSize - 1);
1197         nvWriteVIDEO(pNv, NV_PVIDEO_UVPLANE_LIMIT(1), pNv->VRAMPhysicalSize - 1);
1198         nvWriteMC(pNv, NV_PBUS_POWERCTRL_2, 0);
1199
1200         nvWriteCurCRTC(pNv, NV_CRTC_CURSOR_CONFIG, state->cursorConfig);
1201         nvWriteCurCRTC(pNv, NV_CRTC_0830, state->displayV - 3);
1202         nvWriteCurCRTC(pNv, NV_CRTC_0834, state->displayV - 1);
1203     
1204         if(pNv->FlatPanel) {
1205            if((pNv->Chipset & 0x0ff0) == CHIPSET_NV11) {
1206                nvWriteCurRAMDAC(pNv, NV_RAMDAC_DITHER_NV11, state->dither);
1207            } else 
1208            if(pNv->twoHeads) {
1209                nvWriteCurRAMDAC(pNv, NV_RAMDAC_FP_DITHER, state->dither);
1210            }
1211     
1212            nvWriteCurVGA(pNv, NV_VGA_CRTCX_FP_HTIMING, state->timingH);
1213            nvWriteCurVGA(pNv, NV_VGA_CRTCX_FP_VTIMING, state->timingV);
1214            nvWriteCurVGA(pNv, NV_VGA_CRTCX_BUFFER, 0xfa);
1215         }
1216
1217         nvWriteCurVGA(pNv, NV_VGA_CRTCX_EXTRA, state->extra);
1218     }
1219
1220     nvWriteCurVGA(pNv, NV_VGA_CRTCX_REPAINT0, state->repaint0);
1221     nvWriteCurVGA(pNv, NV_VGA_CRTCX_REPAINT1, state->repaint1);
1222     nvWriteCurVGA(pNv, NV_VGA_CRTCX_LSR, state->screen);
1223     nvWriteCurVGA(pNv, NV_VGA_CRTCX_PIXEL, state->pixel);
1224     nvWriteCurVGA(pNv, NV_VGA_CRTCX_HEB, state->horiz);
1225     nvWriteCurVGA(pNv, NV_VGA_CRTCX_FIFO1, state->fifo);
1226     nvWriteCurVGA(pNv, NV_VGA_CRTCX_FIFO0, state->arbitration0);
1227     nvWriteCurVGA(pNv, NV_VGA_CRTCX_FIFO_LWM, state->arbitration1);
1228     if(pNv->Architecture >= NV_ARCH_30) {
1229       nvWriteCurVGA(pNv, NV_VGA_CRTCX_FIFO_LWM_NV30, state->arbitration1 >> 8);
1230     }
1231
1232     nvWriteCurVGA(pNv, NV_VGA_CRTCX_CURCTL0, state->cursor0);
1233     nvWriteCurVGA(pNv, NV_VGA_CRTCX_CURCTL1, state->cursor1);
1234     if(pNv->Architecture == NV_ARCH_40) {  /* HW bug */
1235        volatile CARD32 curpos = nvReadCurRAMDAC(pNv, NV_RAMDAC_CURSOR_POS);
1236        nvWriteCurRAMDAC(pNv, NV_RAMDAC_CURSOR_POS, curpos);
1237     }
1238     nvWriteCurVGA(pNv, NV_VGA_CRTCX_CURCTL2, state->cursor2);
1239     nvWriteCurVGA(pNv, NV_VGA_CRTCX_INTERLACE, state->interlace);
1240
1241     if(!pNv->FlatPanel) {
1242        NVWriteRAMDAC(pNv, 0, NV_RAMDAC_PLL_SELECT, state->pllsel);
1243        NVWriteRAMDAC(pNv, 0, NV_RAMDAC_VPLL, state->vpll);
1244        if(pNv->twoHeads)
1245           NVWriteRAMDAC(pNv, 0, NV_RAMDAC_VPLL2, state->vpll2);
1246        if(pNv->twoStagePLL) {
1247           NVWriteRAMDAC(pNv, 0, NV_RAMDAC_VPLL_B, state->vpllB);
1248           NVWriteRAMDAC(pNv, 0, NV_RAMDAC_VPLL2_B, state->vpll2B);
1249        }
1250     } else {
1251        nvWriteCurRAMDAC(pNv, NV_RAMDAC_FP_CONTROL, state->scale);
1252        nvWriteCurRAMDAC(pNv, NV_RAMDAC_FP_HCRTC, state->crtcSync);
1253     }
1254     nvWriteCurRAMDAC(pNv, NV_RAMDAC_GENERAL_CONTROL, state->general);
1255
1256     nvWriteCurCRTC(pNv, NV_CRTC_INTR_EN_0, 0);
1257     nvWriteCurCRTC(pNv, NV_CRTC_INTR_0, NV_CRTC_INTR_VBLANK);
1258 }
1259
1260 void NVUnloadStateExt
1261 (
1262     NVPtr pNv,
1263     RIVA_HW_STATE *state
1264 )
1265 {
1266     state->repaint0     = nvReadCurVGA(pNv, NV_VGA_CRTCX_REPAINT0);
1267     state->repaint1     = nvReadCurVGA(pNv, NV_VGA_CRTCX_REPAINT1);
1268     state->screen       = nvReadCurVGA(pNv, NV_VGA_CRTCX_LSR);
1269     state->pixel        = nvReadCurVGA(pNv, NV_VGA_CRTCX_PIXEL);
1270     state->horiz        = nvReadCurVGA(pNv, NV_VGA_CRTCX_HEB);
1271     state->fifo         = nvReadCurVGA(pNv, NV_VGA_CRTCX_FIFO1);
1272     state->arbitration0 = nvReadCurVGA(pNv, NV_VGA_CRTCX_FIFO0);
1273     state->arbitration1 = nvReadCurVGA(pNv, NV_VGA_CRTCX_FIFO_LWM);
1274     if(pNv->Architecture >= NV_ARCH_30) {
1275        state->arbitration1 |= (nvReadCurVGA(pNv, NV_VGA_CRTCX_FIFO_LWM_NV30) & 1) << 8;
1276     }
1277     state->cursor0      = nvReadCurVGA(pNv, NV_VGA_CRTCX_CURCTL0);
1278     state->cursor1      = nvReadCurVGA(pNv, NV_VGA_CRTCX_CURCTL1);
1279     state->cursor2      = nvReadCurVGA(pNv, NV_VGA_CRTCX_CURCTL2);
1280     state->interlace    = nvReadCurVGA(pNv, NV_VGA_CRTCX_INTERLACE);
1281
1282     state->vpll         = NVReadRAMDAC(pNv, 0, NV_RAMDAC_VPLL);
1283     if(pNv->twoHeads)
1284        state->vpll2     = NVReadRAMDAC(pNv, 0, NV_RAMDAC_VPLL2);
1285     if(pNv->twoStagePLL) {
1286         state->vpllB    = NVReadRAMDAC(pNv, 0, NV_RAMDAC_VPLL_B);
1287         state->vpll2B   = NVReadRAMDAC(pNv, 0, NV_RAMDAC_VPLL2_B);
1288     }
1289     state->pllsel       = NVReadRAMDAC(pNv, 0, NV_RAMDAC_PLL_SELECT);
1290     state->general      = nvReadCurRAMDAC(pNv, NV_RAMDAC_GENERAL_CONTROL);
1291     state->scale        = nvReadCurRAMDAC(pNv, NV_RAMDAC_FP_CONTROL);
1292
1293     if(pNv->Architecture >= NV_ARCH_10) {
1294         if(pNv->twoHeads) {
1295            state->head     = NVReadCRTC(pNv, 0, NV_CRTC_FSEL);
1296            state->head2    = NVReadCRTC(pNv, 1, NV_CRTC_FSEL);
1297            state->crtcOwner = nvReadCurVGA(pNv, NV_VGA_CRTCX_OWNER);
1298         }
1299         state->extra = nvReadCurVGA(pNv, NV_VGA_CRTCX_EXTRA);
1300
1301         state->cursorConfig = nvReadCurCRTC(pNv, NV_CRTC_CURSOR_CONFIG);
1302
1303         if((pNv->Chipset & 0x0ff0) == CHIPSET_NV11) {
1304            state->dither = nvReadCurRAMDAC(pNv, NV_RAMDAC_DITHER_NV11);
1305         } else 
1306         if(pNv->twoHeads) {
1307             state->dither = nvReadCurRAMDAC(pNv, NV_RAMDAC_FP_DITHER);
1308         }
1309
1310         if(pNv->FlatPanel) {
1311            state->timingH = nvReadCurVGA(pNv, NV_VGA_CRTCX_FP_HTIMING);
1312            state->timingV = nvReadCurVGA(pNv, NV_VGA_CRTCX_FP_VTIMING);
1313         }
1314     }
1315
1316     if(pNv->FlatPanel) {
1317        state->crtcSync = nvReadCurRAMDAC(pNv, NV_RAMDAC_FP_HCRTC);
1318     }
1319 }
1320
1321 void NVSetStartAddress (
1322     NVPtr   pNv,
1323     CARD32 start
1324 )
1325 {
1326     nvWriteCurCRTC(pNv, NV_CRTC_START, start);
1327 }
1328
1329 uint32_t nv_pitch_align(NVPtr pNv, uint32_t width, int bpp)
1330 {
1331         int mask;
1332
1333         if (bpp == 15)
1334                 bpp = 16;
1335         if (bpp == 24)
1336                 bpp = 8;
1337
1338         /* Alignment requirements taken from the Haiku driver */
1339         if (pNv->Architecture == NV_ARCH_04 || pNv->NoAccel) /* CRTC only case */
1340                 /* Apparently a hardware bug on some hardware makes this 128 instead of 64 */
1341                 mask = 128 / bpp - 1;
1342         else /* Accel case */
1343                 mask = 512 / bpp - 1;
1344
1345         return (width + mask) & ~mask;
1346 }
1347
1348 #define VGA_SEQ_PLANE_WRITE     0x02
1349 #define VGA_SEQ_MEMORY_MODE     0x04
1350 #define VGA_GFX_PLANE_READ      0x04
1351 #define VGA_GFX_MODE            0x05
1352 #define VGA_GFX_MISC            0x06
1353
1354 void nv_save_restore_vga_fonts(ScrnInfoPtr pScrn, bool save)
1355 {
1356         NVPtr pNv = NVPTR(pScrn);
1357         bool graphicsmode;
1358         uint8_t misc, gr4, gr5, gr6, seq2, seq4;
1359         int i;
1360
1361         NVSetEnablePalette(pNv, 0, true);
1362         graphicsmode = NVReadVgaAttr(pNv, 0, 0x10) & 1;
1363         NVSetEnablePalette(pNv, 0, false);
1364
1365         if (graphicsmode)       /* graphics mode => framebuffer => no need to save */
1366                 return;
1367
1368         xf86DrvMsg(pScrn->scrnIndex, X_INFO, "%sing VGA fonts\n", save ? "Sav" : "Restor");
1369         if (pNv->twoHeads)
1370                 NVBlankScreen(pScrn, 1, true);
1371         NVBlankScreen(pScrn, 0, true);
1372
1373         /* save control regs */
1374         misc = NVReadPVIO(pNv, 0, VGA_MISC_OUT_R);
1375         seq2 = NVReadVgaSeq(pNv, 0, VGA_SEQ_PLANE_WRITE);
1376         seq4 = NVReadVgaSeq(pNv, 0, VGA_SEQ_MEMORY_MODE);
1377         gr4 = NVReadVgaGr(pNv, 0, VGA_GFX_PLANE_READ);
1378         gr5 = NVReadVgaGr(pNv, 0, VGA_GFX_MODE);
1379         gr6 = NVReadVgaGr(pNv, 0, VGA_GFX_MISC);
1380
1381         NVWritePVIO(pNv, 0, VGA_MISC_OUT_W, 0x67);
1382         NVWriteVgaSeq(pNv, 0, VGA_SEQ_MEMORY_MODE, 0x6);
1383         NVWriteVgaGr(pNv, 0, VGA_GFX_MODE, 0x0);
1384         NVWriteVgaGr(pNv, 0, VGA_GFX_MISC, 0x5);
1385
1386         /* store font in plane 0 */
1387         NVWriteVgaSeq(pNv, 0, VGA_SEQ_PLANE_WRITE, 0x1);
1388         NVWriteVgaGr(pNv, 0, VGA_GFX_PLANE_READ, 0x0);
1389         for (i = 0; i < 16384; i++)
1390                 if (save)
1391                         pNv->saved_vga_font[0][i] = MMIO_IN32(pNv->FB_BAR, i * 4);
1392                 else
1393                         MMIO_OUT32(pNv->FB_BAR, i * 4, pNv->saved_vga_font[0][i]);
1394
1395         /* store font in plane 1 */
1396         NVWriteVgaSeq(pNv, 0, VGA_SEQ_PLANE_WRITE, 0x2);
1397         NVWriteVgaGr(pNv, 0, VGA_GFX_PLANE_READ, 0x1);
1398         for (i = 0; i < 16384; i++)
1399                 if (save)
1400                         pNv->saved_vga_font[1][i] = MMIO_IN32(pNv->FB_BAR, i * 4);
1401                 else
1402                         MMIO_OUT32(pNv->FB_BAR, i * 4, pNv->saved_vga_font[1][i]);
1403
1404         /* store font in plane 2 */
1405         NVWriteVgaSeq(pNv, 0, VGA_SEQ_PLANE_WRITE, 0x4);
1406         NVWriteVgaGr(pNv, 0, VGA_GFX_PLANE_READ, 0x2);
1407         for (i = 0; i < 16384; i++)
1408                 if (save)
1409                         pNv->saved_vga_font[2][i] = MMIO_IN32(pNv->FB_BAR, i * 4);
1410                 else
1411                         MMIO_OUT32(pNv->FB_BAR, i * 4, pNv->saved_vga_font[2][i]);
1412
1413         /* store font in plane 3 */
1414         NVWriteVgaSeq(pNv, 0, VGA_SEQ_PLANE_WRITE, 0x8);
1415         NVWriteVgaGr(pNv, 0, VGA_GFX_PLANE_READ, 0x3);
1416         for (i = 0; i < 16384; i++)
1417                 if (save)
1418                         pNv->saved_vga_font[3][i] = MMIO_IN32(pNv->FB_BAR, i * 4);
1419                 else
1420                         MMIO_OUT32(pNv->FB_BAR, i * 4, pNv->saved_vga_font[3][i]);
1421
1422         /* restore control regs */
1423         NVWritePVIO(pNv, 0, VGA_MISC_OUT_W, misc);
1424         NVWriteVgaGr(pNv, 0, VGA_GFX_PLANE_READ, gr4);
1425         NVWriteVgaGr(pNv, 0, VGA_GFX_MODE, gr5);
1426         NVWriteVgaGr(pNv, 0, VGA_GFX_MISC, gr6);
1427         NVWriteVgaSeq(pNv, 0, VGA_SEQ_PLANE_WRITE, seq2);
1428         NVWriteVgaSeq(pNv, 0, VGA_SEQ_MEMORY_MODE, seq4);
1429
1430         if (pNv->twoHeads)
1431                 NVBlankScreen(pScrn, 1, false);
1432         NVBlankScreen(pScrn, 0, false);
1433 }