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