File: /usr/src/linux/drivers/video/riva/riva_hw.c
1 /***************************************************************************\
2 |* *|
3 |* Copyright 1993-1999 NVIDIA, Corporation. All rights reserved. *|
4 |* *|
5 |* NOTICE TO USER: The source code is copyrighted under U.S. and *|
6 |* international laws. Users and possessors of this source code are *|
7 |* hereby granted a nonexclusive, royalty-free copyright license to *|
8 |* use this code in individual and commercial software. *|
9 |* *|
10 |* Any use of this source code must include, in the user documenta- *|
11 |* tion and internal comments to the code, notices to the end user *|
12 |* as follows: *|
13 |* *|
14 |* Copyright 1993-1999 NVIDIA, Corporation. All rights reserved. *|
15 |* *|
16 |* NVIDIA, CORPORATION MAKES NO REPRESENTATION ABOUT THE SUITABILITY *|
17 |* OF THIS SOURCE CODE FOR ANY PURPOSE. IT IS PROVIDED "AS IS" *|
18 |* WITHOUT EXPRESS OR IMPLIED WARRANTY OF ANY KIND. NVIDIA, CORPOR- *|
19 |* ATION DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOURCE CODE, *|
20 |* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGE- *|
21 |* MENT, AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL *|
22 |* NVIDIA, CORPORATION BE LIABLE FOR ANY SPECIAL, INDIRECT, INCI- *|
23 |* DENTAL, OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RE- *|
24 |* SULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION *|
25 |* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF *|
26 |* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOURCE CODE. *|
27 |* *|
28 |* U.S. Government End Users. This source code is a "commercial *|
29 |* item," as that term is defined at 48 C.F.R. 2.101 (OCT 1995), *|
30 |* consisting of "commercial computer software" and "commercial *|
31 |* computer software documentation," as such terms are used in *|
32 |* 48 C.F.R. 12.212 (SEPT 1995) and is provided to the U.S. Govern- *|
33 |* ment only as a commercial end item. Consistent with 48 C.F.R. *|
34 |* 12.212 and 48 C.F.R. 227.7202-1 through 227.7202-4 (JUNE 1995), *|
35 |* all U.S. Government End Users acquire the source code with only *|
36 |* those rights set forth herein. *|
37 |* *|
38 \***************************************************************************/
39
40 /*
41 * GPL licensing note -- nVidia is allowing a liberal interpretation of
42 * the documentation restriction above, to merely say that this nVidia's
43 * copyright and disclaimer should be included with all code derived
44 * from this source. -- Jeff Garzik <jgarzik@mandrakesoft.com>, 01/Nov/99
45 */
46
47 /* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/nv/riva_hw.c,v 1.8 2000/02/08 17:19:11 dawes Exp $ */
48
49 #include "riva_hw.h"
50 #include "riva_tbl.h"
51 /*
52 * This file is an OS-agnostic file used to make RIVA 128 and RIVA TNT
53 * operate identically (except TNT has more memory and better 3D quality.
54 */
55 static int nv3Busy
56 (
57 RIVA_HW_INST *chip
58 )
59 {
60 return ((chip->Rop->FifoFree < chip->FifoEmptyCount) || (chip->PGRAPH[0x000006B0/4] & 0x01));
61 }
62 static int nv4Busy
63 (
64 RIVA_HW_INST *chip
65 )
66 {
67 return ((chip->Rop->FifoFree < chip->FifoEmptyCount) || (chip->PGRAPH[0x00000700/4] & 0x01));
68 }
69 static int nv10Busy
70 (
71 RIVA_HW_INST *chip
72 )
73 {
74 return ((chip->Rop->FifoFree < chip->FifoEmptyCount) || (chip->PGRAPH[0x00000700/4] & 0x01));
75 }
76 static void nv3LockUnlock
77 (
78 RIVA_HW_INST *chip,
79 int LockUnlock
80 )
81 {
82 VGA_WR08(chip->PVIO, 0x3C4, 0x06);
83 VGA_WR08(chip->PVIO, 0x3C5, LockUnlock ? 0x99 : 0x57);
84 }
85 static void nv4LockUnlock
86 (
87 RIVA_HW_INST *chip,
88 int LockUnlock
89 )
90 {
91 VGA_WR08(chip->PCIO, 0x3D4, 0x1F);
92 VGA_WR08(chip->PCIO, 0x3D5, LockUnlock ? 0x99 : 0x57);
93 }
94 static void nv10LockUnlock
95 (
96 RIVA_HW_INST *chip,
97 int LockUnlock
98 )
99 {
100 VGA_WR08(chip->PCIO, 0x3D4, 0x1F);
101 VGA_WR08(chip->PCIO, 0x3D5, LockUnlock ? 0x99 : 0x57);
102 }
103
104 static int ShowHideCursor
105 (
106 RIVA_HW_INST *chip,
107 int ShowHide
108 )
109 {
110 int current;
111 current = chip->CurrentState->cursor1;
112 chip->CurrentState->cursor1 = (chip->CurrentState->cursor1 & 0xFE) |
113 (ShowHide & 0x01);
114 VGA_WR08(chip->PCIO, 0x3D4, 0x31);
115 VGA_WR08(chip->PCIO, 0x3D5, chip->CurrentState->cursor1);
116 return (current & 0x01);
117 }
118
119 /****************************************************************************\
120 * *
121 * The video arbitration routines calculate some "magic" numbers. Fixes *
122 * the snow seen when accessing the framebuffer without it. *
123 * It just works (I hope). *
124 * *
125 \****************************************************************************/
126
127 #define DEFAULT_GR_LWM 100
128 #define DEFAULT_VID_LWM 100
129 #define DEFAULT_GR_BURST_SIZE 256
130 #define DEFAULT_VID_BURST_SIZE 128
131 #define VIDEO 0
132 #define GRAPHICS 1
133 #define MPORT 2
134 #define ENGINE 3
135 #define GFIFO_SIZE 320
136 #define GFIFO_SIZE_128 256
137 #define MFIFO_SIZE 120
138 #define VFIFO_SIZE 256
139 #define ABS(a) (a>0?a:-a)
140 typedef struct {
141 int gdrain_rate;
142 int vdrain_rate;
143 int mdrain_rate;
144 int gburst_size;
145 int vburst_size;
146 char vid_en;
147 char gr_en;
148 int wcmocc, wcgocc, wcvocc, wcvlwm, wcglwm;
149 int by_gfacc;
150 char vid_only_once;
151 char gr_only_once;
152 char first_vacc;
153 char first_gacc;
154 char first_macc;
155 int vocc;
156 int gocc;
157 int mocc;
158 char cur;
159 char engine_en;
160 char converged;
161 int priority;
162 } nv3_arb_info;
163 typedef struct {
164 int graphics_lwm;
165 int video_lwm;
166 int graphics_burst_size;
167 int video_burst_size;
168 int graphics_hi_priority;
169 int media_hi_priority;
170 int rtl_values;
171 int valid;
172 } nv3_fifo_info;
173 typedef struct {
174 char pix_bpp;
175 char enable_video;
176 char gr_during_vid;
177 char enable_mp;
178 int memory_width;
179 int video_scale;
180 int pclk_khz;
181 int mclk_khz;
182 int mem_page_miss;
183 int mem_latency;
184 char mem_aligned;
185 } nv3_sim_state;
186 typedef struct {
187 int graphics_lwm;
188 int video_lwm;
189 int graphics_burst_size;
190 int video_burst_size;
191 int valid;
192 } nv4_fifo_info;
193 typedef struct {
194 int pclk_khz;
195 int mclk_khz;
196 int nvclk_khz;
197 char mem_page_miss;
198 char mem_latency;
199 int memory_width;
200 char enable_video;
201 char gr_during_vid;
202 char pix_bpp;
203 char mem_aligned;
204 char enable_mp;
205 } nv4_sim_state;
206 typedef struct {
207 int graphics_lwm;
208 int video_lwm;
209 int graphics_burst_size;
210 int video_burst_size;
211 int valid;
212 } nv10_fifo_info;
213 typedef struct {
214 int pclk_khz;
215 int mclk_khz;
216 int nvclk_khz;
217 char mem_page_miss;
218 char mem_latency;
219 int memory_type;
220 int memory_width;
221 char enable_video;
222 char gr_during_vid;
223 char pix_bpp;
224 char mem_aligned;
225 char enable_mp;
226 } nv10_sim_state;
227 static int nv3_iterate(nv3_fifo_info *res_info, nv3_sim_state * state, nv3_arb_info *ainfo)
228 {
229 int iter = 0;
230 int tmp;
231 int vfsize, mfsize, gfsize;
232 int mburst_size = 32;
233 int mmisses, gmisses, vmisses;
234 int misses;
235 int vlwm, glwm, mlwm;
236 int last, next, cur;
237 int max_gfsize ;
238 long ns;
239
240 vlwm = 0;
241 glwm = 0;
242 mlwm = 0;
243 vfsize = 0;
244 gfsize = 0;
245 cur = ainfo->cur;
246 mmisses = 2;
247 gmisses = 2;
248 vmisses = 2;
249 if (ainfo->gburst_size == 128) max_gfsize = GFIFO_SIZE_128;
250 else max_gfsize = GFIFO_SIZE;
251 max_gfsize = GFIFO_SIZE;
252 while (1)
253 {
254 if (ainfo->vid_en)
255 {
256 if (ainfo->wcvocc > ainfo->vocc) ainfo->wcvocc = ainfo->vocc;
257 if (ainfo->wcvlwm > vlwm) ainfo->wcvlwm = vlwm ;
258 ns = 1000000 * ainfo->vburst_size/(state->memory_width/8)/state->mclk_khz;
259 vfsize = ns * ainfo->vdrain_rate / 1000000;
260 vfsize = ainfo->wcvlwm - ainfo->vburst_size + vfsize;
261 }
262 if (state->enable_mp)
263 {
264 if (ainfo->wcmocc > ainfo->mocc) ainfo->wcmocc = ainfo->mocc;
265 }
266 if (ainfo->gr_en)
267 {
268 if (ainfo->wcglwm > glwm) ainfo->wcglwm = glwm ;
269 if (ainfo->wcgocc > ainfo->gocc) ainfo->wcgocc = ainfo->gocc;
270 ns = 1000000 * (ainfo->gburst_size/(state->memory_width/8))/state->mclk_khz;
271 gfsize = (ns * (long) ainfo->gdrain_rate)/1000000;
272 gfsize = ainfo->wcglwm - ainfo->gburst_size + gfsize;
273 }
274 mfsize = 0;
275 if (!state->gr_during_vid && ainfo->vid_en)
276 if (ainfo->vid_en && (ainfo->vocc < 0) && !ainfo->vid_only_once)
277 next = VIDEO;
278 else if (ainfo->mocc < 0)
279 next = MPORT;
280 else if (ainfo->gocc< ainfo->by_gfacc)
281 next = GRAPHICS;
282 else return (0);
283 else switch (ainfo->priority)
284 {
285 case VIDEO:
286 if (ainfo->vid_en && ainfo->vocc<0 && !ainfo->vid_only_once)
287 next = VIDEO;
288 else if (ainfo->gr_en && ainfo->gocc<0 && !ainfo->gr_only_once)
289 next = GRAPHICS;
290 else if (ainfo->mocc<0)
291 next = MPORT;
292 else return (0);
293 break;
294 case GRAPHICS:
295 if (ainfo->gr_en && ainfo->gocc<0 && !ainfo->gr_only_once)
296 next = GRAPHICS;
297 else if (ainfo->vid_en && ainfo->vocc<0 && !ainfo->vid_only_once)
298 next = VIDEO;
299 else if (ainfo->mocc<0)
300 next = MPORT;
301 else return (0);
302 break;
303 default:
304 if (ainfo->mocc<0)
305 next = MPORT;
306 else if (ainfo->gr_en && ainfo->gocc<0 && !ainfo->gr_only_once)
307 next = GRAPHICS;
308 else if (ainfo->vid_en && ainfo->vocc<0 && !ainfo->vid_only_once)
309 next = VIDEO;
310 else return (0);
311 break;
312 }
313 last = cur;
314 cur = next;
315 iter++;
316 switch (cur)
317 {
318 case VIDEO:
319 if (last==cur) misses = 0;
320 else if (ainfo->first_vacc) misses = vmisses;
321 else misses = 1;
322 ainfo->first_vacc = 0;
323 if (last!=cur)
324 {
325 ns = 1000000 * (vmisses*state->mem_page_miss + state->mem_latency)/state->mclk_khz;
326 vlwm = ns * ainfo->vdrain_rate/ 1000000;
327 vlwm = ainfo->vocc - vlwm;
328 }
329 ns = 1000000*(misses*state->mem_page_miss + ainfo->vburst_size)/(state->memory_width/8)/state->mclk_khz;
330 ainfo->vocc = ainfo->vocc + ainfo->vburst_size - ns*ainfo->vdrain_rate/1000000;
331 ainfo->gocc = ainfo->gocc - ns*ainfo->gdrain_rate/1000000;
332 ainfo->mocc = ainfo->mocc - ns*ainfo->mdrain_rate/1000000;
333 break;
334 case GRAPHICS:
335 if (last==cur) misses = 0;
336 else if (ainfo->first_gacc) misses = gmisses;
337 else misses = 1;
338 ainfo->first_gacc = 0;
339 if (last!=cur)
340 {
341 ns = 1000000*(gmisses*state->mem_page_miss + state->mem_latency)/state->mclk_khz ;
342 glwm = ns * ainfo->gdrain_rate/1000000;
343 glwm = ainfo->gocc - glwm;
344 }
345 ns = 1000000*(misses*state->mem_page_miss + ainfo->gburst_size/(state->memory_width/8))/state->mclk_khz;
346 ainfo->vocc = ainfo->vocc + 0 - ns*ainfo->vdrain_rate/1000000;
347 ainfo->gocc = ainfo->gocc + ainfo->gburst_size - ns*ainfo->gdrain_rate/1000000;
348 ainfo->mocc = ainfo->mocc + 0 - ns*ainfo->mdrain_rate/1000000;
349 break;
350 default:
351 if (last==cur) misses = 0;
352 else if (ainfo->first_macc) misses = mmisses;
353 else misses = 1;
354 ainfo->first_macc = 0;
355 ns = 1000000*(misses*state->mem_page_miss + mburst_size/(state->memory_width/8))/state->mclk_khz;
356 ainfo->vocc = ainfo->vocc + 0 - ns*ainfo->vdrain_rate/1000000;
357 ainfo->gocc = ainfo->gocc + 0 - ns*ainfo->gdrain_rate/1000000;
358 ainfo->mocc = ainfo->mocc + mburst_size - ns*ainfo->mdrain_rate/1000000;
359 break;
360 }
361 if (iter>100)
362 {
363 ainfo->converged = 0;
364 return (1);
365 }
366 ns = 1000000*ainfo->gburst_size/(state->memory_width/8)/state->mclk_khz;
367 tmp = ns * ainfo->gdrain_rate/1000000;
368 if (ABS(ainfo->gburst_size) + ((ABS(ainfo->wcglwm) + 16 ) & ~0x7) - tmp > max_gfsize)
369 {
370 ainfo->converged = 0;
371 return (1);
372 }
373 ns = 1000000*ainfo->vburst_size/(state->memory_width/8)/state->mclk_khz;
374 tmp = ns * ainfo->vdrain_rate/1000000;
375 if (ABS(ainfo->vburst_size) + (ABS(ainfo->wcvlwm + 32) & ~0xf) - tmp> VFIFO_SIZE)
376 {
377 ainfo->converged = 0;
378 return (1);
379 }
380 if (ABS(ainfo->gocc) > max_gfsize)
381 {
382 ainfo->converged = 0;
383 return (1);
384 }
385 if (ABS(ainfo->vocc) > VFIFO_SIZE)
386 {
387 ainfo->converged = 0;
388 return (1);
389 }
390 if (ABS(ainfo->mocc) > MFIFO_SIZE)
391 {
392 ainfo->converged = 0;
393 return (1);
394 }
395 if (ABS(vfsize) > VFIFO_SIZE)
396 {
397 ainfo->converged = 0;
398 return (1);
399 }
400 if (ABS(gfsize) > max_gfsize)
401 {
402 ainfo->converged = 0;
403 return (1);
404 }
405 if (ABS(mfsize) > MFIFO_SIZE)
406 {
407 ainfo->converged = 0;
408 return (1);
409 }
410 }
411 }
412 static char nv3_arb(nv3_fifo_info * res_info, nv3_sim_state * state, nv3_arb_info *ainfo)
413 {
414 long ens, vns, mns, gns;
415 int mmisses, gmisses, vmisses, eburst_size, mburst_size;
416 int refresh_cycle;
417
418 refresh_cycle = 0;
419 refresh_cycle = 2*(state->mclk_khz/state->pclk_khz) + 5;
420 mmisses = 2;
421 if (state->mem_aligned) gmisses = 2;
422 else gmisses = 3;
423 vmisses = 2;
424 eburst_size = state->memory_width * 1;
425 mburst_size = 32;
426 gns = 1000000 * (gmisses*state->mem_page_miss + state->mem_latency)/state->mclk_khz;
427 ainfo->by_gfacc = gns*ainfo->gdrain_rate/1000000;
428 ainfo->wcmocc = 0;
429 ainfo->wcgocc = 0;
430 ainfo->wcvocc = 0;
431 ainfo->wcvlwm = 0;
432 ainfo->wcglwm = 0;
433 ainfo->engine_en = 1;
434 ainfo->converged = 1;
435 if (ainfo->engine_en)
436 {
437 ens = 1000000*(state->mem_page_miss + eburst_size/(state->memory_width/8) +refresh_cycle)/state->mclk_khz;
438 ainfo->mocc = state->enable_mp ? 0-ens*ainfo->mdrain_rate/1000000 : 0;
439 ainfo->vocc = ainfo->vid_en ? 0-ens*ainfo->vdrain_rate/1000000 : 0;
440 ainfo->gocc = ainfo->gr_en ? 0-ens*ainfo->gdrain_rate/1000000 : 0;
441 ainfo->cur = ENGINE;
442 ainfo->first_vacc = 1;
443 ainfo->first_gacc = 1;
444 ainfo->first_macc = 1;
445 nv3_iterate(res_info, state,ainfo);
446 }
447 if (state->enable_mp)
448 {
449 mns = 1000000 * (mmisses*state->mem_page_miss + mburst_size/(state->memory_width/8) + refresh_cycle)/state->mclk_khz;
450 ainfo->mocc = state->enable_mp ? 0 : mburst_size - mns*ainfo->mdrain_rate/1000000;
451 ainfo->vocc = ainfo->vid_en ? 0 : 0- mns*ainfo->vdrain_rate/1000000;
452 ainfo->gocc = ainfo->gr_en ? 0: 0- mns*ainfo->gdrain_rate/1000000;
453 ainfo->cur = MPORT;
454 ainfo->first_vacc = 1;
455 ainfo->first_gacc = 1;
456 ainfo->first_macc = 0;
457 nv3_iterate(res_info, state,ainfo);
458 }
459 if (ainfo->gr_en)
460 {
461 ainfo->first_vacc = 1;
462 ainfo->first_gacc = 0;
463 ainfo->first_macc = 1;
464 gns = 1000000*(gmisses*state->mem_page_miss + ainfo->gburst_size/(state->memory_width/8) + refresh_cycle)/state->mclk_khz;
465 ainfo->gocc = ainfo->gburst_size - gns*ainfo->gdrain_rate/1000000;
466 ainfo->vocc = ainfo->vid_en? 0-gns*ainfo->vdrain_rate/1000000 : 0;
467 ainfo->mocc = state->enable_mp ? 0-gns*ainfo->mdrain_rate/1000000: 0;
468 ainfo->cur = GRAPHICS;
469 nv3_iterate(res_info, state,ainfo);
470 }
471 if (ainfo->vid_en)
472 {
473 ainfo->first_vacc = 0;
474 ainfo->first_gacc = 1;
475 ainfo->first_macc = 1;
476 vns = 1000000*(vmisses*state->mem_page_miss + ainfo->vburst_size/(state->memory_width/8) + refresh_cycle)/state->mclk_khz;
477 ainfo->vocc = ainfo->vburst_size - vns*ainfo->vdrain_rate/1000000;
478 ainfo->gocc = ainfo->gr_en? (0-vns*ainfo->gdrain_rate/1000000) : 0;
479 ainfo->mocc = state->enable_mp? 0-vns*ainfo->mdrain_rate/1000000 :0 ;
480 ainfo->cur = VIDEO;
481 nv3_iterate(res_info, state, ainfo);
482 }
483 if (ainfo->converged)
484 {
485 res_info->graphics_lwm = (int)ABS(ainfo->wcglwm) + 16;
486 res_info->video_lwm = (int)ABS(ainfo->wcvlwm) + 32;
487 res_info->graphics_burst_size = ainfo->gburst_size;
488 res_info->video_burst_size = ainfo->vburst_size;
489 res_info->graphics_hi_priority = (ainfo->priority == GRAPHICS);
490 res_info->media_hi_priority = (ainfo->priority == MPORT);
491 if (res_info->video_lwm > 160)
492 {
493 res_info->graphics_lwm = 256;
494 res_info->video_lwm = 128;
495 res_info->graphics_burst_size = 64;
496 res_info->video_burst_size = 64;
497 res_info->graphics_hi_priority = 0;
498 res_info->media_hi_priority = 0;
499 ainfo->converged = 0;
500 return (0);
501 }
502 if (res_info->video_lwm > 128)
503 {
504 res_info->video_lwm = 128;
505 }
506 return (1);
507 }
508 else
509 {
510 res_info->graphics_lwm = 256;
511 res_info->video_lwm = 128;
512 res_info->graphics_burst_size = 64;
513 res_info->video_burst_size = 64;
514 res_info->graphics_hi_priority = 0;
515 res_info->media_hi_priority = 0;
516 return (0);
517 }
518 }
519 static char nv3_get_param(nv3_fifo_info *res_info, nv3_sim_state * state, nv3_arb_info *ainfo)
520 {
521 int done, g,v, p;
522
523 done = 0;
524 for (p=0; p < 2; p++)
525 {
526 for (g=128 ; g > 32; g= g>> 1)
527 {
528 for (v=128; v >=32; v = v>> 1)
529 {
530 ainfo->priority = p;
531 ainfo->gburst_size = g;
532 ainfo->vburst_size = v;
533 done = nv3_arb(res_info, state,ainfo);
534 if (done && (g==128))
535 if ((res_info->graphics_lwm + g) > 256)
536 done = 0;
537 if (done)
538 goto Done;
539 }
540 }
541 }
542
543 Done:
544 return done;
545 }
546 static void nv3CalcArbitration
547 (
548 nv3_fifo_info * res_info,
549 nv3_sim_state * state
550 )
551 {
552 nv3_fifo_info save_info;
553 nv3_arb_info ainfo;
554 char res_gr, res_vid;
555
556 ainfo.gr_en = 1;
557 ainfo.vid_en = state->enable_video;
558 ainfo.vid_only_once = 0;
559 ainfo.gr_only_once = 0;
560 ainfo.gdrain_rate = (int) state->pclk_khz * (state->pix_bpp/8);
561 ainfo.vdrain_rate = (int) state->pclk_khz * 2;
562 if (state->video_scale != 0)
563 ainfo.vdrain_rate = ainfo.vdrain_rate/state->video_scale;
564 ainfo.mdrain_rate = 33000;
565 res_info->rtl_values = 0;
566 if (!state->gr_during_vid && state->enable_video)
567 {
568 ainfo.gr_only_once = 1;
569 ainfo.gr_en = 1;
570 ainfo.gdrain_rate = 0;
571 res_vid = nv3_get_param(res_info, state, &ainfo);
572 res_vid = ainfo.converged;
573 save_info.video_lwm = res_info->video_lwm;
574 save_info.video_burst_size = res_info->video_burst_size;
575 ainfo.vid_en = 1;
576 ainfo.vid_only_once = 1;
577 ainfo.gr_en = 1;
578 ainfo.gdrain_rate = (int) state->pclk_khz * (state->pix_bpp/8);
579 ainfo.vdrain_rate = 0;
580 res_gr = nv3_get_param(res_info, state, &ainfo);
581 res_gr = ainfo.converged;
582 res_info->video_lwm = save_info.video_lwm;
583 res_info->video_burst_size = save_info.video_burst_size;
584 res_info->valid = res_gr & res_vid;
585 }
586 else
587 {
588 if (!ainfo.gr_en) ainfo.gdrain_rate = 0;
589 if (!ainfo.vid_en) ainfo.vdrain_rate = 0;
590 res_gr = nv3_get_param(res_info, state, &ainfo);
591 res_info->valid = ainfo.converged;
592 }
593 }
594 static void nv3UpdateArbitrationSettings
595 (
596 unsigned VClk,
597 unsigned pixelDepth,
598 unsigned *burst,
599 unsigned *lwm,
600 RIVA_HW_INST *chip
601 )
602 {
603 nv3_fifo_info fifo_data;
604 nv3_sim_state sim_data;
605 unsigned int M, N, P, pll, MClk;
606
607 pll = chip->PRAMDAC[0x00000504/4];
608 M = (pll >> 0) & 0xFF; N = (pll >> 8) & 0xFF; P = (pll >> 16) & 0x0F;
609 MClk = (N * chip->CrystalFreqKHz / M) >> P;
610 sim_data.pix_bpp = (char)pixelDepth;
611 sim_data.enable_video = 0;
612 sim_data.enable_mp = 0;
613 sim_data.video_scale = 1;
614 sim_data.memory_width = (chip->PEXTDEV[0x00000000/4] & 0x10) ? 128 : 64;
615 sim_data.memory_width = 128;
616
617 sim_data.mem_latency = 9;
618 sim_data.mem_aligned = 1;
619 sim_data.mem_page_miss = 11;
620 sim_data.gr_during_vid = 0;
621 sim_data.pclk_khz = VClk;
622 sim_data.mclk_khz = MClk;
623 nv3CalcArbitration(&fifo_data, &sim_data);
624 if (fifo_data.valid)
625 {
626 int b = fifo_data.graphics_burst_size >> 4;
627 *burst = 0;
628 while (b >>= 1) (*burst)++;
629 *lwm = fifo_data.graphics_lwm >> 3;
630 }
631 else
632 {
633 *lwm = 0x24;
634 *burst = 0x2;
635 }
636 }
637 static void nv4CalcArbitration
638 (
639 nv4_fifo_info *fifo,
640 nv4_sim_state *arb
641 )
642 {
643 int data, pagemiss, cas,width, video_enable, color_key_enable, bpp, align;
644 int nvclks, mclks, pclks, vpagemiss, crtpagemiss, vbs;
645 int found, mclk_extra, mclk_loop, cbs, m1, p1;
646 int mclk_freq, pclk_freq, nvclk_freq, mp_enable;
647 int us_m, us_n, us_p, video_drain_rate, crtc_drain_rate;
648 int vpm_us, us_video, vlwm, video_fill_us, cpm_us, us_crt,clwm;
649 int craw, vraw;
650
651 fifo->valid = 1;
652 pclk_freq = arb->pclk_khz;
653 mclk_freq = arb->mclk_khz;
654 nvclk_freq = arb->nvclk_khz;
655 pagemiss = arb->mem_page_miss;
656 cas = arb->mem_latency;
657 width = arb->memory_width >> 6;
658 video_enable = arb->enable_video;
659 color_key_enable = arb->gr_during_vid;
660 bpp = arb->pix_bpp;
661 align = arb->mem_aligned;
662 mp_enable = arb->enable_mp;
663 clwm = 0;
664 vlwm = 0;
665 cbs = 128;
666 pclks = 2;
667 nvclks = 2;
668 nvclks += 2;
669 nvclks += 1;
670 mclks = 5;
671 mclks += 3;
672 mclks += 1;
673 mclks += cas;
674 mclks += 1;
675 mclks += 1;
676 mclks += 1;
677 mclks += 1;
678 mclk_extra = 3;
679 nvclks += 2;
680 nvclks += 1;
681 nvclks += 1;
682 nvclks += 1;
683 if (mp_enable)
684 mclks+=4;
685 nvclks += 0;
686 pclks += 0;
687 found = 0;
688 vbs = 0;
689 while (found != 1)
690 {
691 fifo->valid = 1;
692 found = 1;
693 mclk_loop = mclks+mclk_extra;
694 us_m = mclk_loop *1000*1000 / mclk_freq;
695 us_n = nvclks*1000*1000 / nvclk_freq;
696 us_p = nvclks*1000*1000 / pclk_freq;
697 if (video_enable)
698 {
699 video_drain_rate = pclk_freq * 2;
700 crtc_drain_rate = pclk_freq * bpp/8;
701 vpagemiss = 2;
702 vpagemiss += 1;
703 crtpagemiss = 2;
704 vpm_us = (vpagemiss * pagemiss)*1000*1000/mclk_freq;
705 if (nvclk_freq * 2 > mclk_freq * width)
706 video_fill_us = cbs*1000*1000 / 16 / nvclk_freq ;
707 else
708 video_fill_us = cbs*1000*1000 / (8 * width) / mclk_freq;
709 us_video = vpm_us + us_m + us_n + us_p + video_fill_us;
710 vlwm = us_video * video_drain_rate/(1000*1000);
711 vlwm++;
712 vbs = 128;
713 if (vlwm > 128) vbs = 64;
714 if (vlwm > (256-64)) vbs = 32;
715 if (nvclk_freq * 2 > mclk_freq * width)
716 video_fill_us = vbs *1000*1000/ 16 / nvclk_freq ;
717 else
718 video_fill_us = vbs*1000*1000 / (8 * width) / mclk_freq;
719 cpm_us = crtpagemiss * pagemiss *1000*1000/ mclk_freq;
720 us_crt =
721 us_video
722 +video_fill_us
723 +cpm_us
724 +us_m + us_n +us_p
725 ;
726 clwm = us_crt * crtc_drain_rate/(1000*1000);
727 clwm++;
728 }
729 else
730 {
731 crtc_drain_rate = pclk_freq * bpp/8;
732 crtpagemiss = 2;
733 crtpagemiss += 1;
734 cpm_us = crtpagemiss * pagemiss *1000*1000/ mclk_freq;
735 us_crt = cpm_us + us_m + us_n + us_p ;
736 clwm = us_crt * crtc_drain_rate/(1000*1000);
737 clwm++;
738 }
739 m1 = clwm + cbs - 512;
740 p1 = m1 * pclk_freq / mclk_freq;
741 p1 = p1 * bpp / 8;
742 if ((p1 < m1) && (m1 > 0))
743 {
744 fifo->valid = 0;
745 found = 0;
746 if (mclk_extra ==0) found = 1;
747 mclk_extra--;
748 }
749 else if (video_enable)
750 {
751 if ((clwm > 511) || (vlwm > 255))
752 {
753 fifo->valid = 0;
754 found = 0;
755 if (mclk_extra ==0) found = 1;
756 mclk_extra--;
757 }
758 }
759 else
760 {
761 if (clwm > 519)
762 {
763 fifo->valid = 0;
764 found = 0;
765 if (mclk_extra ==0) found = 1;
766 mclk_extra--;
767 }
768 }
769 craw = clwm;
770 vraw = vlwm;
771 if (clwm < 384) clwm = 384;
772 if (vlwm < 128) vlwm = 128;
773 data = (int)(clwm);
774 fifo->graphics_lwm = data;
775 fifo->graphics_burst_size = 128;
776 data = (int)((vlwm+15));
777 fifo->video_lwm = data;
778 fifo->video_burst_size = vbs;
779 }
780 }
781 static void nv4UpdateArbitrationSettings
782 (
783 unsigned VClk,
784 unsigned pixelDepth,
785 unsigned *burst,
786 unsigned *lwm,
787 RIVA_HW_INST *chip
788 )
789 {
790 nv4_fifo_info fifo_data;
791 nv4_sim_state sim_data;
792 unsigned int M, N, P, pll, MClk, NVClk, cfg1;
793
794 pll = chip->PRAMDAC[0x00000504/4];
795 M = (pll >> 0) & 0xFF; N = (pll >> 8) & 0xFF; P = (pll >> 16) & 0x0F;
796 MClk = (N * chip->CrystalFreqKHz / M) >> P;
797 pll = chip->PRAMDAC[0x00000500/4];
798 M = (pll >> 0) & 0xFF; N = (pll >> 8) & 0xFF; P = (pll >> 16) & 0x0F;
799 NVClk = (N * chip->CrystalFreqKHz / M) >> P;
800 cfg1 = chip->PFB[0x00000204/4];
801 sim_data.pix_bpp = (char)pixelDepth;
802 sim_data.enable_video = 0;
803 sim_data.enable_mp = 0;
804 sim_data.memory_width = (chip->PEXTDEV[0x00000000/4] & 0x10) ? 128 : 64;
805 sim_data.mem_latency = (char)cfg1 & 0x0F;
806 sim_data.mem_aligned = 1;
807 sim_data.mem_page_miss = (char)(((cfg1 >> 4) &0x0F) + ((cfg1 >> 31) & 0x01));
808 sim_data.gr_during_vid = 0;
809 sim_data.pclk_khz = VClk;
810 sim_data.mclk_khz = MClk;
811 sim_data.nvclk_khz = NVClk;
812 nv4CalcArbitration(&fifo_data, &sim_data);
813 if (fifo_data.valid)
814 {
815 int b = fifo_data.graphics_burst_size >> 4;
816 *burst = 0;
817 while (b >>= 1) (*burst)++;
818 *lwm = fifo_data.graphics_lwm >> 3;
819 }
820 }
821 static void nv10CalcArbitration
822 (
823 nv10_fifo_info *fifo,
824 nv10_sim_state *arb
825 )
826 {
827 int data, pagemiss, cas,width, video_enable, color_key_enable, bpp, align;
828 int nvclks, mclks, pclks, vpagemiss, crtpagemiss, vbs;
829 int nvclk_fill, us_extra;
830 int found, mclk_extra, mclk_loop, cbs, m1;
831 int mclk_freq, pclk_freq, nvclk_freq, mp_enable;
832 int us_m, us_m_min, us_n, us_p, video_drain_rate, crtc_drain_rate;
833 int vus_m, vus_n, vus_p;
834 int vpm_us, us_video, vlwm, cpm_us, us_crt,clwm;
835 int clwm_rnd_down;
836 int craw, m2us, us_pipe, us_pipe_min, vus_pipe, p1clk, p2;
837 int pclks_2_top_fifo, min_mclk_extra;
838 int us_min_mclk_extra;
839
840 fifo->valid = 1;
841 pclk_freq = arb->pclk_khz; /* freq in KHz */
842 mclk_freq = arb->mclk_khz;
843 nvclk_freq = arb->nvclk_khz;
844 pagemiss = arb->mem_page_miss;
845 cas = arb->mem_latency;
846 width = arb->memory_width/64;
847 video_enable = arb->enable_video;
848 color_key_enable = arb->gr_during_vid;
849 bpp = arb->pix_bpp;
850 align = arb->mem_aligned;
851 mp_enable = arb->enable_mp;
852 clwm = 0;
853 vlwm = 1024;
854
855 cbs = 512;
856 vbs = 512;
857
858 pclks = 4; /* lwm detect. */
859
860 nvclks = 3; /* lwm -> sync. */
861 nvclks += 2; /* fbi bus cycles (1 req + 1 busy) */
862
863 mclks = 1; /* 2 edge sync. may be very close to edge so just put one. */
864
865 mclks += 1; /* arb_hp_req */
866 mclks += 5; /* ap_hp_req tiling pipeline */
867
868 mclks += 2; /* tc_req latency fifo */
869 mclks += 2; /* fb_cas_n_ memory request to fbio block */
870 mclks += 7; /* sm_d_rdv data returned from fbio block */
871
872 /* fb.rd.d.Put_gc need to accumulate 256 bits for read */
873 if (arb->memory_type == 0)
874 if (arb->memory_width == 64) /* 64 bit bus */
875 mclks += 4;
876 else
877 mclks += 2;
878 else
879 if (arb->memory_width == 64) /* 64 bit bus */
880 mclks += 2;
881 else
882 mclks += 1;
883
884 if ((!video_enable) && (arb->memory_width == 128))
885 {
886 mclk_extra = (bpp == 32) ? 31 : 42; /* Margin of error */
887 min_mclk_extra = 17;
888 }
889 else
890 {
891 mclk_extra = (bpp == 32) ? 8 : 4; /* Margin of error */
892 /* mclk_extra = 4; */ /* Margin of error */
893 min_mclk_extra = 18;
894 }
895
896 nvclks += 1; /* 2 edge sync. may be very close to edge so just put one. */
897 nvclks += 1; /* fbi_d_rdv_n */
898 nvclks += 1; /* Fbi_d_rdata */
899 nvclks += 1; /* crtfifo load */
900
901 if(mp_enable)
902 mclks+=4; /* Mp can get in with a burst of 8. */
903 /* Extra clocks determined by heuristics */
904
905 nvclks += 0;
906 pclks += 0;
907 found = 0;
908 while(found != 1) {
909 fifo->valid = 1;
910 found = 1;
911 mclk_loop = mclks+mclk_extra;
912 us_m = mclk_loop *1000*1000 / mclk_freq; /* Mclk latency in us */
913 us_m_min = mclks * 1000*1000 / mclk_freq; /* Minimum Mclk latency in us */
914 us_min_mclk_extra = min_mclk_extra *1000*1000 / mclk_freq;
915 us_n = nvclks*1000*1000 / nvclk_freq;/* nvclk latency in us */
916 us_p = pclks*1000*1000 / pclk_freq;/* nvclk latency in us */
917 us_pipe = us_m + us_n + us_p;
918 us_pipe_min = us_m_min + us_n + us_p;
919 us_extra = 0;
920
921 vus_m = mclk_loop *1000*1000 / mclk_freq; /* Mclk latency in us */
922 vus_n = (4)*1000*1000 / nvclk_freq;/* nvclk latency in us */
923 vus_p = 0*1000*1000 / pclk_freq;/* pclk latency in us */
924 vus_pipe = vus_m + vus_n + vus_p;
925
926 if(video_enable) {
927 video_drain_rate = pclk_freq * 4; /* MB/s */
928 crtc_drain_rate = pclk_freq * bpp/8; /* MB/s */
929
930 vpagemiss = 1; /* self generating page miss */
931 vpagemiss += 1; /* One higher priority before */
932
933 crtpagemiss = 2; /* self generating page miss */
934 if(mp_enable)
935 crtpagemiss += 1; /* if MA0 conflict */
936
937 vpm_us = (vpagemiss * pagemiss)*1000*1000/mclk_freq;
938
939 us_video = vpm_us + vus_m; /* Video has separate read return path */
940
941 cpm_us = crtpagemiss * pagemiss *1000*1000/ mclk_freq;
942 us_crt =
943 us_video /* Wait for video */
944 +cpm_us /* CRT Page miss */
945 +us_m + us_n +us_p /* other latency */
946 ;
947
948 clwm = us_crt * crtc_drain_rate/(1000*1000);
949 clwm++; /* fixed point <= float_point - 1. Fixes that */
950 } else {
951 crtc_drain_rate = pclk_freq * bpp/8; /* bpp * pclk/8 */
952
953 crtpagemiss = 1; /* self generating page miss */
954 crtpagemiss += 1; /* MA0 page miss */
955 if(mp_enable)
956 crtpagemiss += 1; /* if MA0 conflict */
957 cpm_us = crtpagemiss * pagemiss *1000*1000/ mclk_freq;
958 us_crt = cpm_us + us_m + us_n + us_p ;
959 clwm = us_crt * crtc_drain_rate/(1000*1000);
960 clwm++; /* fixed point <= float_point - 1. Fixes that */
961
962 /*
963 //
964 // Another concern, only for high pclks so don't do this
965 // with video:
966 // What happens if the latency to fetch the cbs is so large that
967 // fifo empties. In that case we need to have an alternate clwm value
968 // based off the total burst fetch
969 //
970 us_crt = (cbs * 1000 * 1000)/ (8*width)/mclk_freq ;
971 us_crt = us_crt + us_m + us_n + us_p + (4 * 1000 * 1000)/mclk_freq;
972 clwm_mt = us_crt * crtc_drain_rate/(1000*1000);
973 clwm_mt ++;
974 if(clwm_mt > clwm)
975 clwm = clwm_mt;
976 */
977 /* Finally, a heuristic check when width == 64 bits */
978 if(width == 1){
979 nvclk_fill = nvclk_freq * 8;
980 if(crtc_drain_rate * 100 >= nvclk_fill * 102)
981 clwm = 0xfff; /*Large number to fail */
982
983 else if(crtc_drain_rate * 100 >= nvclk_fill * 98) {
984 clwm = 1024;
985 cbs = 512;
986 us_extra = (cbs * 1000 * 1000)/ (8*width)/mclk_freq ;
987 }
988 }
989 }
990
991
992 /*
993 Overfill check:
994
995 */
996
997 clwm_rnd_down = ((int)clwm/8)*8;
998 if (clwm_rnd_down < clwm)
999 clwm += 8;
1000
1001 m1 = clwm + cbs - 1024; /* Amount of overfill */
1002 m2us = us_pipe_min + us_min_mclk_extra;
1003 pclks_2_top_fifo = (1024-clwm)/(8*width);
1004
1005 /* pclk cycles to drain */
1006 p1clk = m2us * pclk_freq/(1000*1000);
1007 p2 = p1clk * bpp / 8; /* bytes drained. */
1008
1009 if((p2 < m1) && (m1 > 0)) {
1010 fifo->valid = 0;
1011 found = 0;
1012 if(min_mclk_extra == 0) {
1013 if(cbs <= 32) {
1014 found = 1; /* Can't adjust anymore! */
1015 } else {
1016 cbs = cbs/2; /* reduce the burst size */
1017 }
1018 } else {
1019 min_mclk_extra--;
1020 }
1021 } else {
1022 if (clwm > 1023){ /* Have some margin */
1023 fifo->valid = 0;
1024 found = 0;
1025 if(min_mclk_extra == 0)
1026 found = 1; /* Can't adjust anymore! */
1027 else
1028 min_mclk_extra--;
1029 }
1030 }
1031 craw = clwm;
1032
1033 if(clwm < (1024-cbs+8)) clwm = 1024-cbs+8;
1034 data = (int)(clwm);
1035 /* printf("CRT LWM: %f bytes, prog: 0x%x, bs: 256\n", clwm, data ); */
1036 fifo->graphics_lwm = data; fifo->graphics_burst_size = cbs;
1037
1038 /* printf("VID LWM: %f bytes, prog: 0x%x, bs: %d\n, ", vlwm, data, vbs ); */
1039 fifo->video_lwm = 1024; fifo->video_burst_size = 512;
1040 }
1041 }
1042 static void nv10UpdateArbitrationSettings
1043 (
1044 unsigned VClk,
1045 unsigned pixelDepth,
1046 unsigned *burst,
1047 unsigned *lwm,
1048 RIVA_HW_INST *chip
1049 )
1050 {
1051 nv10_fifo_info fifo_data;
1052 nv10_sim_state sim_data;
1053 unsigned int M, N, P, pll, MClk, NVClk, cfg1;
1054
1055 pll = chip->PRAMDAC[0x00000504/4];
1056 M = (pll >> 0) & 0xFF; N = (pll >> 8) & 0xFF; P = (pll >> 16) & 0x0F;
1057 MClk = (N * chip->CrystalFreqKHz / M) >> P;
1058 pll = chip->PRAMDAC[0x00000500/4];
1059 M = (pll >> 0) & 0xFF; N = (pll >> 8) & 0xFF; P = (pll >> 16) & 0x0F;
1060 NVClk = (N * chip->CrystalFreqKHz / M) >> P;
1061 cfg1 = chip->PFB[0x00000204/4];
1062 sim_data.pix_bpp = (char)pixelDepth;
1063 sim_data.enable_video = 0;
1064 sim_data.enable_mp = 0;
1065 sim_data.memory_type = (chip->PFB[0x00000200/4] & 0x01) ? 1 : 0;
1066 sim_data.memory_width = (chip->PEXTDEV[0x00000000/4] & 0x10) ? 128 : 64;
1067 sim_data.mem_latency = (char)cfg1 & 0x0F;
1068 sim_data.mem_aligned = 1;
1069 sim_data.mem_page_miss = (char)(((cfg1 >> 4) &0x0F) + ((cfg1 >> 31) & 0x01));
1070 sim_data.gr_during_vid = 0;
1071 sim_data.pclk_khz = VClk;
1072 sim_data.mclk_khz = MClk;
1073 sim_data.nvclk_khz = NVClk;
1074 nv10CalcArbitration(&fifo_data, &sim_data);
1075 if (fifo_data.valid)
1076 {
1077 int b = fifo_data.graphics_burst_size >> 4;
1078 *burst = 0;
1079 while (b >>= 1) (*burst)++;
1080 *lwm = fifo_data.graphics_lwm >> 3;
1081 }
1082 }
1083
1084 /****************************************************************************\
1085 * *
1086 * RIVA Mode State Routines *
1087 * *
1088 \****************************************************************************/
1089
1090 /*
1091 * Calculate the Video Clock parameters for the PLL.
1092 */
1093 static int CalcVClock
1094 (
1095 int clockIn,
1096 int double_scan,
1097 int *clockOut,
1098 int *mOut,
1099 int *nOut,
1100 int *pOut,
1101 RIVA_HW_INST *chip
1102 )
1103 {
1104 unsigned lowM, highM, highP;
1105 unsigned DeltaNew, DeltaOld;
1106 unsigned VClk, Freq;
1107 unsigned M, N, P;
1108
1109 DeltaOld = 0xFFFFFFFF;
1110
1111 VClk = (unsigned)clockIn;
1112 if (double_scan)
1113 VClk *= 2;
1114
1115 if (chip->CrystalFreqKHz == 14318)
1116 {
1117 lowM = 8;
1118 highM = 14 - (chip->Architecture == NV_ARCH_03);
1119 }
1120 else
1121 {
1122 lowM = 7;
1123 highM = 13 - (chip->Architecture == NV_ARCH_03);
1124 }
1125
1126 highP = 4 - (chip->Architecture == NV_ARCH_03);
1127 for (P = 0; P <= highP; P ++)
1128 {
1129 Freq = VClk << P;
1130 if ((Freq >= 128000) && (Freq <= chip->MaxVClockFreqKHz))
1131 {
1132 for (M = lowM; M <= highM; M++)
1133 {
1134 N = (VClk * M / chip->CrystalFreqKHz) << P;
1135 Freq = (chip->CrystalFreqKHz * N / M) >> P;
1136 if (Freq > VClk)
1137 DeltaNew = Freq - VClk;
1138 else
1139 DeltaNew = VClk - Freq;
1140 if (DeltaNew < DeltaOld)
1141 {
1142 *mOut = M;
1143 *nOut = N;
1144 *pOut = P;
1145 *clockOut = Freq;
1146 DeltaOld = DeltaNew;
1147 }
1148 }
1149 }
1150 }
1151 return (DeltaOld != 0xFFFFFFFF);
1152 }
1153 /*
1154 * Calculate extended mode parameters (SVGA) and save in a
1155 * mode state structure.
1156 */
1157 static void CalcStateExt
1158 (
1159 RIVA_HW_INST *chip,
1160 RIVA_HW_STATE *state,
1161 int bpp,
1162 int width,
1163 int hDisplaySize,
1164 int hDisplay,
1165 int hStart,
1166 int hEnd,
1167 int hTotal,
1168 int height,
1169 int vDisplay,
1170 int vStart,
1171 int vEnd,
1172 int vTotal,
1173 int dotClock
1174 )
1175 {
1176 int pixelDepth, VClk, m, n, p;
1177 /*
1178 * Save mode parameters.
1179 */
1180 state->bpp = bpp;
1181 state->width = width;
1182 state->height = height;
1183 /*
1184 * Extended RIVA registers.
1185 */
1186 pixelDepth = (bpp + 1)/8;
1187 CalcVClock(dotClock, hDisplaySize < 512, /* double scan? */
1188 &VClk, &m, &n, &p, chip);
1189
1190 switch (chip->Architecture)
1191 {
1192 case NV_ARCH_03:
1193 nv3UpdateArbitrationSettings(VClk,
1194 pixelDepth * 8,
1195 &(state->arbitration0),
1196 &(state->arbitration1),
1197 chip);
1198 state->cursor0 = 0x00;
1199 state->cursor1 = 0x78;
1200 state->cursor2 = 0x00000000;
1201 state->pllsel = 0x10010100;
1202 state->config = ((width + 31)/32)
1203 | (((pixelDepth > 2) ? 3 : pixelDepth) << 8)
1204 | 0x1000;
1205 state->general = 0x00100100;
1206 state->repaint1 = hDisplaySize < 1280 ? 0x06 : 0x02;
1207 break;
1208 case NV_ARCH_04:
1209 nv4UpdateArbitrationSettings(VClk,
1210 pixelDepth * 8,
1211 &(state->arbitration0),
1212 &(state->arbitration1),
1213 chip);
1214 state->cursor0 = 0x00;
1215 state->cursor1 = 0xFC;
1216 state->cursor2 = 0x00000000;
1217 state->pllsel = 0x10000700;
1218 state->config = 0x00001114;
1219 state->general = bpp == 16 ? 0x00101100 : 0x00100100;
1220 state->repaint1 = hDisplaySize < 1280 ? 0x04 : 0x00;
1221 break;
1222 case NV_ARCH_10:
1223 nv10UpdateArbitrationSettings(VClk,
1224 pixelDepth * 8,
1225 &(state->arbitration0),
1226 &(state->arbitration1),
1227 chip);
1228 state->cursor0 = 0x00;
1229 state->cursor1 = 0xFC;
1230 state->cursor2 = 0x00000000;
1231 state->pllsel = 0x10000700;
1232 state->config = chip->PFB[0x00000200/4];
1233 state->general = bpp == 16 ? 0x00101100 : 0x00100100;
1234 state->repaint1 = hDisplaySize < 1280 ? 0x04 : 0x00;
1235 break;
1236 }
1237 state->vpll = (p << 16) | (n << 8) | m;
1238 state->screen = ((hTotal & 0x040) >> 2)
1239 | ((vDisplay & 0x400) >> 7)
1240 | ((vStart & 0x400) >> 8)
1241 | ((vDisplay & 0x400) >> 9)
1242 | ((vTotal & 0x400) >> 10);
1243 state->repaint0 = (((width/8)*pixelDepth) & 0x700) >> 3;
1244 state->horiz = hTotal < 260 ? 0x00 : 0x01;
1245 state->pixel = pixelDepth > 2 ? 3 : pixelDepth;
1246 state->offset0 =
1247 state->offset1 =
1248 state->offset2 =
1249 state->offset3 = 0;
1250 state->pitch0 =
1251 state->pitch1 =
1252 state->pitch2 =
1253 state->pitch3 = pixelDepth * width;
1254 }
1255 /*
1256 * Load fixed function state and pre-calculated/stored state.
1257 */
1258 #define LOAD_FIXED_STATE(tbl,dev) \
1259 for (i = 0; i < sizeof(tbl##Table##dev)/8; i++) \
1260 chip->dev[tbl##Table##dev[i][0]] = tbl##Table##dev[i][1]
1261 #define LOAD_FIXED_STATE_8BPP(tbl,dev) \
1262 for (i = 0; i < sizeof(tbl##Table##dev##_8BPP)/8; i++) \
1263 chip->dev[tbl##Table##dev##_8BPP[i][0]] = tbl##Table##dev##_8BPP[i][1]
1264 #define LOAD_FIXED_STATE_15BPP(tbl,dev) \
1265 for (i = 0; i < sizeof(tbl##Table##dev##_15BPP)/8; i++) \
1266 chip->dev[tbl##Table##dev##_15BPP[i][0]] = tbl##Table##dev##_15BPP[i][1]
1267 #define LOAD_FIXED_STATE_16BPP(tbl,dev) \
1268 for (i = 0; i < sizeof(tbl##Table##dev##_16BPP)/8; i++) \
1269 chip->dev[tbl##Table##dev##_16BPP[i][0]] = tbl##Table##dev##_16BPP[i][1]
1270 #define LOAD_FIXED_STATE_32BPP(tbl,dev) \
1271 for (i = 0; i < sizeof(tbl##Table##dev##_32BPP)/8; i++) \
1272 chip->dev[tbl##Table##dev##_32BPP[i][0]] = tbl##Table##dev##_32BPP[i][1]
1273 static void UpdateFifoState
1274 (
1275 RIVA_HW_INST *chip
1276 )
1277 {
1278 int i;
1279
1280 switch (chip->Architecture)
1281 {
1282 case NV_ARCH_04:
1283 LOAD_FIXED_STATE(nv4,FIFO);
1284 chip->Tri03 = 0L;
1285 chip->Tri05 = (RivaTexturedTriangle05 *)&(chip->FIFO[0x0000E000/4]);
1286 break;
1287 case NV_ARCH_10:
1288 /*
1289 * Initialize state for the RivaTriangle3D05 routines.
1290 */
1291 LOAD_FIXED_STATE(nv10tri05,PGRAPH);
1292 LOAD_FIXED_STATE(nv10,FIFO);
1293 chip->Tri03 = 0L;
1294 chip->Tri05 = (RivaTexturedTriangle05 *)&(chip->FIFO[0x0000E000/4]);
1295 break;
1296 }
1297 }
1298 static void LoadStateExt
1299 (
1300 RIVA_HW_INST *chip,
1301 RIVA_HW_STATE *state
1302 )
1303 {
1304 int i;
1305
1306 /*
1307 * Load HW fixed function state.
1308 */
1309 LOAD_FIXED_STATE(Riva,PMC);
1310 LOAD_FIXED_STATE(Riva,PTIMER);
1311 switch (chip->Architecture)
1312 {
1313 case NV_ARCH_03:
1314 /*
1315 * Make sure frame buffer config gets set before loading PRAMIN.
1316 */
1317 chip->PFB[0x00000200/4] = state->config;
1318 LOAD_FIXED_STATE(nv3,PFIFO);
1319 LOAD_FIXED_STATE(nv3,PRAMIN);
1320 LOAD_FIXED_STATE(nv3,PGRAPH);
1321 switch (state->bpp)
1322 {
1323 case 15:
1324 case 16:
1325 LOAD_FIXED_STATE_15BPP(nv3,PRAMIN);
1326 LOAD_FIXED_STATE_15BPP(nv3,PGRAPH);
1327 chip->Tri03 = (RivaTexturedTriangle03 *)&(chip->FIFO[0x0000E000/4]);
1328 break;
1329 case 24:
1330 case 32:
1331 LOAD_FIXED_STATE_32BPP(nv3,PRAMIN);
1332 LOAD_FIXED_STATE_32BPP(nv3,PGRAPH);
1333 chip->Tri03 = 0L;
1334 break;
1335 case 8:
1336 default:
1337 LOAD_FIXED_STATE_8BPP(nv3,PRAMIN);
1338 LOAD_FIXED_STATE_8BPP(nv3,PGRAPH);
1339 chip->Tri03 = 0L;
1340 break;
1341 }
1342 for (i = 0x00000; i < 0x00800; i++)
1343 chip->PRAMIN[0x00000502 + i] = (i << 12) | 0x03;
1344 chip->PGRAPH[0x00000630/4] = state->offset0;
1345 chip->PGRAPH[0x00000634/4] = state->offset1;
1346 chip->PGRAPH[0x00000638/4] = state->offset2;
1347 chip->PGRAPH[0x0000063C/4] = state->offset3;
1348 chip->PGRAPH[0x00000650/4] = state->pitch0;
1349 chip->PGRAPH[0x00000654/4] = state->pitch1;
1350 chip->PGRAPH[0x00000658/4] = state->pitch2;
1351 chip->PGRAPH[0x0000065C/4] = state->pitch3;
1352 break;
1353 case NV_ARCH_04:
1354 /*
1355 * Make sure frame buffer config gets set before loading PRAMIN.
1356 */
1357 chip->PFB[0x00000200/4] = state->config;
1358 LOAD_FIXED_STATE(nv4,PFIFO);
1359 LOAD_FIXED_STATE(nv4,PRAMIN);
1360 LOAD_FIXED_STATE(nv4,PGRAPH);
1361 switch (state->bpp)
1362 {
1363 case 15:
1364 LOAD_FIXED_STATE_15BPP(nv4,PRAMIN);
1365 LOAD_FIXED_STATE_15BPP(nv4,PGRAPH);
1366 chip->Tri03 = (RivaTexturedTriangle03 *)&(chip->FIFO[0x0000E000/4]);
1367 break;
1368 case 16:
1369 LOAD_FIXED_STATE_16BPP(nv4,PRAMIN);
1370 LOAD_FIXED_STATE_16BPP(nv4,PGRAPH);
1371 chip->Tri03 = (RivaTexturedTriangle03 *)&(chip->FIFO[0x0000E000/4]);
1372 break;
1373 case 24:
1374 case 32:
1375 LOAD_FIXED_STATE_32BPP(nv4,PRAMIN);
1376 LOAD_FIXED_STATE_32BPP(nv4,PGRAPH);
1377 chip->Tri03 = 0L;
1378 break;
1379 case 8:
1380 default:
1381 LOAD_FIXED_STATE_8BPP(nv4,PRAMIN);
1382 LOAD_FIXED_STATE_8BPP(nv4,PGRAPH);
1383 chip->Tri03 = 0L;
1384 break;
1385 }
1386 chip->PGRAPH[0x00000640/4] = state->offset0;
1387 chip->PGRAPH[0x00000644/4] = state->offset1;
1388 chip->PGRAPH[0x00000648/4] = state->offset2;
1389 chip->PGRAPH[0x0000064C/4] = state->offset3;
1390 chip->PGRAPH[0x00000670/4] = state->pitch0;
1391 chip->PGRAPH[0x00000674/4] = state->pitch1;
1392 chip->PGRAPH[0x00000678/4] = state->pitch2;
1393 chip->PGRAPH[0x0000067C/4] = state->pitch3;
1394 break;
1395 case NV_ARCH_10:
1396 LOAD_FIXED_STATE(nv10,PFIFO);
1397 LOAD_FIXED_STATE(nv10,PRAMIN);
1398 LOAD_FIXED_STATE(nv10,PGRAPH);
1399 switch (state->bpp)
1400 {
1401 case 15:
1402 LOAD_FIXED_STATE_15BPP(nv10,PRAMIN);
1403 LOAD_FIXED_STATE_15BPP(nv10,PGRAPH);
1404 chip->Tri03 = (RivaTexturedTriangle03 *)&(chip->FIFO[0x0000E000/4]);
1405 break;
1406 case 16:
1407 LOAD_FIXED_STATE_16BPP(nv10,PRAMIN);
1408 LOAD_FIXED_STATE_16BPP(nv10,PGRAPH);
1409 chip->Tri03 = (RivaTexturedTriangle03 *)&(chip->FIFO[0x0000E000/4]);
1410 break;
1411 case 24:
1412 case 32:
1413 LOAD_FIXED_STATE_32BPP(nv10,PRAMIN);
1414 LOAD_FIXED_STATE_32BPP(nv10,PGRAPH);
1415 chip->Tri03 = 0L;
1416 break;
1417 case 8:
1418 default:
1419 LOAD_FIXED_STATE_8BPP(nv10,PRAMIN);
1420 LOAD_FIXED_STATE_8BPP(nv10,PGRAPH);
1421 chip->Tri03 = 0L;
1422 break;
1423 }
1424 chip->PGRAPH[0x00000640/4] = state->offset0;
1425 chip->PGRAPH[0x00000644/4] = state->offset1;
1426 chip->PGRAPH[0x00000648/4] = state->offset2;
1427 chip->PGRAPH[0x0000064C/4] = state->offset3;
1428 chip->PGRAPH[0x00000670/4] = state->pitch0;
1429 chip->PGRAPH[0x00000674/4] = state->pitch1;
1430 chip->PGRAPH[0x00000678/4] = state->pitch2;
1431 chip->PGRAPH[0x0000067C/4] = state->pitch3;
1432 chip->PGRAPH[0x00000680/4] = state->pitch3;
1433 chip->PGRAPH[0x00000B00/4] = chip->PFB[0x00000240/4];
1434 chip->PGRAPH[0x00000B04/4] = chip->PFB[0x00000244/4];
1435 chip->PGRAPH[0x00000B08/4] = chip->PFB[0x00000248/4];
1436 chip->PGRAPH[0x00000B0C/4] = chip->PFB[0x0000024C/4];
1437 chip->PGRAPH[0x00000B10/4] = chip->PFB[0x00000250/4];
1438 chip->PGRAPH[0x00000B14/4] = chip->PFB[0x00000254/4];
1439 chip->PGRAPH[0x00000B18/4] = chip->PFB[0x00000258/4];
1440 chip->PGRAPH[0x00000B1C/4] = chip->PFB[0x0000025C/4];
1441 chip->PGRAPH[0x00000B20/4] = chip->PFB[0x00000260/4];
1442 chip->PGRAPH[0x00000B24/4] = chip->PFB[0x00000264/4];
1443 chip->PGRAPH[0x00000B28/4] = chip->PFB[0x00000268/4];
1444 chip->PGRAPH[0x00000B2C/4] = chip->PFB[0x0000026C/4];
1445 chip->PGRAPH[0x00000B30/4] = chip->PFB[0x00000270/4];
1446 chip->PGRAPH[0x00000B34/4] = chip->PFB[0x00000274/4];
1447 chip->PGRAPH[0x00000B38/4] = chip->PFB[0x00000278/4];
1448 chip->PGRAPH[0x00000B3C/4] = chip->PFB[0x0000027C/4];
1449 chip->PGRAPH[0x00000B40/4] = chip->PFB[0x00000280/4];
1450 chip->PGRAPH[0x00000B44/4] = chip->PFB[0x00000284/4];
1451 chip->PGRAPH[0x00000B48/4] = chip->PFB[0x00000288/4];
1452 chip->PGRAPH[0x00000B4C/4] = chip->PFB[0x0000028C/4];
1453 chip->PGRAPH[0x00000B50/4] = chip->PFB[0x00000290/4];
1454 chip->PGRAPH[0x00000B54/4] = chip->PFB[0x00000294/4];
1455 chip->PGRAPH[0x00000B58/4] = chip->PFB[0x00000298/4];
1456 chip->PGRAPH[0x00000B5C/4] = chip->PFB[0x0000029C/4];
1457 chip->PGRAPH[0x00000B60/4] = chip->PFB[0x000002A0/4];
1458 chip->PGRAPH[0x00000B64/4] = chip->PFB[0x000002A4/4];
1459 chip->PGRAPH[0x00000B68/4] = chip->PFB[0x000002A8/4];
1460 chip->PGRAPH[0x00000B6C/4] = chip->PFB[0x000002AC/4];
1461 chip->PGRAPH[0x00000B70/4] = chip->PFB[0x000002B0/4];
1462 chip->PGRAPH[0x00000B74/4] = chip->PFB[0x000002B4/4];
1463 chip->PGRAPH[0x00000B78/4] = chip->PFB[0x000002B8/4];
1464 chip->PGRAPH[0x00000B7C/4] = chip->PFB[0x000002BC/4];
1465 chip->PGRAPH[0x00000F40/4] = 0x10000000;
1466 chip->PGRAPH[0x00000F44/4] = 0x00000000;
1467 chip->PGRAPH[0x00000F50/4] = 0x00000040;
1468 chip->PGRAPH[0x00000F54/4] = 0x00000008;
1469 chip->PGRAPH[0x00000F50/4] = 0x00000200;
1470 for (i = 0; i < (3*16); i++)
1471 chip->PGRAPH[0x00000F54/4] = 0x00000000;
1472 chip->PGRAPH[0x00000F50/4] = 0x00000040;
1473 chip->PGRAPH[0x00000F54/4] = 0x00000000;
1474 chip->PGRAPH[0x00000F50/4] = 0x00000800;
1475 for (i = 0; i < (16*16); i++)
1476 chip->PGRAPH[0x00000F54/4] = 0x00000000;
1477 chip->PGRAPH[0x00000F40/4] = 0x30000000;
1478 chip->PGRAPH[0x00000F44/4] = 0x00000004;
1479 chip->PGRAPH[0x00000F50/4] = 0x00006400;
1480 for (i = 0; i < (59*4); i++)
1481 chip->PGRAPH[0x00000F54/4] = 0x00000000;
1482 chip->PGRAPH[0x00000F50/4] = 0x00006800;
1483 for (i = 0; i < (47*4); i++)
1484 chip->PGRAPH[0x00000F54/4] = 0x00000000;
1485 chip->PGRAPH[0x00000F50/4] = 0x00006C00;
1486 for (i = 0; i < (3*4); i++)
1487 chip->PGRAPH[0x00000F54/4] = 0x00000000;
1488 chip->PGRAPH[0x00000F50/4] = 0x00007000;
1489 for (i = 0; i < (19*4); i++)
1490 chip->PGRAPH[0x00000F54/4] = 0x00000000;
1491 chip->PGRAPH[0x00000F50/4] = 0x00007400;
1492 for (i = 0; i < (12*4); i++)
1493 chip->PGRAPH[0x00000F54/4] = 0x00000000;
1494 chip->PGRAPH[0x00000F50/4] = 0x00007800;
1495 for (i = 0; i < (12*4); i++)
1496 chip->PGRAPH[0x00000F54/4] = 0x00000000;
1497 chip->PGRAPH[0x00000F50/4] = 0x00004400;
1498 for (i = 0; i < (8*4); i++)
1499 chip->PGRAPH[0x00000F54/4] = 0x00000000;
1500 chip->PGRAPH[0x00000F50/4] = 0x00000000;
1501 for (i = 0; i < 16; i++)
1502 chip->PGRAPH[0x00000F54/4] = 0x00000000;
1503 chip->PGRAPH[0x00000F50/4] = 0x00000040;
1504 for (i = 0; i < 4; i++)
1505 chip->PGRAPH[0x00000F54/4] = 0x00000000;
1506 break;
1507 }
1508 LOAD_FIXED_STATE(Riva,FIFO);
1509 UpdateFifoState(chip);
1510 /*
1511 * Load HW mode state.
1512 */
1513 VGA_WR08(chip->PCIO, 0x03D4, 0x19);
1514 VGA_WR08(chip->PCIO, 0x03D5, state->repaint0);
1515 VGA_WR08(chip->PCIO, 0x03D4, 0x1A);
1516 VGA_WR08(chip->PCIO, 0x03D5, state->repaint1);
1517 VGA_WR08(chip->PCIO, 0x03D4, 0x25);
1518 VGA_WR08(chip->PCIO, 0x03D5, state->screen);
1519 VGA_WR08(chip->PCIO, 0x03D4, 0x28);
1520 VGA_WR08(chip->PCIO, 0x03D5, state->pixel);
1521 VGA_WR08(chip->PCIO, 0x03D4, 0x2D);
1522 VGA_WR08(chip->PCIO, 0x03D5, state->horiz);
1523 VGA_WR08(chip->PCIO, 0x03D4, 0x1B);
1524 VGA_WR08(chip->PCIO, 0x03D5, state->arbitration0);
1525 VGA_WR08(chip->PCIO, 0x03D4, 0x20);
1526 VGA_WR08(chip->PCIO, 0x03D5, state->arbitration1);
1527 VGA_WR08(chip->PCIO, 0x03D4, 0x30);
1528 VGA_WR08(chip->PCIO, 0x03D5, state->cursor0);
1529 VGA_WR08(chip->PCIO, 0x03D4, 0x31);
1530 VGA_WR08(chip->PCIO, 0x03D5, state->cursor1);
1531 chip->PRAMDAC[0x00000300/4] = state->cursor2;
1532 chip->PRAMDAC[0x00000508/4] = state->vpll;
1533 chip->PRAMDAC[0x0000050C/4] = state->pllsel;
1534 chip->PRAMDAC[0x00000600/4] = state->general;
1535 /*
1536 * Turn off VBlank enable and reset.
1537 */
1538 *(chip->VBLANKENABLE) = 0;
1539 *(chip->VBLANK) = chip->VBlankBit;
1540 /*
1541 * Set interrupt enable.
1542 */
1543 chip->PMC[0x00000140/4] = chip->EnableIRQ & 0x01;
1544 /*
1545 * Set current state pointer.
1546 */
1547 chip->CurrentState = state;
1548 /*
1549 * Reset FIFO free and empty counts.
1550 */
1551 chip->FifoFreeCount = 0;
1552 /* Free count from first subchannel */
1553 chip->FifoEmptyCount = chip->Rop->FifoFree;
1554 }
1555 static void UnloadStateExt
1556 (
1557 RIVA_HW_INST *chip,
1558 RIVA_HW_STATE *state
1559 )
1560 {
1561 /*
1562 * Save current HW state.
1563 */
1564 VGA_WR08(chip->PCIO, 0x03D4, 0x19);
1565 state->repaint0 = VGA_RD08(chip->PCIO, 0x03D5);
1566 VGA_WR08(chip->PCIO, 0x03D4, 0x1A);
1567 state->repaint1 = VGA_RD08(chip->PCIO, 0x03D5);
1568 VGA_WR08(chip->PCIO, 0x03D4, 0x25);
1569 state->screen = VGA_RD08(chip->PCIO, 0x03D5);
1570 VGA_WR08(chip->PCIO, 0x03D4, 0x28);
1571 state->pixel = VGA_RD08(chip->PCIO, 0x03D5);
1572 VGA_WR08(chip->PCIO, 0x03D4, 0x2D);
1573 state->horiz = VGA_RD08(chip->PCIO, 0x03D5);
1574 VGA_WR08(chip->PCIO, 0x03D4, 0x1B);
1575 state->arbitration0 = VGA_RD08(chip->PCIO, 0x03D5);
1576 VGA_WR08(chip->PCIO, 0x03D4, 0x20);
1577 state->arbitration1 = VGA_RD08(chip->PCIO, 0x03D5);
1578 VGA_WR08(chip->PCIO, 0x03D4, 0x30);
1579 state->cursor0 = VGA_RD08(chip->PCIO, 0x03D5);
1580 VGA_WR08(chip->PCIO, 0x03D4, 0x31);
1581 state->cursor1 = VGA_RD08(chip->PCIO, 0x03D5);
1582 state->cursor2 = chip->PRAMDAC[0x00000300/4];
1583 state->vpll = chip->PRAMDAC[0x00000508/4];
1584 state->pllsel = chip->PRAMDAC[0x0000050C/4];
1585 state->general = chip->PRAMDAC[0x00000600/4];
1586 state->config = chip->PFB[0x00000200/4];
1587 switch (chip->Architecture)
1588 {
1589 case NV_ARCH_03:
1590 state->offset0 = chip->PGRAPH[0x00000630/4];
1591 state->offset1 = chip->PGRAPH[0x00000634/4];
1592 state->offset2 = chip->PGRAPH[0x00000638/4];
1593 state->offset3 = chip->PGRAPH[0x0000063C/4];
1594 state->pitch0 = chip->PGRAPH[0x00000650/4];
1595 state->pitch1 = chip->PGRAPH[0x00000654/4];
1596 state->pitch2 = chip->PGRAPH[0x00000658/4];
1597 state->pitch3 = chip->PGRAPH[0x0000065C/4];
1598 break;
1599 case NV_ARCH_04:
1600 state->offset0 = chip->PGRAPH[0x00000640/4];
1601 state->offset1 = chip->PGRAPH[0x00000644/4];
1602 state->offset2 = chip->PGRAPH[0x00000648/4];
1603 state->offset3 = chip->PGRAPH[0x0000064C/4];
1604 state->pitch0 = chip->PGRAPH[0x00000670/4];
1605 state->pitch1 = chip->PGRAPH[0x00000674/4];
1606 state->pitch2 = chip->PGRAPH[0x00000678/4];
1607 state->pitch3 = chip->PGRAPH[0x0000067C/4];
1608 break;
1609 case NV_ARCH_10:
1610 state->offset0 = chip->PGRAPH[0x00000640/4];
1611 state->offset1 = chip->PGRAPH[0x00000644/4];
1612 state->offset2 = chip->PGRAPH[0x00000648/4];
1613 state->offset3 = chip->PGRAPH[0x0000064C/4];
1614 state->pitch0 = chip->PGRAPH[0x00000670/4];
1615 state->pitch1 = chip->PGRAPH[0x00000674/4];
1616 state->pitch2 = chip->PGRAPH[0x00000678/4];
1617 state->pitch3 = chip->PGRAPH[0x0000067C/4];
1618 break;
1619 }
1620 }
1621 static void SetStartAddress
1622 (
1623 RIVA_HW_INST *chip,
1624 unsigned start
1625 )
1626 {
1627 int offset = start >> 2;
1628 int pan = (start & 3) << 1;
1629 unsigned char tmp;
1630
1631 /*
1632 * Unlock extended registers.
1633 */
1634 chip->LockUnlock(chip, 0);
1635 /*
1636 * Set start address.
1637 */
1638 VGA_WR08(chip->PCIO, 0x3D4, 0x0D); VGA_WR08(chip->PCIO, 0x3D5, offset);
1639 offset >>= 8;
1640 VGA_WR08(chip->PCIO, 0x3D4, 0x0C); VGA_WR08(chip->PCIO, 0x3D5, offset);
1641 offset >>= 8;
1642 VGA_WR08(chip->PCIO, 0x3D4, 0x19); tmp = VGA_RD08(chip->PCIO, 0x3D5);
1643 VGA_WR08(chip->PCIO, 0x3D5, (offset & 0x01F) | (tmp & ~0x1F));
1644 VGA_WR08(chip->PCIO, 0x3D4, 0x2D); tmp = VGA_RD08(chip->PCIO, 0x3D5);
1645 VGA_WR08(chip->PCIO, 0x3D5, (offset & 0x60) | (tmp & ~0x60));
1646 /*
1647 * 4 pixel pan register.
1648 */
1649 offset = VGA_RD08(chip->PCIO, chip->IO + 0x0A);
1650 VGA_WR08(chip->PCIO, 0x3C0, 0x13);
1651 VGA_WR08(chip->PCIO, 0x3C0, pan);
1652 }
1653 static void nv3SetSurfaces2D
1654 (
1655 RIVA_HW_INST *chip,
1656 unsigned surf0,
1657 unsigned surf1
1658 )
1659 {
1660 RivaSurface *Surface = (RivaSurface *)&(chip->FIFO[0x0000E000/4]);
1661
1662 RIVA_FIFO_FREE(*chip,Tri03,5);
1663 chip->FIFO[0x00003800] = 0x80000003;
1664 Surface->Offset = surf0;
1665 chip->FIFO[0x00003800] = 0x80000004;
1666 Surface->Offset = surf1;
1667 chip->FIFO[0x00003800] = 0x80000013;
1668 }
1669 static void nv4SetSurfaces2D
1670 (
1671 RIVA_HW_INST *chip,
1672 unsigned surf0,
1673 unsigned surf1
1674 )
1675 {
1676 RivaSurface *Surface = (RivaSurface *)&(chip->FIFO[0x0000E000/4]);
1677
1678 chip->FIFO[0x00003800] = 0x80000003;
1679 Surface->Offset = surf0;
1680 chip->FIFO[0x00003800] = 0x80000004;
1681 Surface->Offset = surf1;
1682 chip->FIFO[0x00003800] = 0x80000014;
1683 }
1684 static void nv10SetSurfaces2D
1685 (
1686 RIVA_HW_INST *chip,
1687 unsigned surf0,
1688 unsigned surf1
1689 )
1690 {
1691 RivaSurface *Surface = (RivaSurface *)&(chip->FIFO[0x0000E000/4]);
1692
1693 chip->FIFO[0x00003800] = 0x80000003;
1694 Surface->Offset = surf0;
1695 chip->FIFO[0x00003800] = 0x80000004;
1696 Surface->Offset = surf1;
1697 chip->FIFO[0x00003800] = 0x80000014;
1698 }
1699 static void nv3SetSurfaces3D
1700 (
1701 RIVA_HW_INST *chip,
1702 unsigned surf0,
1703 unsigned surf1
1704 )
1705 {
1706 RivaSurface *Surface = (RivaSurface *)&(chip->FIFO[0x0000E000/4]);
1707
1708 RIVA_FIFO_FREE(*chip,Tri03,5);
1709 chip->FIFO[0x00003800] = 0x80000005;
1710 Surface->Offset = surf0;
1711 chip->FIFO[0x00003800] = 0x80000006;
1712 Surface->Offset = surf1;
1713 chip->FIFO[0x00003800] = 0x80000013;
1714 }
1715 static void nv4SetSurfaces3D
1716 (
1717 RIVA_HW_INST *chip,
1718 unsigned surf0,
1719 unsigned surf1
1720 )
1721 {
1722 RivaSurface *Surface = (RivaSurface *)&(chip->FIFO[0x0000E000/4]);
1723
1724 chip->FIFO[0x00003800] = 0x80000005;
1725 Surface->Offset = surf0;
1726 chip->FIFO[0x00003800] = 0x80000006;
1727 Surface->Offset = surf1;
1728 chip->FIFO[0x00003800] = 0x80000014;
1729 }
1730 static void nv10SetSurfaces3D
1731 (
1732 RIVA_HW_INST *chip,
1733 unsigned surf0,
1734 unsigned surf1
1735 )
1736 {
1737 RivaSurface3D *Surfaces3D = (RivaSurface3D *)&(chip->FIFO[0x0000E000/4]);
1738
1739 RIVA_FIFO_FREE(*chip,Tri03,4);
1740 chip->FIFO[0x00003800] = 0x80000007;
1741 Surfaces3D->RenderBufferOffset = surf0;
1742 Surfaces3D->ZBufferOffset = surf1;
1743 chip->FIFO[0x00003800] = 0x80000014;
1744 }
1745
1746 /****************************************************************************\
1747 * *
1748 * Probe RIVA Chip Configuration *
1749 * *
1750 \****************************************************************************/
1751
1752 static void nv3GetConfig
1753 (
1754 RIVA_HW_INST *chip
1755 )
1756 {
1757 /*
1758 * Fill in chip configuration.
1759 */
1760 if (chip->PFB[0x00000000/4] & 0x00000020)
1761 {
1762 if (((chip->PMC[0x00000000/4] & 0xF0) == 0x20)
1763 && ((chip->PMC[0x00000000/4] & 0x0F) >= 0x02))
1764 {
1765 /*
1766 * SDRAM 128 ZX.
1767 */
1768 chip->RamBandwidthKBytesPerSec = 800000;
1769 switch (chip->PFB[0x00000000/4] & 0x03)
1770 {
1771 case 2:
1772 chip->RamAmountKBytes = 1024 * 4;
1773 break;
1774 case 1:
1775 chip->RamAmountKBytes = 1024 * 2;
1776 break;
1777 default:
1778 chip->RamAmountKBytes = 1024 * 8;
1779 break;
1780 }
1781 }
1782 else
1783 {
1784 chip->RamBandwidthKBytesPerSec = 1000000;
1785 chip->RamAmountKBytes = 1024 * 8;
1786 }
1787 }
1788 else
1789 {
1790 /*
1791 * SGRAM 128.
1792 */
1793 chip->RamBandwidthKBytesPerSec = 1000000;
1794 switch (chip->PFB[0x00000000/4] & 0x00000003)
1795 {
1796 case 0:
1797 chip->RamAmountKBytes = 1024 * 8;
1798 break;
1799 case 2:
1800 chip->RamAmountKBytes = 1024 * 4;
1801 break;
1802 default:
1803 chip->RamAmountKBytes = 1024 * 2;
1804 break;
1805 }
1806 }
1807 chip->CrystalFreqKHz = (chip->PEXTDEV[0x00000000/4] & 0x00000020) ? 14318 : 13500;
1808 chip->CURSOR = &(chip->PRAMIN[0x00008000/4 - 0x0800/4]);
1809 chip->CURSORPOS = &(chip->PRAMDAC[0x0300/4]);
1810 chip->VBLANKENABLE = &(chip->PGRAPH[0x0140/4]);
1811 chip->VBLANK = &(chip->PGRAPH[0x0100/4]);
1812 chip->VBlankBit = 0x00000100;
1813 chip->MaxVClockFreqKHz = 256000;
1814 /*
1815 * Set chip functions.
1816 */
1817 chip->Busy = nv3Busy;
1818 chip->ShowHideCursor = ShowHideCursor;
1819 chip->CalcStateExt = CalcStateExt;
1820 chip->LoadStateExt = LoadStateExt;
1821 chip->UnloadStateExt = UnloadStateExt;
1822 chip->SetStartAddress = SetStartAddress;
1823 chip->SetSurfaces2D = nv3SetSurfaces2D;
1824 chip->SetSurfaces3D = nv3SetSurfaces3D;
1825 chip->LockUnlock = nv3LockUnlock;
1826 }
1827 static void nv4GetConfig
1828 (
1829 RIVA_HW_INST *chip
1830 )
1831 {
1832 /*
1833 * Fill in chip configuration.
1834 */
1835 if (chip->PFB[0x00000000/4] & 0x00000100)
1836 {
1837 chip->RamAmountKBytes = ((chip->PFB[0x00000000/4] >> 12) & 0x0F) * 1024 * 2
1838 + 1024 * 2;
1839 }
1840 else
1841 {
1842 switch (chip->PFB[0x00000000/4] & 0x00000003)
1843 {
1844 case 0:
1845 chip->RamAmountKBytes = 1024 * 32;
1846 break;
1847 case 1:
1848 chip->RamAmountKBytes = 1024 * 4;
1849 break;
1850 case 2:
1851 chip->RamAmountKBytes = 1024 * 8;
1852 break;
1853 case 3:
1854 default:
1855 chip->RamAmountKBytes = 1024 * 16;
1856 break;
1857 }
1858 }
1859 switch ((chip->PFB[0x00000000/4] >> 3) & 0x00000003)
1860 {
1861 case 3:
1862 chip->RamBandwidthKBytesPerSec = 800000;
1863 break;
1864 default:
1865 chip->RamBandwidthKBytesPerSec = 1000000;
1866 break;
1867 }
1868 chip->CrystalFreqKHz = (chip->PEXTDEV[0x00000000/4] & 0x00000040) ? 14318 : 13500;
1869 chip->CURSOR = &(chip->PRAMIN[0x00010000/4 - 0x0800/4]);
1870 chip->CURSORPOS = &(chip->PRAMDAC[0x0300/4]);
1871 chip->VBLANKENABLE = &(chip->PCRTC[0x0140/4]);
1872 chip->VBLANK = &(chip->PCRTC[0x0100/4]);
1873 chip->VBlankBit = 0x00000001;
1874 chip->MaxVClockFreqKHz = 350000;
1875 /*
1876 * Set chip functions.
1877 */
1878 chip->Busy = nv4Busy;
1879 chip->ShowHideCursor = ShowHideCursor;
1880 chip->CalcStateExt = CalcStateExt;
1881 chip->LoadStateExt = LoadStateExt;
1882 chip->UnloadStateExt = UnloadStateExt;
1883 chip->SetStartAddress = SetStartAddress;
1884 chip->SetSurfaces2D = nv4SetSurfaces2D;
1885 chip->SetSurfaces3D = nv4SetSurfaces3D;
1886 chip->LockUnlock = nv4LockUnlock;
1887 }
1888 static void nv10GetConfig
1889 (
1890 RIVA_HW_INST *chip
1891 )
1892 {
1893 /*
1894 * Fill in chip configuration.
1895 */
1896 switch ((chip->PFB[0x0000020C/4] >> 20) & 0x000000FF)
1897 {
1898 case 0x02:
1899 chip->RamAmountKBytes = 1024 * 2;
1900 break;
1901 case 0x04:
1902 chip->RamAmountKBytes = 1024 * 4;
1903 break;
1904 case 0x08:
1905 chip->RamAmountKBytes = 1024 * 8;
1906 break;
1907 case 0x10:
1908 chip->RamAmountKBytes = 1024 * 16;
1909 break;
1910 case 0x20:
1911 chip->RamAmountKBytes = 1024 * 32;
1912 break;
1913 case 0x40:
1914 chip->RamAmountKBytes = 1024 * 64;
1915 break;
1916 case 0x80:
1917 chip->RamAmountKBytes = 1024 * 128;
1918 break;
1919 default:
1920 chip->RamAmountKBytes = 1024 * 16;
1921 break;
1922 }
1923 switch ((chip->PFB[0x00000000/4] >> 3) & 0x00000003)
1924 {
1925 case 3:
1926 chip->RamBandwidthKBytesPerSec = 800000;
1927 break;
1928 default:
1929 chip->RamBandwidthKBytesPerSec = 1000000;
1930 break;
1931 }
1932 chip->CrystalFreqKHz = (chip->PEXTDEV[0x00000000/4] & 0x00000040) ? 14318 : 13500;
1933 chip->CURSOR = &(chip->PRAMIN[0x00010000/4 - 0x0800/4]);
1934 chip->CURSORPOS = &(chip->PRAMDAC[0x0300/4]);
1935 chip->VBLANKENABLE = &(chip->PCRTC[0x0140/4]);
1936 chip->VBLANK = &(chip->PCRTC[0x0100/4]);
1937 chip->VBlankBit = 0x00000001;
1938 chip->MaxVClockFreqKHz = 350000;
1939 /*
1940 * Set chip functions.
1941 */
1942 chip->Busy = nv10Busy;
1943 chip->ShowHideCursor = ShowHideCursor;
1944 chip->CalcStateExt = CalcStateExt;
1945 chip->LoadStateExt = LoadStateExt;
1946 chip->UnloadStateExt = UnloadStateExt;
1947 chip->SetStartAddress = SetStartAddress;
1948 chip->SetSurfaces2D = nv10SetSurfaces2D;
1949 chip->SetSurfaces3D = nv10SetSurfaces3D;
1950 chip->LockUnlock = nv10LockUnlock;
1951 }
1952 int RivaGetConfig
1953 (
1954 RIVA_HW_INST *chip
1955 )
1956 {
1957 /*
1958 * Save this so future SW know whats it's dealing with.
1959 */
1960 chip->Version = RIVA_SW_VERSION;
1961 /*
1962 * Chip specific configuration.
1963 */
1964 switch (chip->Architecture)
1965 {
1966 case NV_ARCH_03:
1967 nv3GetConfig(chip);
1968 break;
1969 case NV_ARCH_04:
1970 nv4GetConfig(chip);
1971 break;
1972 case NV_ARCH_10:
1973 nv10GetConfig(chip);
1974 break;
1975 default:
1976 return (-1);
1977 }
1978 /*
1979 * Fill in FIFO pointers.
1980 */
1981 chip->Rop = (RivaRop *)&(chip->FIFO[0x00000000/4]);
1982 chip->Clip = (RivaClip *)&(chip->FIFO[0x00002000/4]);
1983 chip->Patt = (RivaPattern *)&(chip->FIFO[0x00004000/4]);
1984 chip->Pixmap = (RivaPixmap *)&(chip->FIFO[0x00006000/4]);
1985 chip->Blt = (RivaScreenBlt *)&(chip->FIFO[0x00008000/4]);
1986 chip->Bitmap = (RivaBitmap *)&(chip->FIFO[0x0000A000/4]);
1987 chip->Line = (RivaLine *)&(chip->FIFO[0x0000C000/4]);
1988 chip->Tri03 = (RivaTexturedTriangle03 *)&(chip->FIFO[0x0000E000/4]);
1989 return (0);
1990 }
1991
1992