Subversion Repositories shark

Rev

Rev 472 | Details | Compare with Previous | Last modification | View Log | RSS feed

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