1 /*
2 * Copyright (c) 1993-2003 NVIDIA, Corporation
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the
6 * "Software"), to deal in the Software without restriction, including
7 * without limitation the rights to use, copy, modify, merge, publish,
8 * distribute, sublicense, and/or sell copies of the Software, and to
9 * permit persons to whom the Software is furnished to do so, subject to
10 * the following conditions:
11 *
12 * The above copyright notice and this permission notice shall be included
13 * in all copies or substantial portions of the Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
16 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
18 * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
19 * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
20 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
21 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22 */
23
24 #ifdef HAVE_CONFIG_H
25 #include "config.h"
26 #endif
27
28 #include "nv_local.h"
29 #include "compiler.h"
30 #include "nv_include.h"
31
32
NVLockUnlock(NVPtr pNv,Bool Lock)33 void NVLockUnlock (
34 NVPtr pNv,
35 Bool Lock
36 )
37 {
38 CARD8 cr11;
39
40 VGA_WR08(pNv->PCIO, 0x3D4, 0x1F);
41 VGA_WR08(pNv->PCIO, 0x3D5, Lock ? 0x99 : 0x57);
42
43 VGA_WR08(pNv->PCIO, 0x3D4, 0x11);
44 cr11 = VGA_RD08(pNv->PCIO, 0x3D5);
45 if(Lock) cr11 |= 0x80;
46 else cr11 &= ~0x80;
47 VGA_WR08(pNv->PCIO, 0x3D5, cr11);
48 }
49
NVShowHideCursor(NVPtr pNv,int ShowHide)50 int NVShowHideCursor (
51 NVPtr pNv,
52 int ShowHide
53 )
54 {
55 int current = pNv->CurrentState->cursor1;
56
57 pNv->CurrentState->cursor1 = (pNv->CurrentState->cursor1 & 0xFE) |
58 (ShowHide & 0x01);
59 VGA_WR08(pNv->PCIO, 0x3D4, 0x31);
60 VGA_WR08(pNv->PCIO, 0x3D5, pNv->CurrentState->cursor1);
61
62 if(pNv->Architecture == NV_ARCH_40) { /* HW bug */
63 volatile CARD32 curpos = pNv->PRAMDAC[0x0300/4];
64 pNv->PRAMDAC[0x0300/4] = curpos;
65 }
66
67 return (current & 0x01);
68 }
69
70 /****************************************************************************\
71 * *
72 * The video arbitration routines calculate some "magic" numbers. Fixes *
73 * the snow seen when accessing the framebuffer without it. *
74 * It just works (I hope). *
75 * *
76 \****************************************************************************/
77
78 typedef struct {
79 int graphics_lwm;
80 int video_lwm;
81 int graphics_burst_size;
82 int video_burst_size;
83 int valid;
84 } nv4_fifo_info;
85
86 typedef struct {
87 int pclk_khz;
88 int mclk_khz;
89 int nvclk_khz;
90 char mem_page_miss;
91 char mem_latency;
92 int memory_width;
93 char enable_video;
94 char gr_during_vid;
95 char pix_bpp;
96 char mem_aligned;
97 char enable_mp;
98 } nv4_sim_state;
99
100 typedef struct {
101 int graphics_lwm;
102 int video_lwm;
103 int graphics_burst_size;
104 int video_burst_size;
105 int valid;
106 } nv10_fifo_info;
107
108 typedef struct {
109 int pclk_khz;
110 int mclk_khz;
111 int nvclk_khz;
112 char mem_page_miss;
113 char mem_latency;
114 int memory_type;
115 int memory_width;
116 char enable_video;
117 char gr_during_vid;
118 char pix_bpp;
119 char mem_aligned;
120 char enable_mp;
121 } nv10_sim_state;
122
123
nvGetClocks(NVPtr pNv,unsigned int * MClk,unsigned int * NVClk)124 static void nvGetClocks(NVPtr pNv, unsigned int *MClk, unsigned int *NVClk)
125 {
126 unsigned int pll, N, M, MB, NB, P;
127
128 if(pNv->Architecture >= NV_ARCH_40) {
129 pll = pNv->PMC[0x4020/4];
130 P = (pll >> 16) & 0x07;
131 pll = pNv->PMC[0x4024/4];
132 M = pll & 0xFF;
133 N = (pll >> 8) & 0xFF;
134 if(((pNv->Chipset & 0xfff0) == 0x0290) ||
135 ((pNv->Chipset & 0xfff0) == 0x0390))
136 {
137 MB = 1;
138 NB = 1;
139 } else {
140 MB = (pll >> 16) & 0xFF;
141 NB = (pll >> 24) & 0xFF;
142 }
143 *MClk = ((N * NB * pNv->CrystalFreqKHz) / (M * MB)) >> P;
144
145 pll = pNv->PMC[0x4000/4];
146 P = (pll >> 16) & 0x07;
147 pll = pNv->PMC[0x4004/4];
148 M = pll & 0xFF;
149 N = (pll >> 8) & 0xFF;
150 MB = (pll >> 16) & 0xFF;
151 NB = (pll >> 24) & 0xFF;
152
153 *NVClk = ((N * NB * pNv->CrystalFreqKHz) / (M * MB)) >> P;
154 } else
155 if(pNv->twoStagePLL) {
156 pll = pNv->PRAMDAC0[0x0504/4];
157 M = pll & 0xFF;
158 N = (pll >> 8) & 0xFF;
159 P = (pll >> 16) & 0x0F;
160 pll = pNv->PRAMDAC0[0x0574/4];
161 if(pll & 0x80000000) {
162 MB = pll & 0xFF;
163 NB = (pll >> 8) & 0xFF;
164 } else {
165 MB = 1;
166 NB = 1;
167 }
168 *MClk = ((N * NB * pNv->CrystalFreqKHz) / (M * MB)) >> P;
169
170 pll = pNv->PRAMDAC0[0x0500/4];
171 M = pll & 0xFF;
172 N = (pll >> 8) & 0xFF;
173 P = (pll >> 16) & 0x0F;
174 pll = pNv->PRAMDAC0[0x0570/4];
175 if(pll & 0x80000000) {
176 MB = pll & 0xFF;
177 NB = (pll >> 8) & 0xFF;
178 } else {
179 MB = 1;
180 NB = 1;
181 }
182 *NVClk = ((N * NB * pNv->CrystalFreqKHz) / (M * MB)) >> P;
183 } else
184 if(((pNv->Chipset & 0x0ff0) == 0x0300) ||
185 ((pNv->Chipset & 0x0ff0) == 0x0330))
186 {
187 pll = pNv->PRAMDAC0[0x0504/4];
188 M = pll & 0x0F;
189 N = (pll >> 8) & 0xFF;
190 P = (pll >> 16) & 0x07;
191 if(pll & 0x00000080) {
192 MB = (pll >> 4) & 0x07;
193 NB = (pll >> 19) & 0x1f;
194 } else {
195 MB = 1;
196 NB = 1;
197 }
198 *MClk = ((N * NB * pNv->CrystalFreqKHz) / (M * MB)) >> P;
199
200 pll = pNv->PRAMDAC0[0x0500/4];
201 M = pll & 0x0F;
202 N = (pll >> 8) & 0xFF;
203 P = (pll >> 16) & 0x07;
204 if(pll & 0x00000080) {
205 MB = (pll >> 4) & 0x07;
206 NB = (pll >> 19) & 0x1f;
207 } else {
208 MB = 1;
209 NB = 1;
210 }
211 *NVClk = ((N * NB * pNv->CrystalFreqKHz) / (M * MB)) >> P;
212 } else {
213 pll = pNv->PRAMDAC0[0x0504/4];
214 M = pll & 0xFF;
215 N = (pll >> 8) & 0xFF;
216 P = (pll >> 16) & 0x0F;
217 *MClk = (N * pNv->CrystalFreqKHz / M) >> P;
218
219 pll = pNv->PRAMDAC0[0x0500/4];
220 M = pll & 0xFF;
221 N = (pll >> 8) & 0xFF;
222 P = (pll >> 16) & 0x0F;
223 *NVClk = (N * pNv->CrystalFreqKHz / M) >> P;
224 }
225
226 #if 0
227 ErrorF("NVClock = %i MHz, MEMClock = %i MHz\n", *NVClk/1000, *MClk/1000);
228 #endif
229 }
230
231
nv4CalcArbitration(nv4_fifo_info * fifo,nv4_sim_state * arb)232 static void nv4CalcArbitration (
233 nv4_fifo_info *fifo,
234 nv4_sim_state *arb
235 )
236 {
237 int data, pagemiss, cas,width, video_enable, bpp;
238 int nvclks, mclks, pclks, vpagemiss, crtpagemiss, vbs;
239 int found, mclk_extra, mclk_loop, cbs, m1, p1;
240 int mclk_freq, pclk_freq, nvclk_freq, mp_enable;
241 int us_m, us_n, us_p, video_drain_rate, crtc_drain_rate;
242 int vpm_us, us_video, vlwm, video_fill_us, cpm_us, us_crt,clwm;
243
244 fifo->valid = 1;
245 pclk_freq = arb->pclk_khz;
246 mclk_freq = arb->mclk_khz;
247 nvclk_freq = arb->nvclk_khz;
248 pagemiss = arb->mem_page_miss;
249 cas = arb->mem_latency;
250 width = arb->memory_width >> 6;
251 video_enable = arb->enable_video;
252 bpp = arb->pix_bpp;
253 mp_enable = arb->enable_mp;
254 clwm = 0;
255 vlwm = 0;
256 cbs = 128;
257 pclks = 2;
258 nvclks = 2;
259 nvclks += 2;
260 nvclks += 1;
261 mclks = 5;
262 mclks += 3;
263 mclks += 1;
264 mclks += cas;
265 mclks += 1;
266 mclks += 1;
267 mclks += 1;
268 mclks += 1;
269 mclk_extra = 3;
270 nvclks += 2;
271 nvclks += 1;
272 nvclks += 1;
273 nvclks += 1;
274 if (mp_enable)
275 mclks+=4;
276 nvclks += 0;
277 pclks += 0;
278 found = 0;
279 vbs = 0;
280 while (found != 1)
281 {
282 fifo->valid = 1;
283 found = 1;
284 mclk_loop = mclks+mclk_extra;
285 us_m = mclk_loop *1000*1000 / mclk_freq;
286 us_n = nvclks*1000*1000 / nvclk_freq;
287 us_p = nvclks*1000*1000 / pclk_freq;
288 if (video_enable)
289 {
290 video_drain_rate = pclk_freq * 2;
291 crtc_drain_rate = pclk_freq * bpp/8;
292 vpagemiss = 2;
293 vpagemiss += 1;
294 crtpagemiss = 2;
295 vpm_us = (vpagemiss * pagemiss)*1000*1000/mclk_freq;
296 if (nvclk_freq * 2 > mclk_freq * width)
297 video_fill_us = cbs*1000*1000 / 16 / nvclk_freq ;
298 else
299 video_fill_us = cbs*1000*1000 / (8 * width) / mclk_freq;
300 us_video = vpm_us + us_m + us_n + us_p + video_fill_us;
301 vlwm = us_video * video_drain_rate/(1000*1000);
302 vlwm++;
303 vbs = 128;
304 if (vlwm > 128) vbs = 64;
305 if (vlwm > (256-64)) vbs = 32;
306 if (nvclk_freq * 2 > mclk_freq * width)
307 video_fill_us = vbs *1000*1000/ 16 / nvclk_freq ;
308 else
309 video_fill_us = vbs*1000*1000 / (8 * width) / mclk_freq;
310 cpm_us = crtpagemiss * pagemiss *1000*1000/ mclk_freq;
311 us_crt =
312 us_video
313 +video_fill_us
314 +cpm_us
315 +us_m + us_n +us_p
316 ;
317 clwm = us_crt * crtc_drain_rate/(1000*1000);
318 clwm++;
319 }
320 else
321 {
322 crtc_drain_rate = pclk_freq * bpp/8;
323 crtpagemiss = 2;
324 crtpagemiss += 1;
325 cpm_us = crtpagemiss * pagemiss *1000*1000/ mclk_freq;
326 us_crt = cpm_us + us_m + us_n + us_p ;
327 clwm = us_crt * crtc_drain_rate/(1000*1000);
328 clwm++;
329 }
330 m1 = clwm + cbs - 512;
331 p1 = m1 * pclk_freq / mclk_freq;
332 p1 = p1 * bpp / 8;
333 if ((p1 < m1) && (m1 > 0))
334 {
335 fifo->valid = 0;
336 found = 0;
337 if (mclk_extra ==0) found = 1;
338 mclk_extra--;
339 }
340 else if (video_enable)
341 {
342 if ((clwm > 511) || (vlwm > 255))
343 {
344 fifo->valid = 0;
345 found = 0;
346 if (mclk_extra ==0) found = 1;
347 mclk_extra--;
348 }
349 }
350 else
351 {
352 if (clwm > 519)
353 {
354 fifo->valid = 0;
355 found = 0;
356 if (mclk_extra ==0) found = 1;
357 mclk_extra--;
358 }
359 }
360 if (clwm < 384) clwm = 384;
361 if (vlwm < 128) vlwm = 128;
362 data = (int)(clwm);
363 fifo->graphics_lwm = data;
364 fifo->graphics_burst_size = 128;
365 data = (int)((vlwm+15));
366 fifo->video_lwm = data;
367 fifo->video_burst_size = vbs;
368 }
369 }
370
nv4UpdateArbitrationSettings(unsigned VClk,unsigned pixelDepth,unsigned * burst,unsigned * lwm,NVPtr pNv)371 static void nv4UpdateArbitrationSettings (
372 unsigned VClk,
373 unsigned pixelDepth,
374 unsigned *burst,
375 unsigned *lwm,
376 NVPtr pNv
377 )
378 {
379 nv4_fifo_info fifo_data;
380 nv4_sim_state sim_data;
381 unsigned int MClk, NVClk, cfg1;
382
383 nvGetClocks(pNv, &MClk, &NVClk);
384
385 cfg1 = pNv->PFB[0x00000204/4];
386 sim_data.pix_bpp = (char)pixelDepth;
387 sim_data.enable_video = 0;
388 sim_data.enable_mp = 0;
389 sim_data.memory_width = (pNv->PEXTDEV[0x0000/4] & 0x10) ? 128 : 64;
390 sim_data.mem_latency = (char)cfg1 & 0x0F;
391 sim_data.mem_aligned = 1;
392 sim_data.mem_page_miss = (char)(((cfg1 >> 4) &0x0F) + ((cfg1 >> 31) & 0x01));
393 sim_data.gr_during_vid = 0;
394 sim_data.pclk_khz = VClk;
395 sim_data.mclk_khz = MClk;
396 sim_data.nvclk_khz = NVClk;
397 nv4CalcArbitration(&fifo_data, &sim_data);
398 if (fifo_data.valid)
399 {
400 int b = fifo_data.graphics_burst_size >> 4;
401 *burst = 0;
402 while (b >>= 1) (*burst)++;
403 *lwm = fifo_data.graphics_lwm >> 3;
404 }
405 }
406
nv10CalcArbitration(nv10_fifo_info * fifo,nv10_sim_state * arb)407 static void nv10CalcArbitration (
408 nv10_fifo_info *fifo,
409 nv10_sim_state *arb
410 )
411 {
412 int data, pagemiss, width, video_enable, bpp;
413 int nvclks, mclks, pclks, vpagemiss, crtpagemiss;
414 int nvclk_fill;
415 int found, mclk_extra, mclk_loop, cbs, m1;
416 int mclk_freq, pclk_freq, nvclk_freq, mp_enable;
417 int us_m, us_m_min, us_n, us_p, crtc_drain_rate;
418 int vus_m;
419 int vpm_us, us_video, cpm_us, us_crt,clwm;
420 int clwm_rnd_down;
421 int m2us, us_pipe_min, p1clk, p2;
422 int min_mclk_extra;
423 int us_min_mclk_extra;
424
425 fifo->valid = 1;
426 pclk_freq = arb->pclk_khz; /* freq in KHz */
427 mclk_freq = arb->mclk_khz;
428 nvclk_freq = arb->nvclk_khz;
429 pagemiss = arb->mem_page_miss;
430 width = arb->memory_width/64;
431 video_enable = arb->enable_video;
432 bpp = arb->pix_bpp;
433 mp_enable = arb->enable_mp;
434 clwm = 0;
435
436 cbs = 512;
437
438 pclks = 4; /* lwm detect. */
439
440 nvclks = 3; /* lwm -> sync. */
441 nvclks += 2; /* fbi bus cycles (1 req + 1 busy) */
442
443 mclks = 1; /* 2 edge sync. may be very close to edge so just put one. */
444
445 mclks += 1; /* arb_hp_req */
446 mclks += 5; /* ap_hp_req tiling pipeline */
447
448 mclks += 2; /* tc_req latency fifo */
449 mclks += 2; /* fb_cas_n_ memory request to fbio block */
450 mclks += 7; /* sm_d_rdv data returned from fbio block */
451
452 /* fb.rd.d.Put_gc need to accumulate 256 bits for read */
453 if (arb->memory_type == 0)
454 if (arb->memory_width == 64) /* 64 bit bus */
455 mclks += 4;
456 else
457 mclks += 2;
458 else
459 if (arb->memory_width == 64) /* 64 bit bus */
460 mclks += 2;
461 else
462 mclks += 1;
463
464 if ((!video_enable) && (arb->memory_width == 128))
465 {
466 mclk_extra = (bpp == 32) ? 31 : 42; /* Margin of error */
467 min_mclk_extra = 17;
468 }
469 else
470 {
471 mclk_extra = (bpp == 32) ? 8 : 4; /* Margin of error */
472 /* mclk_extra = 4; */ /* Margin of error */
473 min_mclk_extra = 18;
474 }
475
476 nvclks += 1; /* 2 edge sync. may be very close to edge so just put one. */
477 nvclks += 1; /* fbi_d_rdv_n */
478 nvclks += 1; /* Fbi_d_rdata */
479 nvclks += 1; /* crtfifo load */
480
481 if(mp_enable)
482 mclks+=4; /* Mp can get in with a burst of 8. */
483 /* Extra clocks determined by heuristics */
484
485 nvclks += 0;
486 pclks += 0;
487 found = 0;
488 while(found != 1) {
489 fifo->valid = 1;
490 found = 1;
491 mclk_loop = mclks+mclk_extra;
492 us_m = mclk_loop *1000*1000 / mclk_freq; /* Mclk latency in us */
493 us_m_min = mclks * 1000*1000 / mclk_freq; /* Minimum Mclk latency in us */
494 us_min_mclk_extra = min_mclk_extra *1000*1000 / mclk_freq;
495 us_n = nvclks*1000*1000 / nvclk_freq;/* nvclk latency in us */
496 us_p = pclks*1000*1000 / pclk_freq;/* nvclk latency in us */
497 us_pipe_min = us_m_min + us_n + us_p;
498
499 vus_m = mclk_loop *1000*1000 / mclk_freq; /* Mclk latency in us */
500
501 if(video_enable) {
502 crtc_drain_rate = pclk_freq * bpp/8; /* MB/s */
503
504 vpagemiss = 1; /* self generating page miss */
505 vpagemiss += 1; /* One higher priority before */
506
507 crtpagemiss = 2; /* self generating page miss */
508 if(mp_enable)
509 crtpagemiss += 1; /* if MA0 conflict */
510
511 vpm_us = (vpagemiss * pagemiss)*1000*1000/mclk_freq;
512
513 us_video = vpm_us + vus_m; /* Video has separate read return path */
514
515 cpm_us = crtpagemiss * pagemiss *1000*1000/ mclk_freq;
516 us_crt =
517 us_video /* Wait for video */
518 +cpm_us /* CRT Page miss */
519 +us_m + us_n +us_p /* other latency */
520 ;
521
522 clwm = us_crt * crtc_drain_rate/(1000*1000);
523 clwm++; /* fixed point <= float_point - 1. Fixes that */
524 } else {
525 crtc_drain_rate = pclk_freq * bpp/8; /* bpp * pclk/8 */
526
527 crtpagemiss = 1; /* self generating page miss */
528 crtpagemiss += 1; /* MA0 page miss */
529 if(mp_enable)
530 crtpagemiss += 1; /* if MA0 conflict */
531 cpm_us = crtpagemiss * pagemiss *1000*1000/ mclk_freq;
532 us_crt = cpm_us + us_m + us_n + us_p ;
533 clwm = us_crt * crtc_drain_rate/(1000*1000);
534 clwm++; /* fixed point <= float_point - 1. Fixes that */
535
536 /* Finally, a heuristic check when width == 64 bits */
537 if(width == 1){
538 nvclk_fill = nvclk_freq * 8;
539 if(crtc_drain_rate * 100 >= nvclk_fill * 102)
540 clwm = 0xfff; /*Large number to fail */
541
542 else if(crtc_drain_rate * 100 >= nvclk_fill * 98) {
543 clwm = 1024;
544 cbs = 512;
545 }
546 }
547 }
548
549
550 /*
551 Overfill check:
552
553 */
554
555 clwm_rnd_down = ((int)clwm/8)*8;
556 if (clwm_rnd_down < clwm)
557 clwm += 8;
558
559 m1 = clwm + cbs - 1024; /* Amount of overfill */
560 m2us = us_pipe_min + us_min_mclk_extra;
561
562 /* pclk cycles to drain */
563 p1clk = m2us * pclk_freq/(1000*1000);
564 p2 = p1clk * bpp / 8; /* bytes drained. */
565
566 if((p2 < m1) && (m1 > 0)) {
567 fifo->valid = 0;
568 found = 0;
569 if(min_mclk_extra == 0) {
570 if(cbs <= 32) {
571 found = 1; /* Can't adjust anymore! */
572 } else {
573 cbs = cbs/2; /* reduce the burst size */
574 }
575 } else {
576 min_mclk_extra--;
577 }
578 } else {
579 if (clwm > 1023){ /* Have some margin */
580 fifo->valid = 0;
581 found = 0;
582 if(min_mclk_extra == 0)
583 found = 1; /* Can't adjust anymore! */
584 else
585 min_mclk_extra--;
586 }
587 }
588
589 if(clwm < (1024-cbs+8)) clwm = 1024-cbs+8;
590 data = (int)(clwm);
591 /* printf("CRT LWM: %f bytes, prog: 0x%x, bs: 256\n", clwm, data ); */
592 fifo->graphics_lwm = data; fifo->graphics_burst_size = cbs;
593
594 fifo->video_lwm = 1024; fifo->video_burst_size = 512;
595 }
596 }
597
nv10UpdateArbitrationSettings(unsigned VClk,unsigned pixelDepth,unsigned * burst,unsigned * lwm,NVPtr pNv)598 static void nv10UpdateArbitrationSettings (
599 unsigned VClk,
600 unsigned pixelDepth,
601 unsigned *burst,
602 unsigned *lwm,
603 NVPtr pNv
604 )
605 {
606 nv10_fifo_info fifo_data;
607 nv10_sim_state sim_data;
608 unsigned int MClk, NVClk, cfg1;
609
610 nvGetClocks(pNv, &MClk, &NVClk);
611
612 cfg1 = pNv->PFB[0x0204/4];
613 sim_data.pix_bpp = (char)pixelDepth;
614 sim_data.enable_video = 1;
615 sim_data.enable_mp = 0;
616 sim_data.memory_type = (pNv->PFB[0x0200/4] & 0x01) ? 1 : 0;
617 sim_data.memory_width = (pNv->PEXTDEV[0x0000/4] & 0x10) ? 128 : 64;
618 sim_data.mem_latency = (char)cfg1 & 0x0F;
619 sim_data.mem_aligned = 1;
620 sim_data.mem_page_miss = (char)(((cfg1>>4) &0x0F) + ((cfg1>>31) & 0x01));
621 sim_data.gr_during_vid = 0;
622 sim_data.pclk_khz = VClk;
623 sim_data.mclk_khz = MClk;
624 sim_data.nvclk_khz = NVClk;
625 nv10CalcArbitration(&fifo_data, &sim_data);
626 if (fifo_data.valid) {
627 int b = fifo_data.graphics_burst_size >> 4;
628 *burst = 0;
629 while (b >>= 1) (*burst)++;
630 *lwm = fifo_data.graphics_lwm >> 3;
631 }
632 }
633
634
nv30UpdateArbitrationSettings(NVPtr pNv,unsigned * burst,unsigned * lwm)635 static void nv30UpdateArbitrationSettings (
636 NVPtr pNv,
637 unsigned *burst,
638 unsigned *lwm
639 )
640 {
641 unsigned int MClk, NVClk;
642 unsigned int fifo_size, burst_size, graphics_lwm;
643
644 fifo_size = 2048;
645 burst_size = 512;
646 graphics_lwm = fifo_size - burst_size;
647
648 nvGetClocks(pNv, &MClk, &NVClk);
649
650 *burst = 0;
651 burst_size >>= 5;
652 while(burst_size >>= 1) (*burst)++;
653 *lwm = graphics_lwm >> 3;
654 }
655
656 #if XSERVER_LIBPCIACCESS
657 static inline uint32_t
pciaccessReadLong(struct pci_device * const dev,pciaddr_t offset)658 pciaccessReadLong(struct pci_device *const dev, pciaddr_t offset) {
659 uint32_t tmp;
660 pci_device_cfg_read_u32(dev, &tmp, offset);
661 return tmp;
662 }
663 #endif
664
nForceUpdateArbitrationSettings(unsigned VClk,unsigned pixelDepth,unsigned * burst,unsigned * lwm,NVPtr pNv)665 static void nForceUpdateArbitrationSettings (
666 unsigned VClk,
667 unsigned pixelDepth,
668 unsigned *burst,
669 unsigned *lwm,
670 NVPtr pNv
671 )
672 {
673 #if XSERVER_LIBPCIACCESS
674 struct pci_device *const dev1 = pci_device_find_by_slot(0, 0, 0, 1);
675 struct pci_device *const dev2 = pci_device_find_by_slot(0, 0, 0, 2);
676 struct pci_device *const dev3 = pci_device_find_by_slot(0, 0, 0, 3);
677 struct pci_device *const dev5 = pci_device_find_by_slot(0, 0, 0, 5);
678 # define READ_LONG(num, offset) pciaccessReadLong(dev##num, (offset))
679 #else
680 #define READ_LONG(num, offset) pciReadLong(pciTag(0, 0, num), (offset))
681 #endif
682 nv10_fifo_info fifo_data;
683 nv10_sim_state sim_data;
684 unsigned int M, N, P, pll, MClk, NVClk, memctrl;
685
686 if((pNv->Chipset & 0x0FF0) == 0x01A0) {
687 unsigned int uMClkPostDiv;
688
689 uMClkPostDiv = (READ_LONG(3, 0x6C) >> 8) & 0xf;
690 if(!uMClkPostDiv) uMClkPostDiv = 4;
691 MClk = 400000 / uMClkPostDiv;
692 } else {
693 MClk = READ_LONG(5, 0x4C) / 1000;
694 }
695
696 pll = pNv->PRAMDAC0[0x0500/4];
697 M = (pll >> 0) & 0xFF; N = (pll >> 8) & 0xFF; P = (pll >> 16) & 0x0F;
698 NVClk = (N * pNv->CrystalFreqKHz / M) >> P;
699 sim_data.pix_bpp = (char)pixelDepth;
700 sim_data.enable_video = 0;
701 sim_data.enable_mp = 0;
702 sim_data.memory_type = (READ_LONG(1, 0x7C) >> 12) & 1;
703 sim_data.memory_width = 64;
704
705 memctrl = READ_LONG(3, 0x00) >> 16;
706
707 if((memctrl == 0x1A9) || (memctrl == 0x1AB) || (memctrl == 0x1ED)) {
708 int dimm[3];
709
710 dimm[0] = (READ_LONG(2, 0x40) >> 8) & 0x4F;
711 dimm[1] = (READ_LONG(2, 0x44) >> 8) & 0x4F;
712 dimm[2] = (READ_LONG(2, 0x48) >> 8) & 0x4F;
713
714 if((dimm[0] + dimm[1]) != dimm[2]) {
715 ErrorF("WARNING: "
716 "your nForce DIMMs are not arranged in optimal banks!\n");
717 }
718 }
719
720 sim_data.mem_latency = 3;
721 sim_data.mem_aligned = 1;
722 sim_data.mem_page_miss = 10;
723 sim_data.gr_during_vid = 0;
724 sim_data.pclk_khz = VClk;
725 sim_data.mclk_khz = MClk;
726 sim_data.nvclk_khz = NVClk;
727 nv10CalcArbitration(&fifo_data, &sim_data);
728 if (fifo_data.valid)
729 {
730 int b = fifo_data.graphics_burst_size >> 4;
731 *burst = 0;
732 while (b >>= 1) (*burst)++;
733 *lwm = fifo_data.graphics_lwm >> 3;
734 }
735
736 #undef READ_LONG
737 }
738
739
740 /****************************************************************************\
741 * *
742 * RIVA Mode State Routines *
743 * *
744 \****************************************************************************/
745
746 /*
747 * Calculate the Video Clock parameters for the PLL.
748 */
CalcVClock(int clockIn,int * clockOut,U032 * pllOut,NVPtr pNv)749 static void CalcVClock (
750 int clockIn,
751 int *clockOut,
752 U032 *pllOut,
753 NVPtr pNv
754 )
755 {
756 unsigned lowM, highM;
757 unsigned DeltaNew, DeltaOld;
758 unsigned VClk, Freq;
759 unsigned M, N, P;
760
761 DeltaOld = 0xFFFFFFFF;
762
763 VClk = (unsigned)clockIn;
764
765 if (pNv->CrystalFreqKHz == 13500) {
766 lowM = 7;
767 highM = 13;
768 } else {
769 lowM = 8;
770 highM = 14;
771 }
772
773 for (P = 0; P <= 4; P++) {
774 Freq = VClk << P;
775 if ((Freq >= 128000) && (Freq <= 350000)) {
776 for (M = lowM; M <= highM; M++) {
777 N = ((VClk << P) * M) / pNv->CrystalFreqKHz;
778 if(N <= 255) {
779 Freq = ((pNv->CrystalFreqKHz * N) / M) >> P;
780 if (Freq > VClk)
781 DeltaNew = Freq - VClk;
782 else
783 DeltaNew = VClk - Freq;
784 if (DeltaNew < DeltaOld) {
785 *pllOut = (P << 16) | (N << 8) | M;
786 *clockOut = Freq;
787 DeltaOld = DeltaNew;
788 }
789 }
790 }
791 }
792 }
793 }
794
CalcVClock2Stage(int clockIn,int * clockOut,U032 * pllOut,U032 * pllBOut,NVPtr pNv)795 static void CalcVClock2Stage (
796 int clockIn,
797 int *clockOut,
798 U032 *pllOut,
799 U032 *pllBOut,
800 NVPtr pNv
801 )
802 {
803 unsigned DeltaNew, DeltaOld;
804 unsigned VClk, Freq;
805 unsigned M, N, P;
806
807 DeltaOld = 0xFFFFFFFF;
808
809 *pllBOut = 0x80000401; /* fixed at x4 for now */
810
811 VClk = (unsigned)clockIn;
812
813 for (P = 0; P <= 6; P++) {
814 Freq = VClk << P;
815 if ((Freq >= 400000) && (Freq <= 1000000)) {
816 for (M = 1; M <= 13; M++) {
817 N = ((VClk << P) * M) / (pNv->CrystalFreqKHz << 2);
818 if((N >= 5) && (N <= 255)) {
819 Freq = (((pNv->CrystalFreqKHz << 2) * N) / M) >> P;
820 if (Freq > VClk)
821 DeltaNew = Freq - VClk;
822 else
823 DeltaNew = VClk - Freq;
824 if (DeltaNew < DeltaOld) {
825 *pllOut = (P << 16) | (N << 8) | M;
826 *clockOut = Freq;
827 DeltaOld = DeltaNew;
828 }
829 }
830 }
831 }
832 }
833 }
834
835 /*
836 * Calculate extended mode parameters (SVGA) and save in a
837 * mode state structure.
838 */
NVCalcStateExt(NVPtr pNv,RIVA_HW_STATE * state,int bpp,int width,int hDisplaySize,int height,int dotClock,int flags)839 void NVCalcStateExt (
840 NVPtr pNv,
841 RIVA_HW_STATE *state,
842 int bpp,
843 int width,
844 int hDisplaySize,
845 int height,
846 int dotClock,
847 int flags
848 )
849 {
850 int pixelDepth, VClk = 0;
851 /*
852 * Save mode parameters.
853 */
854 state->bpp = bpp; /* this is not bitsPerPixel, it's 8,15,16,32 */
855 state->width = width;
856 state->height = height;
857 /*
858 * Extended RIVA registers.
859 */
860 pixelDepth = (bpp + 1)/8;
861 if(pNv->twoStagePLL)
862 CalcVClock2Stage(dotClock, &VClk, &state->pll, &state->pllB, pNv);
863 else
864 CalcVClock(dotClock, &VClk, &state->pll, pNv);
865
866 switch (pNv->Architecture)
867 {
868 case NV_ARCH_04:
869 nv4UpdateArbitrationSettings(VClk,
870 pixelDepth * 8,
871 &(state->arbitration0),
872 &(state->arbitration1),
873 pNv);
874 state->cursor0 = 0x00;
875 state->cursor1 = 0xbC;
876 if (flags & V_DBLSCAN)
877 state->cursor1 |= 2;
878 state->cursor2 = 0x00000000;
879 state->pllsel = 0x10000700;
880 state->config = 0x00001114;
881 state->general = bpp == 16 ? 0x00101100 : 0x00100100;
882 state->repaint1 = hDisplaySize < 1280 ? 0x04 : 0x00;
883 break;
884 case NV_ARCH_40:
885 if(!pNv->FlatPanel)
886 state->control = pNv->PRAMDAC0[0x0580/4] & 0xeffffeff;
887 /* fallthrough */
888 case NV_ARCH_10:
889 case NV_ARCH_20:
890 case NV_ARCH_30:
891 default:
892 if(((pNv->Chipset & 0xfff0) == 0x0240) ||
893 ((pNv->Chipset & 0xfff0) == 0x03D0) ||
894 ((pNv->Chipset & 0xfff0) == 0x0530))
895 {
896 state->arbitration0 = 128;
897 state->arbitration1 = 0x0480;
898 } else
899 if(((pNv->Chipset & 0xffff) == 0x01A0) ||
900 ((pNv->Chipset & 0xffff) == 0x01f0))
901 {
902 nForceUpdateArbitrationSettings(VClk,
903 pixelDepth * 8,
904 &(state->arbitration0),
905 &(state->arbitration1),
906 pNv);
907 } else if(pNv->Architecture < NV_ARCH_30) {
908 nv10UpdateArbitrationSettings(VClk,
909 pixelDepth * 8,
910 &(state->arbitration0),
911 &(state->arbitration1),
912 pNv);
913 } else {
914 nv30UpdateArbitrationSettings(pNv,
915 &(state->arbitration0),
916 &(state->arbitration1));
917 }
918 state->cursor0 = 0x80 | (pNv->CursorStart >> 17);
919 state->cursor1 = (pNv->CursorStart >> 11) << 2;
920 state->cursor2 = pNv->CursorStart >> 24;
921 if (flags & V_DBLSCAN)
922 state->cursor1 |= 2;
923 state->pllsel = 0x10000700;
924 state->config = pNv->PFB[0x00000200/4];
925 state->general = bpp == 16 ? 0x00101100 : 0x00100100;
926 state->repaint1 = hDisplaySize < 1280 ? 0x04 : 0x00;
927 break;
928 }
929
930 if(bpp != 8) /* DirectColor */
931 state->general |= 0x00000030;
932
933 state->repaint0 = (((width / 8) * pixelDepth) & 0x700) >> 3;
934 state->pixel = (pixelDepth > 2) ? 3 : pixelDepth;
935 }
936
937
NVLoadStateExt(NVPtr pNv,RIVA_HW_STATE * state)938 void NVLoadStateExt (
939 NVPtr pNv,
940 RIVA_HW_STATE *state
941 )
942 {
943 int i, j;
944
945 pNv->PMC[0x0140/4] = 0x00000000;
946 pNv->PMC[0x0200/4] = 0xFFFF00FF;
947 pNv->PMC[0x0200/4] = 0xFFFFFFFF;
948
949 pNv->PTIMER[0x0200] = 0x00000008;
950 pNv->PTIMER[0x0210] = 0x00000003;
951 pNv->PTIMER[0x0140] = 0x00000000;
952 pNv->PTIMER[0x0100] = 0xFFFFFFFF;
953
954 if(pNv->Architecture == NV_ARCH_04) {
955 if (state)
956 pNv->PFB[0x0200/4] = state->config;
957 } else
958 if((pNv->Architecture < NV_ARCH_40) ||
959 ((pNv->Chipset & 0xfff0) == 0x0040))
960 {
961 for(i = 0; i < 8; i++) {
962 pNv->PFB[(0x0240 + (i * 0x10))/4] = 0;
963 pNv->PFB[(0x0244 + (i * 0x10))/4] = pNv->FbMapSize - 1;
964 }
965 } else {
966 int regions = 12;
967
968 if(((pNv->Chipset & 0xfff0) == 0x0090) ||
969 ((pNv->Chipset & 0xfff0) == 0x01D0) ||
970 ((pNv->Chipset & 0xfff0) == 0x0290) ||
971 ((pNv->Chipset & 0xfff0) == 0x0390) ||
972 ((pNv->Chipset & 0xfff0) == 0x03D0))
973 {
974 regions = 15;
975 }
976
977 for(i = 0; i < regions; i++) {
978 pNv->PFB[(0x0600 + (i * 0x10))/4] = 0;
979 pNv->PFB[(0x0604 + (i * 0x10))/4] = pNv->FbMapSize - 1;
980 }
981 }
982
983 if(pNv->Architecture >= NV_ARCH_40) {
984 pNv->PRAMIN[0x0000] = 0x80000010;
985 pNv->PRAMIN[0x0001] = 0x00101202;
986 pNv->PRAMIN[0x0002] = 0x80000011;
987 pNv->PRAMIN[0x0003] = 0x00101204;
988 pNv->PRAMIN[0x0004] = 0x80000012;
989 pNv->PRAMIN[0x0005] = 0x00101206;
990 pNv->PRAMIN[0x0006] = 0x80000013;
991 pNv->PRAMIN[0x0007] = 0x00101208;
992 pNv->PRAMIN[0x0008] = 0x80000014;
993 pNv->PRAMIN[0x0009] = 0x0010120A;
994 pNv->PRAMIN[0x000A] = 0x80000015;
995 pNv->PRAMIN[0x000B] = 0x0010120C;
996 pNv->PRAMIN[0x000C] = 0x80000016;
997 pNv->PRAMIN[0x000D] = 0x0010120E;
998 pNv->PRAMIN[0x000E] = 0x80000017;
999 pNv->PRAMIN[0x000F] = 0x00101210;
1000 pNv->PRAMIN[0x0800] = 0x00003000;
1001 pNv->PRAMIN[0x0801] = pNv->FbMapSize - 1;
1002 pNv->PRAMIN[0x0802] = 0x00000002;
1003 pNv->PRAMIN[0x0808] = 0x02080062;
1004 pNv->PRAMIN[0x0809] = 0x00000000;
1005 pNv->PRAMIN[0x080A] = 0x00001200;
1006 pNv->PRAMIN[0x080B] = 0x00001200;
1007 pNv->PRAMIN[0x080C] = 0x00000000;
1008 pNv->PRAMIN[0x080D] = 0x00000000;
1009 pNv->PRAMIN[0x0810] = 0x02080043;
1010 pNv->PRAMIN[0x0811] = 0x00000000;
1011 pNv->PRAMIN[0x0812] = 0x00000000;
1012 pNv->PRAMIN[0x0813] = 0x00000000;
1013 pNv->PRAMIN[0x0814] = 0x00000000;
1014 pNv->PRAMIN[0x0815] = 0x00000000;
1015 pNv->PRAMIN[0x0818] = 0x02080044;
1016 pNv->PRAMIN[0x0819] = 0x02000000;
1017 pNv->PRAMIN[0x081A] = 0x00000000;
1018 pNv->PRAMIN[0x081B] = 0x00000000;
1019 pNv->PRAMIN[0x081C] = 0x00000000;
1020 pNv->PRAMIN[0x081D] = 0x00000000;
1021 pNv->PRAMIN[0x0820] = 0x02080019;
1022 pNv->PRAMIN[0x0821] = 0x00000000;
1023 pNv->PRAMIN[0x0822] = 0x00000000;
1024 pNv->PRAMIN[0x0823] = 0x00000000;
1025 pNv->PRAMIN[0x0824] = 0x00000000;
1026 pNv->PRAMIN[0x0825] = 0x00000000;
1027 pNv->PRAMIN[0x0828] = 0x020A005C;
1028 pNv->PRAMIN[0x0829] = 0x00000000;
1029 pNv->PRAMIN[0x082A] = 0x00000000;
1030 pNv->PRAMIN[0x082B] = 0x00000000;
1031 pNv->PRAMIN[0x082C] = 0x00000000;
1032 pNv->PRAMIN[0x082D] = 0x00000000;
1033 pNv->PRAMIN[0x0830] = 0x0208009F;
1034 pNv->PRAMIN[0x0831] = 0x00000000;
1035 pNv->PRAMIN[0x0832] = 0x00001200;
1036 pNv->PRAMIN[0x0833] = 0x00001200;
1037 pNv->PRAMIN[0x0834] = 0x00000000;
1038 pNv->PRAMIN[0x0835] = 0x00000000;
1039 pNv->PRAMIN[0x0838] = 0x0208004A;
1040 pNv->PRAMIN[0x0839] = 0x02000000;
1041 pNv->PRAMIN[0x083A] = 0x00000000;
1042 pNv->PRAMIN[0x083B] = 0x00000000;
1043 pNv->PRAMIN[0x083C] = 0x00000000;
1044 pNv->PRAMIN[0x083D] = 0x00000000;
1045 pNv->PRAMIN[0x0840] = 0x02080077;
1046 pNv->PRAMIN[0x0841] = 0x00000000;
1047 pNv->PRAMIN[0x0842] = 0x00001200;
1048 pNv->PRAMIN[0x0843] = 0x00001200;
1049 pNv->PRAMIN[0x0844] = 0x00000000;
1050 pNv->PRAMIN[0x0845] = 0x00000000;
1051 pNv->PRAMIN[0x084C] = 0x00003002;
1052 pNv->PRAMIN[0x084D] = 0x00007FFF;
1053 pNv->PRAMIN[0x084E] = pNv->FbUsableSize | 0x00000002;
1054
1055 #if X_BYTE_ORDER == X_BIG_ENDIAN
1056 pNv->PRAMIN[0x080A] |= 0x01000000;
1057 pNv->PRAMIN[0x0812] |= 0x01000000;
1058 pNv->PRAMIN[0x081A] |= 0x01000000;
1059 pNv->PRAMIN[0x0822] |= 0x01000000;
1060 pNv->PRAMIN[0x082A] |= 0x01000000;
1061 pNv->PRAMIN[0x0832] |= 0x01000000;
1062 pNv->PRAMIN[0x083A] |= 0x01000000;
1063 pNv->PRAMIN[0x0842] |= 0x01000000;
1064 pNv->PRAMIN[0x0819] = 0x01000000;
1065 pNv->PRAMIN[0x0839] = 0x01000000;
1066 #endif
1067 } else {
1068 pNv->PRAMIN[0x0000] = 0x80000010;
1069 pNv->PRAMIN[0x0001] = 0x80011201;
1070 pNv->PRAMIN[0x0002] = 0x80000011;
1071 pNv->PRAMIN[0x0003] = 0x80011202;
1072 pNv->PRAMIN[0x0004] = 0x80000012;
1073 pNv->PRAMIN[0x0005] = 0x80011203;
1074 pNv->PRAMIN[0x0006] = 0x80000013;
1075 pNv->PRAMIN[0x0007] = 0x80011204;
1076 pNv->PRAMIN[0x0008] = 0x80000014;
1077 pNv->PRAMIN[0x0009] = 0x80011205;
1078 pNv->PRAMIN[0x000A] = 0x80000015;
1079 pNv->PRAMIN[0x000B] = 0x80011206;
1080 pNv->PRAMIN[0x000C] = 0x80000016;
1081 pNv->PRAMIN[0x000D] = 0x80011207;
1082 pNv->PRAMIN[0x000E] = 0x80000017;
1083 pNv->PRAMIN[0x000F] = 0x80011208;
1084 pNv->PRAMIN[0x0800] = 0x00003000;
1085 pNv->PRAMIN[0x0801] = pNv->FbMapSize - 1;
1086 pNv->PRAMIN[0x0802] = 0x00000002;
1087 pNv->PRAMIN[0x0803] = 0x00000002;
1088 if(pNv->Architecture >= NV_ARCH_10)
1089 pNv->PRAMIN[0x0804] = 0x01008062;
1090 else
1091 pNv->PRAMIN[0x0804] = 0x01008042;
1092 pNv->PRAMIN[0x0805] = 0x00000000;
1093 pNv->PRAMIN[0x0806] = 0x12001200;
1094 pNv->PRAMIN[0x0807] = 0x00000000;
1095 pNv->PRAMIN[0x0808] = 0x01008043;
1096 pNv->PRAMIN[0x0809] = 0x00000000;
1097 pNv->PRAMIN[0x080A] = 0x00000000;
1098 pNv->PRAMIN[0x080B] = 0x00000000;
1099 pNv->PRAMIN[0x080C] = 0x01008044;
1100 pNv->PRAMIN[0x080D] = 0x00000002;
1101 pNv->PRAMIN[0x080E] = 0x00000000;
1102 pNv->PRAMIN[0x080F] = 0x00000000;
1103 pNv->PRAMIN[0x0810] = 0x01008019;
1104 pNv->PRAMIN[0x0811] = 0x00000000;
1105 pNv->PRAMIN[0x0812] = 0x00000000;
1106 pNv->PRAMIN[0x0813] = 0x00000000;
1107 pNv->PRAMIN[0x0814] = 0x0100A05C;
1108 pNv->PRAMIN[0x0815] = 0x00000000;
1109 pNv->PRAMIN[0x0816] = 0x00000000;
1110 pNv->PRAMIN[0x0817] = 0x00000000;
1111 if(pNv->WaitVSyncPossible)
1112 pNv->PRAMIN[0x0818] = 0x0100809F;
1113 else
1114 pNv->PRAMIN[0x0818] = 0x0100805F;
1115 pNv->PRAMIN[0x0819] = 0x00000000;
1116 pNv->PRAMIN[0x081A] = 0x12001200;
1117 pNv->PRAMIN[0x081B] = 0x00000000;
1118 pNv->PRAMIN[0x081C] = 0x0100804A;
1119 pNv->PRAMIN[0x081D] = 0x00000002;
1120 pNv->PRAMIN[0x081E] = 0x00000000;
1121 pNv->PRAMIN[0x081F] = 0x00000000;
1122 pNv->PRAMIN[0x0820] = 0x01018077;
1123 pNv->PRAMIN[0x0821] = 0x00000000;
1124 pNv->PRAMIN[0x0822] = 0x12001200;
1125 pNv->PRAMIN[0x0823] = 0x00000000;
1126 pNv->PRAMIN[0x0824] = 0x00003002;
1127 pNv->PRAMIN[0x0825] = 0x00007FFF;
1128 pNv->PRAMIN[0x0826] = pNv->FbUsableSize | 0x00000002;
1129 pNv->PRAMIN[0x0827] = 0x00000002;
1130
1131 #if X_BYTE_ORDER == X_BIG_ENDIAN
1132 pNv->PRAMIN[0x0804] |= 0x00080000;
1133 pNv->PRAMIN[0x0808] |= 0x00080000;
1134 pNv->PRAMIN[0x080C] |= 0x00080000;
1135 pNv->PRAMIN[0x0810] |= 0x00080000;
1136 pNv->PRAMIN[0x0814] |= 0x00080000;
1137 pNv->PRAMIN[0x0818] |= 0x00080000;
1138 pNv->PRAMIN[0x081C] |= 0x00080000;
1139 pNv->PRAMIN[0x0820] |= 0x00080000;
1140 pNv->PRAMIN[0x080D] = 0x00000001;
1141 pNv->PRAMIN[0x081D] = 0x00000001;
1142 #endif
1143 }
1144
1145 if(pNv->Architecture < NV_ARCH_10) {
1146 if((pNv->Chipset & 0x0fff) == 0x0020) {
1147 pNv->PRAMIN[0x0824] |= 0x00020000;
1148 pNv->PRAMIN[0x0826] += pNv->FbAddress;
1149 }
1150 pNv->PGRAPH[0x0080/4] = 0x000001FF;
1151 pNv->PGRAPH[0x0080/4] = 0x1230C000;
1152 pNv->PGRAPH[0x0084/4] = 0x72111101;
1153 pNv->PGRAPH[0x0088/4] = 0x11D5F071;
1154 pNv->PGRAPH[0x008C/4] = 0x0004FF31;
1155 pNv->PGRAPH[0x008C/4] = 0x4004FF31;
1156
1157 pNv->PGRAPH[0x0140/4] = 0x00000000;
1158 pNv->PGRAPH[0x0100/4] = 0xFFFFFFFF;
1159 pNv->PGRAPH[0x0170/4] = 0x10010100;
1160 pNv->PGRAPH[0x0710/4] = 0xFFFFFFFF;
1161 pNv->PGRAPH[0x0720/4] = 0x00000001;
1162
1163 pNv->PGRAPH[0x0810/4] = 0x00000000;
1164 pNv->PGRAPH[0x0608/4] = 0xFFFFFFFF;
1165 } else {
1166 pNv->PGRAPH[0x0080/4] = 0xFFFFFFFF;
1167 pNv->PGRAPH[0x0080/4] = 0x00000000;
1168
1169 pNv->PGRAPH[0x0140/4] = 0x00000000;
1170 pNv->PGRAPH[0x0100/4] = 0xFFFFFFFF;
1171 pNv->PGRAPH[0x0144/4] = 0x10010100;
1172 pNv->PGRAPH[0x0714/4] = 0xFFFFFFFF;
1173 pNv->PGRAPH[0x0720/4] = 0x00000001;
1174 pNv->PGRAPH[0x0710/4] &= 0x0007ff00;
1175 pNv->PGRAPH[0x0710/4] |= 0x00020100;
1176
1177 if(pNv->Architecture == NV_ARCH_10) {
1178 pNv->PGRAPH[0x0084/4] = 0x00118700;
1179 pNv->PGRAPH[0x0088/4] = 0x24E00810;
1180 pNv->PGRAPH[0x008C/4] = 0x55DE0030;
1181
1182 for(i = 0; i < 32; i++)
1183 pNv->PGRAPH[(0x0B00/4) + i] = pNv->PFB[(0x0240/4) + i];
1184
1185 pNv->PGRAPH[0x640/4] = 0;
1186 pNv->PGRAPH[0x644/4] = 0;
1187 pNv->PGRAPH[0x684/4] = pNv->FbMapSize - 1;
1188 pNv->PGRAPH[0x688/4] = pNv->FbMapSize - 1;
1189
1190 pNv->PGRAPH[0x0810/4] = 0x00000000;
1191 pNv->PGRAPH[0x0608/4] = 0xFFFFFFFF;
1192 } else {
1193 if(pNv->Architecture >= NV_ARCH_40) {
1194 pNv->PGRAPH[0x0084/4] = 0x401287c0;
1195 pNv->PGRAPH[0x008C/4] = 0x60de8051;
1196 pNv->PGRAPH[0x0090/4] = 0x00008000;
1197 pNv->PGRAPH[0x0610/4] = 0x00be3c5f;
1198 pNv->PGRAPH[0x0bc4/4] |= 0x00008000;
1199
1200 j = pNv->REGS[0x1540/4] & 0xff;
1201 if(j) {
1202 for(i = 0; !(j & 1); j >>= 1, i++);
1203 pNv->PGRAPH[0x5000/4] = i;
1204 }
1205
1206 if((pNv->Chipset & 0xfff0) == 0x0040) {
1207 pNv->PGRAPH[0x09b0/4] = 0x83280fff;
1208 pNv->PGRAPH[0x09b4/4] = 0x000000a0;
1209 } else {
1210 pNv->PGRAPH[0x0820/4] = 0x83280eff;
1211 pNv->PGRAPH[0x0824/4] = 0x000000a0;
1212 }
1213
1214 switch(pNv->Chipset & 0xfff0) {
1215 case 0x0040:
1216 case 0x0210:
1217 pNv->PGRAPH[0x09b8/4] = 0x0078e366;
1218 pNv->PGRAPH[0x09bc/4] = 0x0000014c;
1219 pNv->PFB[0x033C/4] &= 0xffff7fff;
1220 break;
1221 case 0x00C0:
1222 case 0x0120:
1223 pNv->PGRAPH[0x0828/4] = 0x007596ff;
1224 pNv->PGRAPH[0x082C/4] = 0x00000108;
1225 break;
1226 case 0x0160:
1227 case 0x01D0:
1228 case 0x0240:
1229 case 0x03D0:
1230 case 0x0530:
1231 pNv->PMC[0x1700/4] = pNv->PFB[0x020C/4];
1232 pNv->PMC[0x1704/4] = 0;
1233 pNv->PMC[0x1708/4] = 0;
1234 pNv->PMC[0x170C/4] = pNv->PFB[0x020C/4];
1235 pNv->PGRAPH[0x0860/4] = 0;
1236 pNv->PGRAPH[0x0864/4] = 0;
1237 pNv->PRAMDAC[0x0608/4] |= 0x00100000;
1238 break;
1239 case 0x0140:
1240 pNv->PGRAPH[0x0828/4] = 0x0072cb77;
1241 pNv->PGRAPH[0x082C/4] = 0x00000108;
1242 break;
1243 case 0x0220:
1244 pNv->PGRAPH[0x0860/4] = 0;
1245 pNv->PGRAPH[0x0864/4] = 0;
1246 pNv->PRAMDAC[0x0608/4] |= 0x00100000;
1247 break;
1248 case 0x0090:
1249 case 0x0290:
1250 case 0x0390:
1251 pNv->PRAMDAC[0x0608/4] |= 0x00100000;
1252 pNv->PGRAPH[0x0828/4] = 0x07830610;
1253 pNv->PGRAPH[0x082C/4] = 0x0000016A;
1254 break;
1255 default:
1256 break;
1257 };
1258
1259 pNv->PGRAPH[0x0b38/4] = 0x2ffff800;
1260 pNv->PGRAPH[0x0b3c/4] = 0x00006000;
1261 pNv->PGRAPH[0x032C/4] = 0x01000000;
1262 pNv->PGRAPH[0x0220/4] = 0x00001200;
1263 } else
1264 if(pNv->Architecture == NV_ARCH_30) {
1265 pNv->PGRAPH[0x0084/4] = 0x40108700;
1266 pNv->PGRAPH[0x0890/4] = 0x00140000;
1267 pNv->PGRAPH[0x008C/4] = 0xf00e0431;
1268 pNv->PGRAPH[0x0090/4] = 0x00008000;
1269 pNv->PGRAPH[0x0610/4] = 0xf04b1f36;
1270 pNv->PGRAPH[0x0B80/4] = 0x1002d888;
1271 pNv->PGRAPH[0x0B88/4] = 0x62ff007f;
1272 } else {
1273 pNv->PGRAPH[0x0084/4] = 0x00118700;
1274 pNv->PGRAPH[0x008C/4] = 0xF20E0431;
1275 pNv->PGRAPH[0x0090/4] = 0x00000000;
1276 pNv->PGRAPH[0x009C/4] = 0x00000040;
1277
1278 if((pNv->Chipset & 0x0ff0) >= 0x0250) {
1279 pNv->PGRAPH[0x0890/4] = 0x00080000;
1280 pNv->PGRAPH[0x0610/4] = 0x304B1FB6;
1281 pNv->PGRAPH[0x0B80/4] = 0x18B82880;
1282 pNv->PGRAPH[0x0B84/4] = 0x44000000;
1283 pNv->PGRAPH[0x0098/4] = 0x40000080;
1284 pNv->PGRAPH[0x0B88/4] = 0x000000ff;
1285 } else {
1286 pNv->PGRAPH[0x0880/4] = 0x00080000;
1287 pNv->PGRAPH[0x0094/4] = 0x00000005;
1288 pNv->PGRAPH[0x0B80/4] = 0x45CAA208;
1289 pNv->PGRAPH[0x0B84/4] = 0x24000000;
1290 pNv->PGRAPH[0x0098/4] = 0x00000040;
1291 pNv->PGRAPH[0x0750/4] = 0x00E00038;
1292 pNv->PGRAPH[0x0754/4] = 0x00000030;
1293 pNv->PGRAPH[0x0750/4] = 0x00E10038;
1294 pNv->PGRAPH[0x0754/4] = 0x00000030;
1295 }
1296 }
1297
1298 if((pNv->Architecture < NV_ARCH_40) ||
1299 ((pNv->Chipset & 0xfff0) == 0x0040))
1300 {
1301 for(i = 0; i < 32; i++) {
1302 pNv->PGRAPH[(0x0900/4) + i] = pNv->PFB[(0x0240/4) + i];
1303 pNv->PGRAPH[(0x6900/4) + i] = pNv->PFB[(0x0240/4) + i];
1304 }
1305 } else {
1306 if(((pNv->Chipset & 0xfff0) == 0x0090) ||
1307 ((pNv->Chipset & 0xfff0) == 0x01D0) ||
1308 ((pNv->Chipset & 0xfff0) == 0x0290) ||
1309 ((pNv->Chipset & 0xfff0) == 0x0390) ||
1310 ((pNv->Chipset & 0xfff0) == 0x03D0))
1311 {
1312 for(i = 0; i < 60; i++) {
1313 pNv->PGRAPH[(0x0D00/4) + i] = pNv->PFB[(0x0600/4) + i];
1314 pNv->PGRAPH[(0x6900/4) + i] = pNv->PFB[(0x0600/4) + i];
1315 }
1316 } else {
1317 for(i = 0; i < 48; i++) {
1318 pNv->PGRAPH[(0x0900/4) + i] = pNv->PFB[(0x0600/4) + i];
1319 if(((pNv->Chipset & 0xfff0) != 0x0160) &&
1320 ((pNv->Chipset & 0xfff0) != 0x0220) &&
1321 ((pNv->Chipset & 0xfff0) != 0x0240) &&
1322 ((pNv->Chipset & 0xfff0) != 0x0530))
1323 {
1324 pNv->PGRAPH[(0x6900/4) + i] = pNv->PFB[(0x0600/4) + i];
1325 }
1326 }
1327 }
1328 }
1329
1330 if(pNv->Architecture >= NV_ARCH_40) {
1331 if((pNv->Chipset & 0xfff0) == 0x0040) {
1332 pNv->PGRAPH[0x09A4/4] = pNv->PFB[0x0200/4];
1333 pNv->PGRAPH[0x09A8/4] = pNv->PFB[0x0204/4];
1334 pNv->PGRAPH[0x69A4/4] = pNv->PFB[0x0200/4];
1335 pNv->PGRAPH[0x69A8/4] = pNv->PFB[0x0204/4];
1336
1337 pNv->PGRAPH[0x0820/4] = 0;
1338 pNv->PGRAPH[0x0824/4] = 0;
1339 pNv->PGRAPH[0x0864/4] = pNv->FbMapSize - 1;
1340 pNv->PGRAPH[0x0868/4] = pNv->FbMapSize - 1;
1341 } else {
1342 if(((pNv->Chipset & 0xfff0) == 0x0090) ||
1343 ((pNv->Chipset & 0xfff0) == 0x01D0) ||
1344 ((pNv->Chipset & 0xfff0) == 0x0290) ||
1345 ((pNv->Chipset & 0xfff0) == 0x0390))
1346 {
1347 pNv->PGRAPH[0x0DF0/4] = pNv->PFB[0x0200/4];
1348 pNv->PGRAPH[0x0DF4/4] = pNv->PFB[0x0204/4];
1349 } else {
1350 pNv->PGRAPH[0x09F0/4] = pNv->PFB[0x0200/4];
1351 pNv->PGRAPH[0x09F4/4] = pNv->PFB[0x0204/4];
1352 }
1353 pNv->PGRAPH[0x69F0/4] = pNv->PFB[0x0200/4];
1354 pNv->PGRAPH[0x69F4/4] = pNv->PFB[0x0204/4];
1355
1356 pNv->PGRAPH[0x0840/4] = 0;
1357 pNv->PGRAPH[0x0844/4] = 0;
1358 pNv->PGRAPH[0x08a0/4] = pNv->FbMapSize - 1;
1359 pNv->PGRAPH[0x08a4/4] = pNv->FbMapSize - 1;
1360 }
1361 } else {
1362 pNv->PGRAPH[0x09A4/4] = pNv->PFB[0x0200/4];
1363 pNv->PGRAPH[0x09A8/4] = pNv->PFB[0x0204/4];
1364 pNv->PGRAPH[0x0750/4] = 0x00EA0000;
1365 pNv->PGRAPH[0x0754/4] = pNv->PFB[0x0200/4];
1366 pNv->PGRAPH[0x0750/4] = 0x00EA0004;
1367 pNv->PGRAPH[0x0754/4] = pNv->PFB[0x0204/4];
1368
1369 pNv->PGRAPH[0x0820/4] = 0;
1370 pNv->PGRAPH[0x0824/4] = 0;
1371 pNv->PGRAPH[0x0864/4] = pNv->FbMapSize - 1;
1372 pNv->PGRAPH[0x0868/4] = pNv->FbMapSize - 1;
1373 }
1374
1375 pNv->PGRAPH[0x0B20/4] = 0x00000000;
1376 pNv->PGRAPH[0x0B04/4] = 0xFFFFFFFF;
1377 }
1378 }
1379 pNv->PGRAPH[0x053C/4] = 0;
1380 pNv->PGRAPH[0x0540/4] = 0;
1381 pNv->PGRAPH[0x0544/4] = 0x00007FFF;
1382 pNv->PGRAPH[0x0548/4] = 0x00007FFF;
1383
1384 pNv->PFIFO[0x0140] = 0x00000000;
1385 pNv->PFIFO[0x0141] = 0x00000001;
1386 pNv->PFIFO[0x0480] = 0x00000000;
1387 pNv->PFIFO[0x0494] = 0x00000000;
1388 if(pNv->Architecture >= NV_ARCH_40)
1389 pNv->PFIFO[0x0481] = 0x00010000;
1390 else
1391 pNv->PFIFO[0x0481] = 0x00000100;
1392 pNv->PFIFO[0x0490] = 0x00000000;
1393 pNv->PFIFO[0x0491] = 0x00000000;
1394 if(pNv->Architecture >= NV_ARCH_40)
1395 pNv->PFIFO[0x048B] = 0x00001213;
1396 else
1397 pNv->PFIFO[0x048B] = 0x00001209;
1398 pNv->PFIFO[0x0400] = 0x00000000;
1399 pNv->PFIFO[0x0414] = 0x00000000;
1400 pNv->PFIFO[0x0084] = 0x03000100;
1401 pNv->PFIFO[0x0085] = 0x00000110;
1402 pNv->PFIFO[0x0086] = 0x00000112;
1403 pNv->PFIFO[0x0143] = 0x0000FFFF;
1404 pNv->PFIFO[0x0496] = 0x0000FFFF;
1405 pNv->PFIFO[0x0050] = 0x00000000;
1406 pNv->PFIFO[0x0040] = 0xFFFFFFFF;
1407 pNv->PFIFO[0x0415] = 0x00000001;
1408 pNv->PFIFO[0x048C] = 0x00000000;
1409 pNv->PFIFO[0x04A0] = 0x00000000;
1410 #if X_BYTE_ORDER == X_BIG_ENDIAN
1411 pNv->PFIFO[0x0489] = 0x800F0078;
1412 #else
1413 pNv->PFIFO[0x0489] = 0x000F0078;
1414 #endif
1415 pNv->PFIFO[0x0488] = 0x00000001;
1416 pNv->PFIFO[0x0480] = 0x00000001;
1417 pNv->PFIFO[0x0494] = 0x00000001;
1418 pNv->PFIFO[0x0495] = 0x00000001;
1419 pNv->PFIFO[0x0140] = 0x00000001;
1420
1421 if(!state) {
1422 pNv->CurrentState = NULL;
1423 return;
1424 }
1425
1426 if(pNv->Architecture >= NV_ARCH_10) {
1427 if(pNv->twoHeads) {
1428 pNv->PCRTC0[0x0860/4] = state->head;
1429 pNv->PCRTC0[0x2860/4] = state->head2;
1430 }
1431 pNv->PRAMDAC[0x0404/4] |= (1 << 25);
1432
1433 pNv->PMC[0x8704/4] = 1;
1434 pNv->PMC[0x8140/4] = 0;
1435 pNv->PMC[0x8920/4] = 0;
1436 pNv->PMC[0x8924/4] = 0;
1437 pNv->PMC[0x8908/4] = pNv->FbMapSize - 1;
1438 pNv->PMC[0x890C/4] = pNv->FbMapSize - 1;
1439 pNv->PMC[0x1588/4] = 0;
1440
1441 pNv->PCRTC[0x0810/4] = state->cursorConfig;
1442 pNv->PCRTC[0x0830/4] = state->displayV - 3;
1443 pNv->PCRTC[0x0834/4] = state->displayV - 1;
1444
1445 if(pNv->FlatPanel) {
1446 if((pNv->Chipset & 0x0ff0) == 0x0110) {
1447 pNv->PRAMDAC[0x0528/4] = state->dither;
1448 } else
1449 if(pNv->twoHeads) {
1450 pNv->PRAMDAC[0x083C/4] = state->dither;
1451 }
1452
1453 VGA_WR08(pNv->PCIO, 0x03D4, 0x53);
1454 VGA_WR08(pNv->PCIO, 0x03D5, state->timingH);
1455 VGA_WR08(pNv->PCIO, 0x03D4, 0x54);
1456 VGA_WR08(pNv->PCIO, 0x03D5, state->timingV);
1457 VGA_WR08(pNv->PCIO, 0x03D4, 0x21);
1458 VGA_WR08(pNv->PCIO, 0x03D5, 0xfa);
1459 }
1460
1461 VGA_WR08(pNv->PCIO, 0x03D4, 0x41);
1462 VGA_WR08(pNv->PCIO, 0x03D5, state->extra);
1463 }
1464
1465 VGA_WR08(pNv->PCIO, 0x03D4, 0x19);
1466 VGA_WR08(pNv->PCIO, 0x03D5, state->repaint0);
1467 VGA_WR08(pNv->PCIO, 0x03D4, 0x1A);
1468 VGA_WR08(pNv->PCIO, 0x03D5, state->repaint1);
1469 VGA_WR08(pNv->PCIO, 0x03D4, 0x25);
1470 VGA_WR08(pNv->PCIO, 0x03D5, state->screen);
1471 VGA_WR08(pNv->PCIO, 0x03D4, 0x28);
1472 VGA_WR08(pNv->PCIO, 0x03D5, state->pixel);
1473 VGA_WR08(pNv->PCIO, 0x03D4, 0x2D);
1474 VGA_WR08(pNv->PCIO, 0x03D5, state->horiz);
1475 VGA_WR08(pNv->PCIO, 0x03D4, 0x1C);
1476 VGA_WR08(pNv->PCIO, 0x03D5, state->fifo);
1477 VGA_WR08(pNv->PCIO, 0x03D4, 0x1B);
1478 VGA_WR08(pNv->PCIO, 0x03D5, state->arbitration0);
1479 VGA_WR08(pNv->PCIO, 0x03D4, 0x20);
1480 VGA_WR08(pNv->PCIO, 0x03D5, state->arbitration1);
1481 if(pNv->Architecture >= NV_ARCH_30) {
1482 VGA_WR08(pNv->PCIO, 0x03D4, 0x47);
1483 VGA_WR08(pNv->PCIO, 0x03D5, state->arbitration1 >> 8);
1484 }
1485 VGA_WR08(pNv->PCIO, 0x03D4, 0x30);
1486 VGA_WR08(pNv->PCIO, 0x03D5, state->cursor0);
1487 VGA_WR08(pNv->PCIO, 0x03D4, 0x31);
1488 VGA_WR08(pNv->PCIO, 0x03D5, state->cursor1);
1489 VGA_WR08(pNv->PCIO, 0x03D4, 0x2F);
1490 VGA_WR08(pNv->PCIO, 0x03D5, state->cursor2);
1491 VGA_WR08(pNv->PCIO, 0x03D4, 0x39);
1492 VGA_WR08(pNv->PCIO, 0x03D5, state->interlace);
1493
1494 if(!pNv->FlatPanel) {
1495 if(pNv->Architecture >= NV_ARCH_40) {
1496 pNv->PRAMDAC0[0x0580/4] = state->control;
1497 }
1498
1499 pNv->PRAMDAC0[0x050C/4] = state->pllsel;
1500 pNv->PRAMDAC0[0x0508/4] = state->vpll;
1501 if(pNv->twoHeads)
1502 pNv->PRAMDAC0[0x0520/4] = state->vpll2;
1503 if(pNv->twoStagePLL) {
1504 pNv->PRAMDAC0[0x0578/4] = state->vpllB;
1505 pNv->PRAMDAC0[0x057C/4] = state->vpll2B;
1506 }
1507 } else {
1508 pNv->PRAMDAC[0x0848/4] = state->scale;
1509 pNv->PRAMDAC[0x0828/4] = state->crtcSync;
1510 pNv->PRAMDAC[0x0808/4] = state->crtcVSync;
1511 }
1512 pNv->PRAMDAC[0x0600/4] = state->general;
1513
1514 pNv->PCRTC[0x0140/4] = 0;
1515 pNv->PCRTC[0x0100/4] = 1;
1516
1517 pNv->CurrentState = state;
1518 }
1519
NVUnloadStateExt(NVPtr pNv,RIVA_HW_STATE * state)1520 void NVUnloadStateExt
1521 (
1522 NVPtr pNv,
1523 RIVA_HW_STATE *state
1524 )
1525 {
1526 VGA_WR08(pNv->PCIO, 0x03D4, 0x19);
1527 state->repaint0 = VGA_RD08(pNv->PCIO, 0x03D5);
1528 VGA_WR08(pNv->PCIO, 0x03D4, 0x1A);
1529 state->repaint1 = VGA_RD08(pNv->PCIO, 0x03D5);
1530 VGA_WR08(pNv->PCIO, 0x03D4, 0x25);
1531 state->screen = VGA_RD08(pNv->PCIO, 0x03D5);
1532 VGA_WR08(pNv->PCIO, 0x03D4, 0x28);
1533 state->pixel = VGA_RD08(pNv->PCIO, 0x03D5);
1534 VGA_WR08(pNv->PCIO, 0x03D4, 0x2D);
1535 state->horiz = VGA_RD08(pNv->PCIO, 0x03D5);
1536 VGA_WR08(pNv->PCIO, 0x03D4, 0x1C);
1537 state->fifo = VGA_RD08(pNv->PCIO, 0x03D5);
1538 VGA_WR08(pNv->PCIO, 0x03D4, 0x1B);
1539 state->arbitration0 = VGA_RD08(pNv->PCIO, 0x03D5);
1540 VGA_WR08(pNv->PCIO, 0x03D4, 0x20);
1541 state->arbitration1 = VGA_RD08(pNv->PCIO, 0x03D5);
1542 if(pNv->Architecture >= NV_ARCH_30) {
1543 VGA_WR08(pNv->PCIO, 0x03D4, 0x47);
1544 state->arbitration1 |= (VGA_RD08(pNv->PCIO, 0x03D5) & 1) << 8;
1545 }
1546 VGA_WR08(pNv->PCIO, 0x03D4, 0x30);
1547 state->cursor0 = VGA_RD08(pNv->PCIO, 0x03D5);
1548 VGA_WR08(pNv->PCIO, 0x03D4, 0x31);
1549 state->cursor1 = VGA_RD08(pNv->PCIO, 0x03D5);
1550 VGA_WR08(pNv->PCIO, 0x03D4, 0x2F);
1551 state->cursor2 = VGA_RD08(pNv->PCIO, 0x03D5);
1552 VGA_WR08(pNv->PCIO, 0x03D4, 0x39);
1553 state->interlace = VGA_RD08(pNv->PCIO, 0x03D5);
1554 state->vpll = pNv->PRAMDAC0[0x0508/4];
1555 if(pNv->twoHeads)
1556 state->vpll2 = pNv->PRAMDAC0[0x0520/4];
1557 if(pNv->twoStagePLL) {
1558 state->vpllB = pNv->PRAMDAC0[0x0578/4];
1559 state->vpll2B = pNv->PRAMDAC0[0x057C/4];
1560 }
1561 state->pllsel = pNv->PRAMDAC0[0x050C/4];
1562 state->general = pNv->PRAMDAC[0x0600/4];
1563 state->scale = pNv->PRAMDAC[0x0848/4];
1564 state->config = pNv->PFB[0x0200/4];
1565
1566 if(pNv->Architecture >= NV_ARCH_40 && !pNv->FlatPanel) {
1567 state->control = pNv->PRAMDAC0[0x0580/4];
1568 }
1569
1570 if(pNv->Architecture >= NV_ARCH_10) {
1571 if(pNv->twoHeads) {
1572 state->head = pNv->PCRTC0[0x0860/4];
1573 state->head2 = pNv->PCRTC0[0x2860/4];
1574 VGA_WR08(pNv->PCIO, 0x03D4, 0x44);
1575 state->crtcOwner = VGA_RD08(pNv->PCIO, 0x03D5);
1576 }
1577 VGA_WR08(pNv->PCIO, 0x03D4, 0x41);
1578 state->extra = VGA_RD08(pNv->PCIO, 0x03D5);
1579 state->cursorConfig = pNv->PCRTC[0x0810/4];
1580
1581 if((pNv->Chipset & 0x0ff0) == 0x0110) {
1582 state->dither = pNv->PRAMDAC[0x0528/4];
1583 } else
1584 if(pNv->twoHeads) {
1585 state->dither = pNv->PRAMDAC[0x083C/4];
1586 }
1587
1588 if(pNv->FlatPanel) {
1589 VGA_WR08(pNv->PCIO, 0x03D4, 0x53);
1590 state->timingH = VGA_RD08(pNv->PCIO, 0x03D5);
1591 VGA_WR08(pNv->PCIO, 0x03D4, 0x54);
1592 state->timingV = VGA_RD08(pNv->PCIO, 0x03D5);
1593 }
1594 }
1595
1596 if(pNv->FlatPanel) {
1597 state->crtcSync = pNv->PRAMDAC[0x0828/4];
1598 state->crtcVSync = pNv->PRAMDAC[0x0808/4];
1599 }
1600 }
1601
NVSetStartAddress(NVPtr pNv,CARD32 start)1602 void NVSetStartAddress (
1603 NVPtr pNv,
1604 CARD32 start
1605 )
1606 {
1607 if (pNv->VBEDualhead) {
1608 pNv->PCRTC0[0x800/4] = start;
1609 pNv->PCRTC0[0x2800/4] = start + pNv->vbeCRTC1Offset;
1610 } else {
1611 pNv->PCRTC[0x800/4] = start;
1612 }
1613 }
1614