Subversion Repositories shark

Rev

Rev 473 | Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
472 giacomo 1
/*
2
 * linux/drivers/video/riva/fbdev.c - nVidia RIVA 128/TNT/TNT2 fb driver
3
 *
4
 * Maintained by Ani Joshi <ajoshi@shell.unixbox.com>
5
 *
6
 * Copyright 1999-2000 Jeff Garzik
7
 *
8
 * Contributors:
9
 *
10
 *      Ani Joshi:  Lots of debugging and cleanup work, really helped
11
 *      get the driver going
12
 *
13
 *      Ferenc Bakonyi:  Bug fixes, cleanup, modularization
14
 *
15
 *      Jindrich Makovicka:  Accel code help, hw cursor, mtrr
16
 *
17
 *      Paul Richards:  Bug fixes, updates
18
 *
19
 * Initial template from skeletonfb.c, created 28 Dec 1997 by Geert Uytterhoeven
20
 * Includes riva_hw.c from nVidia, see copyright below.
21
 * KGI code provided the basis for state storage, init, and mode switching.
22
 *
23
 * This file is subject to the terms and conditions of the GNU General Public
24
 * License.  See the file COPYING in the main directory of this archive
25
 * for more details.
26
 *
27
 * Known bugs and issues:
28
 *      restoring text mode fails
29
 *      doublescan modes are broken
30
 */
31
 
32
#include <linuxcomp.h>
33
 
34
#include <linux/config.h>
35
#include <linux/module.h>
36
#include <linux/kernel.h>
37
#include <linux/errno.h>
38
#include <linux/string.h>
39
#include <linux/mm.h>
40
#include <linux/tty.h>
41
#include <linux/slab.h>
42
#include <linux/delay.h>
43
#include <linux/fb.h>
44
#include <linux/init.h>
45
#include <linux/pci.h>
46
#ifdef CONFIG_MTRR
47
#include <asm/mtrr.h>
48
#endif
49
 
50
#include "rivafb.h"
51
#include "nvreg.h"
52
 
53
#ifndef CONFIG_PCI              /* sanity check */
54
#error This driver requires PCI support.
55
#endif
56
 
57
/* version number of this driver */
58
#define RIVAFB_VERSION "0.9.5b"
59
 
60
/* ------------------------------------------------------------------------- *
61
 *
62
 * various helpful macros and constants
63
 *
64
 * ------------------------------------------------------------------------- */
65
 
66
#undef RIVAFBDEBUG
67
#ifdef RIVAFBDEBUG
68
#define DPRINTK(fmt, args...) printk(KERN_DEBUG "%s: " fmt, __FUNCTION__ , ## args)
69
#else
70
#define DPRINTK(fmt, args...)
71
#endif
72
 
73
#ifndef RIVA_NDEBUG
74
#define assert(expr) \
75
        if(!(expr)) { \
76
        printk( "Assertion failed! %s,%s,%s,line=%d\n",\
77
        #expr,__FILE__,__FUNCTION__,__LINE__); \
78
        BUG(); \
79
        }
80
#else
81
#define assert(expr)
82
#endif
83
 
84
#define PFX "rivafb: "
85
 
86
/* macro that allows you to set overflow bits */
87
#define SetBitField(value,from,to) SetBF(to,GetBF(value,from))
88
#define SetBit(n)               (1<<(n))
89
#define Set8Bits(value)         ((value)&0xff)
90
 
91
/* HW cursor parameters */
92
#define MAX_CURS                32
93
 
94
/* ------------------------------------------------------------------------- *
95
 *
96
 * prototypes
97
 *
98
 * ------------------------------------------------------------------------- */
99
 
100
static int rivafb_blank(int blank, struct fb_info *info);
101
 
102
/* ------------------------------------------------------------------------- *
103
 *
104
 * card identification
105
 *
106
 * ------------------------------------------------------------------------- */
107
 
108
enum riva_chips {
109
        CH_RIVA_128 = 0,
110
        CH_RIVA_TNT,
111
        CH_RIVA_TNT2,
112
        CH_RIVA_UTNT2,
113
        CH_RIVA_VTNT2,
114
        CH_RIVA_UVTNT2,
115
        CH_RIVA_ITNT2,
116
        CH_GEFORCE_SDR,
117
        CH_GEFORCE_DDR,
118
        CH_QUADRO,
119
        CH_GEFORCE2_MX,
120
        CH_GEFORCE2_MX2,
121
        CH_GEFORCE2_GO,
122
        CH_QUADRO2_MXR,
123
        CH_GEFORCE2_GTS,
124
        CH_GEFORCE2_GTS2,
125
        CH_GEFORCE2_ULTRA,
126
        CH_QUADRO2_PRO,
127
        CH_GEFORCE4_MX_460,
128
        CH_GEFORCE4_MX_440,
129
        CH_GEFORCE4_MX_420,
130
        CH_GEFORCE4_440_GO,
131
        CH_GEFORCE4_420_GO,
132
        CH_GEFORCE4_420_GO_M32,
133
        CH_QUADRO4_500XGL,
134
        CH_GEFORCE4_440_GO_M64,
135
        CH_QUADRO4_200,
136
        CH_QUADRO4_550XGL,
137
        CH_QUADRO4_500_GOGL,
138
        CH_IGEFORCE2,
139
        CH_GEFORCE3,
140
        CH_GEFORCE3_1,
141
        CH_GEFORCE3_2,
142
        CH_QUADRO_DDC,
143
        CH_GEFORCE4_TI_4600,
144
        CH_GEFORCE4_TI_4400,
145
        CH_GEFORCE4_TI_4200,
146
        CH_QUADRO4_900XGL,
147
        CH_QUADRO4_750XGL,
148
        CH_QUADRO4_700XGL
149
};
150
 
151
/* directly indexed by riva_chips enum, above */
152
static struct riva_chip_info {
153
        const char *name;
154
        unsigned arch_rev;
155
} riva_chip_info[] __initdata = {
156
        { "RIVA-128", NV_ARCH_03 },
157
        { "RIVA-TNT", NV_ARCH_04 },
158
        { "RIVA-TNT2", NV_ARCH_04 },
159
        { "RIVA-UTNT2", NV_ARCH_04 },
160
        { "RIVA-VTNT2", NV_ARCH_04 },
161
        { "RIVA-UVTNT2", NV_ARCH_04 },
162
        { "RIVA-ITNT2", NV_ARCH_04 },
163
        { "GeForce-SDR", NV_ARCH_10 },
164
        { "GeForce-DDR", NV_ARCH_10 },
165
        { "Quadro", NV_ARCH_10 },
166
        { "GeForce2-MX", NV_ARCH_10 },
167
        { "GeForce2-MX", NV_ARCH_10 },
168
        { "GeForce2-GO", NV_ARCH_10 },
169
        { "Quadro2-MXR", NV_ARCH_10 },
170
        { "GeForce2-GTS", NV_ARCH_10 },
171
        { "GeForce2-GTS", NV_ARCH_10 },
172
        { "GeForce2-ULTRA", NV_ARCH_10 },
173
        { "Quadro2-PRO", NV_ARCH_10 },
174
        { "GeForce4-MX-460", NV_ARCH_20 },
175
        { "GeForce4-MX-440", NV_ARCH_20 },
176
        { "GeForce4-MX-420", NV_ARCH_20 },
177
        { "GeForce4-440-GO", NV_ARCH_20 },
178
        { "GeForce4-420-GO", NV_ARCH_20 },
179
        { "GeForce4-420-GO-M32", NV_ARCH_20 },
180
        { "Quadro4-500-XGL", NV_ARCH_20 },
181
        { "GeForce4-440-GO-M64", NV_ARCH_20 },
182
        { "Quadro4-200", NV_ARCH_20 },
183
        { "Quadro4-550-XGL", NV_ARCH_20 },
184
        { "Quadro4-500-GOGL", NV_ARCH_20 },
185
        { "GeForce2", NV_ARCH_20 },
186
        { "GeForce3", NV_ARCH_20 },
187
        { "GeForce3 Ti 200", NV_ARCH_20 },
188
        { "GeForce3 Ti 500", NV_ARCH_20 },
189
        { "Quadro DDC", NV_ARCH_20 },
190
        { "GeForce4 Ti 4600", NV_ARCH_20 },
191
        { "GeForce4 Ti 4400", NV_ARCH_20 },
192
        { "GeForce4 Ti 4200", NV_ARCH_20 },
193
        { "Quadro4-900-XGL", NV_ARCH_20 },
194
        { "Quadro4-750-XGL", NV_ARCH_20 },
195
        { "Quadro4-700-XGL", NV_ARCH_20 }
196
};
197
 
198
static struct pci_device_id rivafb_pci_tbl[] = {
199
        { PCI_VENDOR_ID_NVIDIA_SGS, PCI_DEVICE_ID_NVIDIA_SGS_RIVA128,
200
          PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_RIVA_128 },
201
        { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_TNT,
202
          PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_RIVA_TNT },
203
        { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_TNT2,
204
          PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_RIVA_TNT2 },
205
        { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_UTNT2,
206
          PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_RIVA_UTNT2 },
207
        { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_VTNT2,
208
          PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_RIVA_VTNT2 },
209
        { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_UVTNT2,
210
          PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_RIVA_VTNT2 },
211
        { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_ITNT2,
212
          PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_RIVA_ITNT2 },
213
        { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE_SDR,
214
          PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_GEFORCE_SDR },
215
        { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE_DDR,
216
          PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_GEFORCE_DDR },
217
        { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_QUADRO,
218
          PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_QUADRO },
219
        { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE2_MX,
220
          PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_GEFORCE2_MX },
221
        { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE2_MX2,
222
          PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_GEFORCE2_MX2 },
223
        { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE2_GO,
224
          PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_GEFORCE2_GO },
225
        { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_QUADRO2_MXR,
226
          PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_QUADRO2_MXR },
227
        { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE2_GTS,
228
          PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_GEFORCE2_GTS },
229
        { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE2_GTS2,
230
          PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_GEFORCE2_GTS2 },
231
        { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE2_ULTRA,
232
          PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_GEFORCE2_ULTRA },
233
        { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_QUADRO2_PRO,
234
          PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_QUADRO2_PRO },
235
        { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE4_MX_460,
236
          PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_GEFORCE4_MX_460 },
237
        { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE4_MX_440,
238
          PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_GEFORCE4_MX_440 },
239
        { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE4_MX_420,
240
          PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_GEFORCE4_MX_420 },
241
        { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE4_440_GO,
242
          PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_GEFORCE4_440_GO },
243
        { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE4_420_GO,
244
          PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_GEFORCE4_420_GO },
245
        { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE4_420_GO_M32,
246
          PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_GEFORCE4_420_GO_M32 },
247
        { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_QUADRO4_500XGL,
248
          PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_QUADRO4_500XGL },
249
        { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE4_440_GO_M64,
250
          PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_GEFORCE4_440_GO_M64 },
251
        { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_QUADRO4_200,
252
          PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_QUADRO4_200 },
253
        { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_QUADRO4_550XGL,
254
          PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_QUADRO4_550XGL },
255
        { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_QUADRO4_500_GOGL,
256
          PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_QUADRO4_500_GOGL },
257
        { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_IGEFORCE2,
258
          PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_IGEFORCE2 },
259
        { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE3,
260
          PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_GEFORCE3 },
261
        { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE3_1,
262
          PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_GEFORCE3_1 },
263
        { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE3_2,
264
          PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_GEFORCE3_2 },
265
        { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_QUADRO_DDC,
266
          PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_QUADRO_DDC },
267
        { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE4_TI_4600,
268
          PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_GEFORCE4_TI_4600 },
269
        { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE4_TI_4400,
270
          PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_GEFORCE4_TI_4400 },
271
        { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_GEFORCE4_TI_4200,
272
          PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_GEFORCE4_TI_4200 },
273
        { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_QUADRO4_900XGL,
274
          PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_QUADRO4_900XGL },
275
        { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_QUADRO4_750XGL,
276
          PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_QUADRO4_750XGL },
277
        { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_QUADRO4_700XGL,
278
          PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_QUADRO4_700XGL },
279
        { 0, } /* terminate list */
280
};
281
MODULE_DEVICE_TABLE(pci, rivafb_pci_tbl);
282
 
283
/* ------------------------------------------------------------------------- *
284
 *
285
 * global variables
286
 *
287
 * ------------------------------------------------------------------------- */
288
 
289
/* command line data, set in rivafb_setup() */
290
static u32 pseudo_palette[17];
291
static int flatpanel __initdata = -1; /* Autodetect later */
292
static int forceCRTC __initdata = -1;
293
#ifdef CONFIG_MTRR
294
static int nomtrr __initdata = 0;
295
#endif
296
 
297
#ifndef MODULE
298
static char *mode_option __initdata = NULL;
299
#endif
300
 
301
static struct fb_fix_screeninfo rivafb_fix = {
302
        .id             = "nVidia",
303
        .type           = FB_TYPE_PACKED_PIXELS,
304
        .xpanstep       = 1,
305
        .ypanstep       = 1,
306
};
307
 
308
static struct fb_var_screeninfo rivafb_default_var = {
309
        .xres           = 640,
310
        .yres           = 480,
311
        .xres_virtual   = 640,
312
        .yres_virtual   = 480,
313
        .bits_per_pixel = 8,
314
        .red            = {0, 8, 0},
315
        .green          = {0, 8, 0},
316
        .blue           = {0, 8, 0},
317
        .transp         = {0, 0, 0},
318
        .activate       = FB_ACTIVATE_NOW,
319
        .height         = -1,
320
        .width          = -1,
321
        .accel_flags    = FB_ACCELF_TEXT,
322
        .pixclock       = 39721,
323
        .left_margin    = 40,
324
        .right_margin   = 24,
325
        .upper_margin   = 32,
326
        .lower_margin   = 11,
327
        .hsync_len      = 96,
328
        .vsync_len      = 2,
329
        .vmode          = FB_VMODE_NONINTERLACED
330
};
331
 
332
/* from GGI */
333
static const struct riva_regs reg_template = {
334
        {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,        /* ATTR */
335
         0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
336
         0x41, 0x01, 0x0F, 0x00, 0x00},
337
        {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,        /* CRT  */
338
         0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00,
339
         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE3,        /* 0x10 */
340
         0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
341
         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,        /* 0x20 */
342
         0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
343
         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,        /* 0x30 */
344
         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
345
         0x00,                                                  /* 0x40 */
346
         },
347
        {0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x05, 0x0F,        /* GRA  */
348
         0xFF},
349
        {0x03, 0x01, 0x0F, 0x00, 0x0E},                         /* SEQ  */
350
        0xEB                                                    /* MISC */
351
};
352
 
353
/* ------------------------------------------------------------------------- *
354
 *
355
 * MMIO access macros
356
 *
357
 * ------------------------------------------------------------------------- */
358
 
359
static inline void CRTCout(struct riva_par *par, unsigned char index,
360
                           unsigned char val)
361
{
362
        VGA_WR08(par->riva.PCIO, 0x3d4, index);
363
        VGA_WR08(par->riva.PCIO, 0x3d5, val);
364
}
365
 
366
static inline unsigned char CRTCin(struct riva_par *par,
367
                                   unsigned char index)
368
{
369
        VGA_WR08(par->riva.PCIO, 0x3d4, index);
370
        return (VGA_RD08(par->riva.PCIO, 0x3d5));
371
}
372
 
373
static inline void GRAout(struct riva_par *par, unsigned char index,
374
                          unsigned char val)
375
{
376
        VGA_WR08(par->riva.PVIO, 0x3ce, index);
377
        VGA_WR08(par->riva.PVIO, 0x3cf, val);
378
}
379
 
380
static inline unsigned char GRAin(struct riva_par *par,
381
                                  unsigned char index)
382
{
383
        VGA_WR08(par->riva.PVIO, 0x3ce, index);
384
        return (VGA_RD08(par->riva.PVIO, 0x3cf));
385
}
386
 
387
static inline void SEQout(struct riva_par *par, unsigned char index,
388
                          unsigned char val)
389
{
390
        VGA_WR08(par->riva.PVIO, 0x3c4, index);
391
        VGA_WR08(par->riva.PVIO, 0x3c5, val);
392
}
393
 
394
static inline unsigned char SEQin(struct riva_par *par,
395
                                  unsigned char index)
396
{
397
        VGA_WR08(par->riva.PVIO, 0x3c4, index);
398
        return (VGA_RD08(par->riva.PVIO, 0x3c5));
399
}
400
 
401
static inline void ATTRout(struct riva_par *par, unsigned char index,
402
                           unsigned char val)
403
{
404
        VGA_WR08(par->riva.PCIO, 0x3c0, index);
405
        VGA_WR08(par->riva.PCIO, 0x3c0, val);
406
}
407
 
408
static inline unsigned char ATTRin(struct riva_par *par,
409
                                   unsigned char index)
410
{
411
        VGA_WR08(par->riva.PCIO, 0x3c0, index);
412
        return (VGA_RD08(par->riva.PCIO, 0x3c1));
413
}
414
 
415
static inline void MISCout(struct riva_par *par, unsigned char val)
416
{
417
        VGA_WR08(par->riva.PVIO, 0x3c2, val);
418
}
419
 
420
static inline unsigned char MISCin(struct riva_par *par)
421
{
422
        return (VGA_RD08(par->riva.PVIO, 0x3cc));
423
}
424
 
425
static u8 byte_rev[256] = {
426
        0x00, 0x80, 0x40, 0xc0, 0x20, 0xa0, 0x60, 0xe0,
427
        0x10, 0x90, 0x50, 0xd0, 0x30, 0xb0, 0x70, 0xf0,
428
        0x08, 0x88, 0x48, 0xc8, 0x28, 0xa8, 0x68, 0xe8,
429
        0x18, 0x98, 0x58, 0xd8, 0x38, 0xb8, 0x78, 0xf8,
430
        0x04, 0x84, 0x44, 0xc4, 0x24, 0xa4, 0x64, 0xe4,
431
        0x14, 0x94, 0x54, 0xd4, 0x34, 0xb4, 0x74, 0xf4,
432
        0x0c, 0x8c, 0x4c, 0xcc, 0x2c, 0xac, 0x6c, 0xec,
433
        0x1c, 0x9c, 0x5c, 0xdc, 0x3c, 0xbc, 0x7c, 0xfc,
434
        0x02, 0x82, 0x42, 0xc2, 0x22, 0xa2, 0x62, 0xe2,
435
        0x12, 0x92, 0x52, 0xd2, 0x32, 0xb2, 0x72, 0xf2,
436
        0x0a, 0x8a, 0x4a, 0xca, 0x2a, 0xaa, 0x6a, 0xea,
437
        0x1a, 0x9a, 0x5a, 0xda, 0x3a, 0xba, 0x7a, 0xfa,
438
        0x06, 0x86, 0x46, 0xc6, 0x26, 0xa6, 0x66, 0xe6,
439
        0x16, 0x96, 0x56, 0xd6, 0x36, 0xb6, 0x76, 0xf6,
440
        0x0e, 0x8e, 0x4e, 0xce, 0x2e, 0xae, 0x6e, 0xee,
441
        0x1e, 0x9e, 0x5e, 0xde, 0x3e, 0xbe, 0x7e, 0xfe,
442
        0x01, 0x81, 0x41, 0xc1, 0x21, 0xa1, 0x61, 0xe1,
443
        0x11, 0x91, 0x51, 0xd1, 0x31, 0xb1, 0x71, 0xf1,
444
        0x09, 0x89, 0x49, 0xc9, 0x29, 0xa9, 0x69, 0xe9,
445
        0x19, 0x99, 0x59, 0xd9, 0x39, 0xb9, 0x79, 0xf9,
446
        0x05, 0x85, 0x45, 0xc5, 0x25, 0xa5, 0x65, 0xe5,
447
        0x15, 0x95, 0x55, 0xd5, 0x35, 0xb5, 0x75, 0xf5,
448
        0x0d, 0x8d, 0x4d, 0xcd, 0x2d, 0xad, 0x6d, 0xed,
449
        0x1d, 0x9d, 0x5d, 0xdd, 0x3d, 0xbd, 0x7d, 0xfd,
450
        0x03, 0x83, 0x43, 0xc3, 0x23, 0xa3, 0x63, 0xe3,
451
        0x13, 0x93, 0x53, 0xd3, 0x33, 0xb3, 0x73, 0xf3,
452
        0x0b, 0x8b, 0x4b, 0xcb, 0x2b, 0xab, 0x6b, 0xeb,
453
        0x1b, 0x9b, 0x5b, 0xdb, 0x3b, 0xbb, 0x7b, 0xfb,
454
        0x07, 0x87, 0x47, 0xc7, 0x27, 0xa7, 0x67, 0xe7,
455
        0x17, 0x97, 0x57, 0xd7, 0x37, 0xb7, 0x77, 0xf7,
456
        0x0f, 0x8f, 0x4f, 0xcf, 0x2f, 0xaf, 0x6f, 0xef,
457
        0x1f, 0x9f, 0x5f, 0xdf, 0x3f, 0xbf, 0x7f, 0xff,
458
};
459
 
460
static inline void reverse_order(u32 *l)
461
{
462
        u8 *a = (u8 *)l;
463
        *a = byte_rev[*a], a++;
464
        *a = byte_rev[*a], a++;
465
        *a = byte_rev[*a], a++;
466
        *a = byte_rev[*a];
467
}
468
 
469
/* ------------------------------------------------------------------------- *
470
 *
471
 * cursor stuff
472
 *
473
 * ------------------------------------------------------------------------- */
474
 
475
/**
476
 * rivafb_load_cursor_image - load cursor image to hardware
477
 * @data: address to monochrome bitmap (1 = foreground color, 0 = background)
478
 * @par:  pointer to private data
479
 * @w:    width of cursor image in pixels
480
 * @h:    height of cursor image in scanlines
481
 * @bg:   background color (ARGB1555) - alpha bit determines opacity
482
 * @fg:   foreground color (ARGB1555)
483
 *
484
 * DESCRIPTiON:
485
 * Loads cursor image based on a monochrome source and mask bitmap.  The
486
 * image bits determines the color of the pixel, 0 for background, 1 for
487
 * foreground.  Only the affected region (as determined by @w and @h
488
 * parameters) will be updated.
489
 *
490
 * CALLED FROM:
491
 * rivafb_cursor()
492
 */
493
static void rivafb_load_cursor_image(struct riva_par *par, u8 *data,
494
                                     u8 *mask, u16 bg, u16 fg, u32 w, u32 h)
495
{
496
        int i, j, k = 0;
497
        u32 b, m, tmp;
498
 
499
        for (i = 0; i < h; i++) {
500
                b = *((u32 *)data)++;
501
                m = *((u32 *)mask)++;
502
                reverse_order(&b);
503
 
504
                for (j = 0; j < w/2; j++) {
505
                        tmp = 0;
506
#if defined (__BIG_ENDIAN)
507
                        if (m & (1 << 31)) {
508
                                fg |= 1 << 15;
509
                                bg |= 1 << 15;
510
                        }
511
                        tmp = (b & (1 << 31)) ? fg << 16 : bg << 16;
512
                        b <<= 1;
513
                        m <<= 1;
514
 
515
                        if (m & (1 << 31)) {
516
                                fg |= 1 << 15;
517
                                bg |= 1 << 15;
518
                        }
519
                        tmp |= (b & (1 << 31)) ? fg : bg;
520
                        b <<= 1;
521
                        m <<= 1;
522
#else
523
                        if (m & 1) {
524
                                fg |= 1 << 15;
525
                                bg |= 1 << 15;
526
                        }
527
                        tmp = (b & 1) ? fg : bg;
528
                        b >>= 1;
529
                        m >>= 1;
530
 
531
                        if (m & 1) {
532
                                fg |= 1 << 15;
533
                                bg |= 1 << 15;
534
                        }
535
                        tmp |= (b & 1) ? fg << 16 : bg << 16;
536
                        b >>= 1;
537
                        m >>= 1;
538
#endif
539
                        writel(tmp, par->riva.CURSOR + k++);
540
                }
541
                k += (MAX_CURS - w)/2;
542
        }
543
}
544
 
545
/* ------------------------------------------------------------------------- *
546
 *
547
 * general utility functions
548
 *
549
 * ------------------------------------------------------------------------- */
550
 
551
/**
552
 * riva_wclut - set CLUT entry
553
 * @chip: pointer to RIVA_HW_INST object
554
 * @regnum: register number
555
 * @red: red component
556
 * @green: green component
557
 * @blue: blue component
558
 *
559
 * DESCRIPTION:
560
 * Sets color register @regnum.
561
 *
562
 * CALLED FROM:
563
 * rivafb_setcolreg()
564
 */
565
static void riva_wclut(RIVA_HW_INST *chip,
566
                       unsigned char regnum, unsigned char red,
567
                       unsigned char green, unsigned char blue)
568
{
569
        VGA_WR08(chip->PDIO, 0x3c8, regnum);
570
        VGA_WR08(chip->PDIO, 0x3c9, red);
571
        VGA_WR08(chip->PDIO, 0x3c9, green);
572
        VGA_WR08(chip->PDIO, 0x3c9, blue);
573
}
574
 
575
/**
576
 * riva_rclut - read fromCLUT register
577
 * @chip: pointer to RIVA_HW_INST object
578
 * @regnum: register number
579
 * @red: red component
580
 * @green: green component
581
 * @blue: blue component
582
 *
583
 * DESCRIPTION:
584
 * Reads red, green, and blue from color register @regnum.
585
 *
586
 * CALLED FROM:
587
 * rivafb_setcolreg()
588
 */
589
static void riva_rclut(RIVA_HW_INST *chip,
590
                       unsigned char regnum, unsigned char *red,
591
                       unsigned char *green, unsigned char *blue)
592
{
593
 
594
        VGA_WR08(chip->PDIO, 0x3c8, regnum);
595
        *red = VGA_RD08(chip->PDIO, 0x3c9);
596
        *green = VGA_RD08(chip->PDIO, 0x3c9);
597
        *blue = VGA_RD08(chip->PDIO, 0x3c9);
598
}
599
 
600
/**
601
 * riva_save_state - saves current chip state
602
 * @par: pointer to riva_par object containing info for current riva board
603
 * @regs: pointer to riva_regs object
604
 *
605
 * DESCRIPTION:
606
 * Saves current chip state to @regs.
607
 *
608
 * CALLED FROM:
609
 * rivafb_probe()
610
 */
611
/* from GGI */
612
static void riva_save_state(struct riva_par *par, struct riva_regs *regs)
613
{
614
        int i;
615
 
616
        par->riva.LockUnlock(&par->riva, 0);
617
 
618
        par->riva.UnloadStateExt(&par->riva, &regs->ext);
619
 
620
        regs->misc_output = MISCin(par);
621
 
622
        for (i = 0; i < NUM_CRT_REGS; i++)
623
                regs->crtc[i] = CRTCin(par, i);
624
 
625
        for (i = 0; i < NUM_ATC_REGS; i++)
626
                regs->attr[i] = ATTRin(par, i);
627
 
628
        for (i = 0; i < NUM_GRC_REGS; i++)
629
                regs->gra[i] = GRAin(par, i);
630
 
631
        for (i = 0; i < NUM_SEQ_REGS; i++)
632
                regs->seq[i] = SEQin(par, i);
633
}
634
 
635
/**
636
 * riva_load_state - loads current chip state
637
 * @par: pointer to riva_par object containing info for current riva board
638
 * @regs: pointer to riva_regs object
639
 *
640
 * DESCRIPTION:
641
 * Loads chip state from @regs.
642
 *
643
 * CALLED FROM:
644
 * riva_load_video_mode()
645
 * rivafb_probe()
646
 * rivafb_remove()
647
 */
648
/* from GGI */
649
static void riva_load_state(struct riva_par *par, struct riva_regs *regs)
650
{
651
        RIVA_HW_STATE *state = &regs->ext;
652
        int i;
653
 
654
        CRTCout(par, 0x11, 0x00);
655
 
656
        par->riva.LockUnlock(&par->riva, 0);
657
 
658
        par->riva.LoadStateExt(&par->riva, state);
659
 
660
        MISCout(par, regs->misc_output);
661
 
662
        for (i = 0; i < NUM_CRT_REGS; i++) {
663
                switch (i) {
664
                case 0x19:
665
                case 0x20 ... 0x40:
666
                        break;
667
                default:
668
                        CRTCout(par, i, regs->crtc[i]);
669
                }
670
        }
671
 
672
        for (i = 0; i < NUM_ATC_REGS; i++)
673
                ATTRout(par, i, regs->attr[i]);
674
 
675
        for (i = 0; i < NUM_GRC_REGS; i++)
676
                GRAout(par, i, regs->gra[i]);
677
 
678
        for (i = 0; i < NUM_SEQ_REGS; i++)
679
                SEQout(par, i, regs->seq[i]);
680
}
681
 
682
/**
683
 * riva_load_video_mode - calculate timings
684
 * @info: pointer to fb_info object containing info for current riva board
685
 *
686
 * DESCRIPTION:
687
 * Calculate some timings and then send em off to riva_load_state().
688
 *
689
 * CALLED FROM:
690
 * rivafb_set_par()
691
 */
692
static void riva_load_video_mode(struct fb_info *info)
693
{
694
        int bpp, width, hDisplaySize, hDisplay, hStart,
695
            hEnd, hTotal, height, vDisplay, vStart, vEnd, vTotal, dotClock;
696
        int hBlankStart, hBlankEnd, vBlankStart, vBlankEnd;
697
        struct riva_par *par = (struct riva_par *) info->par;
698
        struct riva_regs newmode;
699
 
700
        /* time to calculate */
701
        rivafb_blank(1, info);
702
 
703
        bpp = info->var.bits_per_pixel;
704
        if (bpp == 16 && info->var.green.length == 5)
705
                bpp = 15;
706
        width = info->var.xres_virtual;
707
        hDisplaySize = info->var.xres;
708
        hDisplay = (hDisplaySize / 8) - 1;
709
        hStart = (hDisplaySize + info->var.right_margin) / 8 - 1;
710
        hEnd = (hDisplaySize + info->var.right_margin +
711
                info->var.hsync_len) / 8 - 1;
712
        hTotal = (hDisplaySize + info->var.right_margin +
713
                  info->var.hsync_len + info->var.left_margin) / 8 - 5;
714
        hBlankStart = hDisplay;
715
        hBlankEnd = hTotal + 4;
716
 
717
        height = info->var.yres_virtual;
718
        vDisplay = info->var.yres - 1;
719
        vStart = info->var.yres + info->var.lower_margin - 1;
720
        vEnd = info->var.yres + info->var.lower_margin +
721
               info->var.vsync_len - 1;
722
        vTotal = info->var.yres + info->var.lower_margin +
723
                 info->var.vsync_len + info->var.upper_margin + 2;
724
        vBlankStart = vDisplay;
725
        vBlankEnd = vTotal + 1;
726
        dotClock = 1000000000 / info->var.pixclock;
727
 
728
        memcpy(&newmode, &reg_template, sizeof(struct riva_regs));
729
 
730
        if ((info->var.vmode & FB_VMODE_MASK) == FB_VMODE_INTERLACED)
731
                vTotal |= 1;
732
 
733
        if (par->FlatPanel) {
734
                vStart = vTotal - 3;
735
                vEnd = vTotal - 2;
736
                vBlankStart = vStart;
737
                hStart = hTotal - 3;
738
                hEnd = hTotal - 2;
739
                hBlankEnd = hTotal + 4;
740
        }
741
 
742
        newmode.crtc[0x0] = Set8Bits (hTotal);
743
        newmode.crtc[0x1] = Set8Bits (hDisplay);
744
        newmode.crtc[0x2] = Set8Bits (hBlankStart);
745
        newmode.crtc[0x3] = SetBitField (hBlankEnd, 4: 0, 4:0) | SetBit (7);
746
        newmode.crtc[0x4] = Set8Bits (hStart);
747
        newmode.crtc[0x5] = SetBitField (hBlankEnd, 5: 5, 7:7)
748
                | SetBitField (hEnd, 4: 0, 4:0);
749
        newmode.crtc[0x6] = SetBitField (vTotal, 7: 0, 7:0);
750
        newmode.crtc[0x7] = SetBitField (vTotal, 8: 8, 0:0)
751
                | SetBitField (vDisplay, 8: 8, 1:1)
752
                | SetBitField (vStart, 8: 8, 2:2)
753
                | SetBitField (vBlankStart, 8: 8, 3:3)
754
                | SetBit (4)
755
                | SetBitField (vTotal, 9: 9, 5:5)
756
                | SetBitField (vDisplay, 9: 9, 6:6)
757
                | SetBitField (vStart, 9: 9, 7:7);
758
        newmode.crtc[0x9] = SetBitField (vBlankStart, 9: 9, 5:5)
759
                | SetBit (6);
760
        newmode.crtc[0x10] = Set8Bits (vStart);
761
        newmode.crtc[0x11] = SetBitField (vEnd, 3: 0, 3:0)
762
                | SetBit (5);
763
        newmode.crtc[0x12] = Set8Bits (vDisplay);
764
        newmode.crtc[0x13] = (width / 8) * ((bpp + 1) / 8);
765
        newmode.crtc[0x15] = Set8Bits (vBlankStart);
766
        newmode.crtc[0x16] = Set8Bits (vBlankEnd);
767
 
768
        newmode.ext.screen = SetBitField(hBlankEnd,6:6,4:4)
769
                | SetBitField(vBlankStart,10:10,3:3)
770
                | SetBitField(vStart,10:10,2:2)
771
                | SetBitField(vDisplay,10:10,1:1)
772
                | SetBitField(vTotal,10:10,0:0);
773
        newmode.ext.horiz  = SetBitField(hTotal,8:8,0:0)
774
                | SetBitField(hDisplay,8:8,1:1)
775
                | SetBitField(hBlankStart,8:8,2:2)
776
                | SetBitField(hStart,8:8,3:3);
777
        newmode.ext.extra  = SetBitField(vTotal,11:11,0:0)
778
                | SetBitField(vDisplay,11:11,2:2)
779
                | SetBitField(vStart,11:11,4:4)
780
                | SetBitField(vBlankStart,11:11,6:6);
781
 
782
        if ((info->var.vmode & FB_VMODE_MASK) == FB_VMODE_INTERLACED) {
783
                int tmp = (hTotal >> 1) & ~1;
784
                newmode.ext.interlace = Set8Bits(tmp);
785
                newmode.ext.horiz |= SetBitField(tmp, 8:8,4:4);
786
        } else
787
                newmode.ext.interlace = 0xff; /* interlace off */
788
 
789
        if (par->riva.Architecture >= NV_ARCH_10)
790
                par->riva.CURSOR = (U032 *)(info->screen_base + par->riva.CursorStart);
791
 
792
        if (info->var.sync & FB_SYNC_HOR_HIGH_ACT)
793
                newmode.misc_output &= ~0x40;
794
        else
795
                newmode.misc_output |= 0x40;
796
        if (info->var.sync & FB_SYNC_VERT_HIGH_ACT)
797
                newmode.misc_output &= ~0x80;
798
        else
799
                newmode.misc_output |= 0x80;   
800
 
801
        par->riva.CalcStateExt(&par->riva, &newmode.ext, bpp, width,
802
                                  hDisplaySize, height, dotClock);
803
 
804
        newmode.ext.scale = par->riva.PRAMDAC[0x00000848/4] & 0xfff000ff;
805
        if (par->FlatPanel == 1) {
806
                newmode.ext.pixel |= (1 << 7);
807
                newmode.ext.scale |= (1 << 8);
808
        }
809
        if (par->SecondCRTC) {
810
                newmode.ext.head  = par->riva.PCRTC0[0x00000860/4] & ~0x00001000;
811
                newmode.ext.head2 = par->riva.PCRTC0[0x00002860/4] | 0x00001000;
812
                newmode.ext.crtcOwner = 3;
813
                newmode.ext.pllsel |= 0x20000800;
814
                newmode.ext.vpll2 = newmode.ext.vpll;
815
        } else if (par->riva.twoHeads) {
816
                newmode.ext.head  =  par->riva.PCRTC0[0x00000860/4] | 0x00001000;
817
                newmode.ext.head2 =  par->riva.PCRTC0[0x00002860/4] & ~0x00001000;
818
                newmode.ext.crtcOwner = 0;
819
                newmode.ext.vpll2 = par->riva.PRAMDAC0[0x00000520/4];
820
        }
821
        if (par->FlatPanel == 1) {
822
                newmode.ext.pixel |= (1 << 7);
823
                newmode.ext.scale |= (1 << 8);
824
        }
825
        newmode.ext.cursorConfig = 0x02000100;
826
        par->current_state = newmode;
827
        riva_load_state(par, &par->current_state);
828
        par->riva.LockUnlock(&par->riva, 0); /* important for HW cursor */
829
        rivafb_blank(0, info);
830
}
831
 
832
/**
833
 * rivafb_do_maximize -
834
 * @info: pointer to fb_info object containing info for current riva board
835
 * @var:
836
 * @nom:
837
 * @den:
838
 *
839
 * DESCRIPTION:
840
 * .
841
 *
842
 * RETURNS:
843
 * -EINVAL on failure, 0 on success
844
 *
845
 *
846
 * CALLED FROM:
847
 * rivafb_check_var()
848
 */
849
static int rivafb_do_maximize(struct fb_info *info,
850
                              struct fb_var_screeninfo *var,
851
                              int nom, int den)
852
{
853
        static struct {
854
                int xres, yres;
855
        } modes[] = {
856
                {1600, 1280},
857
                {1280, 1024},
858
                {1024, 768},
859
                {800, 600},
860
                {640, 480},
861
                {-1, -1}
862
        };
863
        int i;
864
 
865
        /* use highest possible virtual resolution */
866
        if (var->xres_virtual == -1 && var->yres_virtual == -1) {
867
                printk(KERN_WARNING PFX
868
                       "using maximum available virtual resolution\n");
869
                for (i = 0; modes[i].xres != -1; i++) {
870
                        if (modes[i].xres * nom / den * modes[i].yres <
871
                            info->fix.smem_len / 2)
872
                                break;
873
                }
874
                if (modes[i].xres == -1) {
875
                        printk(KERN_ERR PFX
876
                               "could not find a virtual resolution that fits into video memory!!\n");
877
                        DPRINTK("EXIT - EINVAL error\n");
878
                        return -EINVAL;
879
                }
880
                var->xres_virtual = modes[i].xres;
881
                var->yres_virtual = modes[i].yres;
882
 
883
                printk(KERN_INFO PFX
884
                       "virtual resolution set to maximum of %dx%d\n",
885
                       var->xres_virtual, var->yres_virtual);
886
        } else if (var->xres_virtual == -1) {
887
                var->xres_virtual = (info->fix.smem_len * den /
888
                        (nom * var->yres_virtual * 2)) & ~15;
889
                printk(KERN_WARNING PFX
890
                       "setting virtual X resolution to %d\n", var->xres_virtual);
891
        } else if (var->yres_virtual == -1) {
892
                var->xres_virtual = (var->xres_virtual + 15) & ~15;
893
                var->yres_virtual = info->fix.smem_len * den /
894
                        (nom * var->xres_virtual * 2);
895
                printk(KERN_WARNING PFX
896
                       "setting virtual Y resolution to %d\n", var->yres_virtual);
897
        } else {
898
                var->xres_virtual = (var->xres_virtual + 15) & ~15;
899
                if (var->xres_virtual * nom / den * var->yres_virtual > info->fix.smem_len) {
900
                        printk(KERN_ERR PFX
901
                               "mode %dx%dx%d rejected...resolution too high to fit into video memory!\n",
902
                               var->xres, var->yres, var->bits_per_pixel);
903
                        DPRINTK("EXIT - EINVAL error\n");
904
                        return -EINVAL;
905
                }
906
        }
907
 
908
        if (var->xres_virtual * nom / den >= 8192) {
909
                printk(KERN_WARNING PFX
910
                       "virtual X resolution (%d) is too high, lowering to %d\n",
911
                       var->xres_virtual, 8192 * den / nom - 16);
912
                var->xres_virtual = 8192 * den / nom - 16;
913
        }
914
 
915
        if (var->xres_virtual < var->xres) {
916
                printk(KERN_ERR PFX
917
                       "virtual X resolution (%d) is smaller than real\n", var->xres_virtual);
918
                return -EINVAL;
919
        }
920
 
921
        if (var->yres_virtual < var->yres) {
922
                printk(KERN_ERR PFX
923
                       "virtual Y resolution (%d) is smaller than real\n", var->yres_virtual);
924
                return -EINVAL;
925
        }
926
        return 0;
927
}
928
 
929
/* acceleration routines */
930
inline void wait_for_idle(struct riva_par *par)
931
{
932
        while (par->riva.Busy(&par->riva));
933
}
934
 
935
/* set copy ROP, no mask */
936
static void riva_setup_ROP(struct riva_par *par)
937
{
938
        RIVA_FIFO_FREE(par->riva, Patt, 5);
939
        par->riva.Patt->Shape = 0;
940
        par->riva.Patt->Color0 = 0xffffffff;
941
        par->riva.Patt->Color1 = 0xffffffff;
942
        par->riva.Patt->Monochrome[0] = 0xffffffff;
943
        par->riva.Patt->Monochrome[1] = 0xffffffff;
944
 
945
        RIVA_FIFO_FREE(par->riva, Rop, 1);
946
        par->riva.Rop->Rop3 = 0xCC;
947
}
948
 
949
void riva_setup_accel(struct riva_par *par)
950
{
951
        RIVA_FIFO_FREE(par->riva, Clip, 2);
952
        par->riva.Clip->TopLeft     = 0x0;
953
        par->riva.Clip->WidthHeight = 0x80008000;
954
        riva_setup_ROP(par);
955
        wait_for_idle(par);
956
}
957
 
958
/**
959
 * riva_get_cmap_len - query current color map length
960
 * @var: standard kernel fb changeable data
961
 *
962
 * DESCRIPTION:
963
 * Get current color map length.
964
 *
965
 * RETURNS:
966
 * Length of color map
967
 *
968
 * CALLED FROM:
969
 * rivafb_setcolreg()
970
 */
971
static int riva_get_cmap_len(const struct fb_var_screeninfo *var)
972
{
973
        int rc = 256;           /* reasonable default */
974
 
975
        switch (var->green.length) {
976
        case 8:
977
                rc = 256;       /* 256 entries (2^8), 8 bpp and RGB8888 */
978
                break;
979
        case 5:
980
                rc = 32;        /* 32 entries (2^5), 16 bpp, RGB555 */
981
                break;
982
        case 6:
983
                rc = 64;        /* 64 entries (2^6), 16 bpp, RGB565 */
984
                break;         
985
        default:
986
                /* should not occur */
987
                break;
988
        }
989
        return rc;
990
}
991
 
992
/* ------------------------------------------------------------------------- *
993
 *
994
 * framebuffer operations
995
 *
996
 * ------------------------------------------------------------------------- */
997
 
998
static int rivafb_open(struct fb_info *info, int user)
999
{
1000
        struct riva_par *par = (struct riva_par *) info->par;
1001
        int cnt = atomic_read(&par->ref_count);
1002
 
1003
        if (!cnt) {
1004
                memset(&par->state, 0, sizeof(struct vgastate));
1005
                par->state.flags = VGA_SAVE_MODE  | VGA_SAVE_FONTS;
1006
                /* save the DAC for Riva128 */
1007
                if (par->riva.Architecture == NV_ARCH_03)
1008
                        par->state.flags |= VGA_SAVE_CMAP;
1009
                save_vga(&par->state);
1010
 
1011
                RivaGetConfig(&par->riva, par->Chipset);
1012
                /* vgaHWunlock() + riva unlock (0x7F) */
1013
                CRTCout(par, 0x11, 0xFF);
1014
                par->riva.LockUnlock(&par->riva, 0);
1015
 
1016
                riva_save_state(par, &par->initial_state);
1017
        }
1018
        atomic_inc(&par->ref_count);
1019
        return 0;
1020
}
1021
 
1022
static int rivafb_release(struct fb_info *info, int user)
1023
{
1024
        struct riva_par *par = (struct riva_par *) info->par;
1025
        int cnt = atomic_read(&par->ref_count);
1026
 
1027
        if (!cnt)
1028
                return -EINVAL;
1029
        if (cnt == 1) {
1030
                par->riva.LockUnlock(&par->riva, 0);
1031
                par->riva.LoadStateExt(&par->riva, &par->initial_state.ext);
1032
                riva_load_state(par, &par->initial_state);
1033
                restore_vga(&par->state);
1034
                par->riva.LockUnlock(&par->riva, 1);
1035
        }
1036
        atomic_dec(&par->ref_count);
1037
        return 0;
1038
}
1039
 
1040
static int rivafb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
1041
{
1042
        int nom, den;           /* translating from pixels->bytes */
1043
 
1044
        switch (var->bits_per_pixel) {
1045
        case 1 ... 8:
1046
                var->red.offset = var->green.offset = var->blue.offset = 0;
1047
                var->red.length = var->green.length = var->blue.length = 8;
1048
                var->bits_per_pixel = 8;
1049
                nom = den = 1;
1050
                break;
1051
        case 9 ... 15:
1052
                var->green.length = 5;
1053
                /* fall through */
1054
        case 16:
1055
                var->bits_per_pixel = 16;
1056
                if (var->green.length == 5) {
1057
                        /* 0rrrrrgg gggbbbbb */
1058
                        var->red.offset = 10;
1059
                        var->green.offset = 5;
1060
                        var->blue.offset = 0;
1061
                        var->red.length = 5;
1062
                        var->green.length = 5;
1063
                        var->blue.length = 5;
1064
                } else {
1065
                        /* rrrrrggg gggbbbbb */
1066
                        var->red.offset = 11;
1067
                        var->green.offset = 5;
1068
                        var->blue.offset = 0;
1069
                        var->red.length = 5;
1070
                        var->green.length = 6;
1071
                        var->blue.length = 5;
1072
                }
1073
                nom = 2;
1074
                den = 1;
1075
                break;
1076
        case 17 ... 32:
1077
                var->red.length = var->green.length = var->blue.length = 8;
1078
                var->bits_per_pixel = 32;
1079
                var->red.offset = 16;
1080
                var->green.offset = 8;
1081
                var->blue.offset = 0;
1082
                nom = 4;
1083
                den = 1;
1084
                break;
1085
        default:
1086
                printk(KERN_ERR PFX
1087
                       "mode %dx%dx%d rejected...color depth not supported.\n",
1088
                       var->xres, var->yres, var->bits_per_pixel);
1089
                DPRINTK("EXIT, returning -EINVAL\n");
1090
                return -EINVAL;
1091
        }
1092
 
1093
        if (rivafb_do_maximize(info, var, nom, den) < 0)
1094
                return -EINVAL;
1095
 
1096
        if (var->xoffset < 0)
1097
                var->xoffset = 0;
1098
        if (var->yoffset < 0)
1099
                var->yoffset = 0;
1100
 
1101
        /* truncate xoffset and yoffset to maximum if too high */
1102
        if (var->xoffset > var->xres_virtual - var->xres)
1103
                var->xoffset = var->xres_virtual - var->xres - 1;
1104
 
1105
        if (var->yoffset > var->yres_virtual - var->yres)
1106
                var->yoffset = var->yres_virtual - var->yres - 1;
1107
 
1108
        var->red.msb_right =
1109
            var->green.msb_right =
1110
            var->blue.msb_right =
1111
            var->transp.offset = var->transp.length = var->transp.msb_right = 0;
1112
        return 0;
1113
}
1114
 
1115
static int rivafb_set_par(struct fb_info *info)
1116
{
1117
        struct riva_par *par = (struct riva_par *) info->par;
1118
 
1119
        riva_load_video_mode(info);
1120
        riva_setup_accel(par);
1121
 
1122
        info->fix.line_length = (info->var.xres_virtual * (info->var.bits_per_pixel >> 3));
1123
        info->fix.visual = (info->var.bits_per_pixel == 8) ?
1124
                                FB_VISUAL_PSEUDOCOLOR : FB_VISUAL_DIRECTCOLOR;
1125
        return 0;
1126
}
1127
 
1128
/**
1129
 * rivafb_pan_display
1130
 * @var: standard kernel fb changeable data
1131
 * @con: TODO
1132
 * @info: pointer to fb_info object containing info for current riva board
1133
 *
1134
 * DESCRIPTION:
1135
 * Pan (or wrap, depending on the `vmode' field) the display using the
1136
 * `xoffset' and `yoffset' fields of the `var' structure.
1137
 * If the values don't fit, return -EINVAL.
1138
 *
1139
 * This call looks only at xoffset, yoffset and the FB_VMODE_YWRAP flag
1140
 */
1141
static int rivafb_pan_display(struct fb_var_screeninfo *var,
1142
                              struct fb_info *info)
1143
{
1144
        struct riva_par *par = (struct riva_par *)info->par;
1145
        unsigned int base;
1146
 
1147
        if (var->xoffset > (var->xres_virtual - var->xres))
1148
                return -EINVAL;
1149
        if (var->yoffset > (var->yres_virtual - var->yres))
1150
                return -EINVAL;
1151
 
1152
        if (var->vmode & FB_VMODE_YWRAP) {
1153
                if (var->yoffset < 0
1154
                    || var->yoffset >= info->var.yres_virtual
1155
                    || var->xoffset) return -EINVAL;
1156
        } else {
1157
                if (var->xoffset + info->var.xres > info->var.xres_virtual ||
1158
                    var->yoffset + info->var.yres > info->var.yres_virtual)
1159
                        return -EINVAL;
1160
        }
1161
 
1162
        base = var->yoffset * info->fix.line_length + var->xoffset;
1163
 
1164
        par->riva.SetStartAddress(&par->riva, base);
1165
 
1166
        info->var.xoffset = var->xoffset;
1167
        info->var.yoffset = var->yoffset;
1168
 
1169
        if (var->vmode & FB_VMODE_YWRAP)
1170
                info->var.vmode |= FB_VMODE_YWRAP;
1171
        else
1172
                info->var.vmode &= ~FB_VMODE_YWRAP;
1173
        return 0;
1174
}
1175
 
1176
static int rivafb_blank(int blank, struct fb_info *info)
1177
{
1178
        struct riva_par *par= (struct riva_par *)info->par;
1179
        unsigned char tmp, vesa;
1180
 
1181
        tmp = SEQin(par, 0x01) & ~0x20; /* screen on/off */
1182
        vesa = CRTCin(par, 0x1a) & ~0xc0;       /* sync on/off */
1183
 
1184
        if (blank) {
1185
                tmp |= 0x20;
1186
                switch (blank - 1) {
1187
                case VESA_NO_BLANKING:
1188
                        break;
1189
                case VESA_VSYNC_SUSPEND:
1190
                        vesa |= 0x80;
1191
                        break;
1192
                case VESA_HSYNC_SUSPEND:
1193
                        vesa |= 0x40;
1194
                        break;
1195
                case VESA_POWERDOWN:
1196
                        vesa |= 0xc0;
1197
                        break;
1198
                }
1199
        }
1200
        SEQout(par, 0x01, tmp);
1201
        CRTCout(par, 0x1a, vesa);
1202
        return 0;
1203
}
1204
 
1205
/**
1206
 * rivafb_setcolreg
1207
 * @regno: register index
1208
 * @red: red component
1209
 * @green: green component
1210
 * @blue: blue component
1211
 * @transp: transparency
1212
 * @info: pointer to fb_info object containing info for current riva board
1213
 *
1214
 * DESCRIPTION:
1215
 * Set a single color register. The values supplied have a 16 bit
1216
 * magnitude.
1217
 *
1218
 * RETURNS:
1219
 * Return != 0 for invalid regno.
1220
 *
1221
 * CALLED FROM:
1222
 * fbcmap.c:fb_set_cmap()
1223
 */
1224
static int rivafb_setcolreg(unsigned regno, unsigned red, unsigned green,
1225
                          unsigned blue, unsigned transp,
1226
                          struct fb_info *info)
1227
{
1228
        struct riva_par *par = (struct riva_par *)info->par;
1229
        RIVA_HW_INST *chip = &par->riva;
1230
        int i;
1231
 
1232
        if (regno >= riva_get_cmap_len(&info->var))
1233
                return -EINVAL;
1234
 
1235
        if (info->var.grayscale) {
1236
                /* gray = 0.30*R + 0.59*G + 0.11*B */
1237
                red = green = blue =
1238
                    (red * 77 + green * 151 + blue * 28) >> 8;
1239
        }
1240
 
1241
        switch (info->var.bits_per_pixel) {
1242
        case 8:
1243
                /* "transparent" stuff is completely ignored. */
1244
                riva_wclut(chip, regno, red >> 8, green >> 8, blue >> 8);
1245
                break;
1246
        case 16:
1247
                if (info->var.green.length == 5) {
1248
                        if (regno < 16) {
1249
                                /* 0rrrrrgg gggbbbbb */
1250
                                ((u32 *)info->pseudo_palette)[regno] =
1251
                                        ((red & 0xf800) >> 1) |
1252
                                        ((green & 0xf800) >> 6) |
1253
                                        ((blue & 0xf800) >> 11);
1254
                        }
1255
                        for (i = 0; i < 8; i++)
1256
                                riva_wclut(chip, regno*8+i, red >> 8,
1257
                                           green >> 8, blue >> 8);
1258
                } else {
1259
                        u8 r, g, b;
1260
 
1261
                        if (regno < 16) {
1262
                                /* rrrrrggg gggbbbbb */
1263
                                ((u32 *)info->pseudo_palette)[regno] =
1264
                                        ((red & 0xf800) >> 0) |
1265
                                        ((green & 0xf800) >> 5) |
1266
                                        ((blue & 0xf800) >> 11);
1267
                        }
1268
                        if (regno < 32) {
1269
                                for (i = 0; i < 8; i++) {
1270
                                        riva_wclut(chip, regno*8+i, red >> 8,
1271
                                                   green >> 8, blue >> 8);
1272
                                }
1273
                        }
1274
                        for (i = 0; i < 4; i++) {
1275
                                riva_rclut(chip, regno*2+i, &r, &g, &b);
1276
                                riva_wclut(chip, regno*4+i, r, green >> 8, b);
1277
                        }
1278
                }
1279
                break;
1280
        case 32:
1281
                if (regno < 16) {
1282
                        ((u32 *)info->pseudo_palette)[regno] =
1283
                                ((red & 0xff00) << 8) |
1284
                                ((green & 0xff00)) | ((blue & 0xff00) >> 8);
1285
 
1286
                }
1287
                riva_wclut(chip, regno, red >> 8, green >> 8, blue >> 8);
1288
                break;
1289
        default:
1290
                /* do nothing */
1291
                break;
1292
        }
1293
        return 0;
1294
}
1295
 
1296
/**
1297
 * rivafb_fillrect - hardware accelerated color fill function
1298
 * @info: pointer to fb_info structure
1299
 * @rect: pointer to fb_fillrect structure
1300
 *
1301
 * DESCRIPTION:
1302
 * This function fills up a region of framebuffer memory with a solid
1303
 * color with a choice of two different ROP's, copy or invert.
1304
 *
1305
 * CALLED FROM:
1306
 * framebuffer hook
1307
 */
1308
static void rivafb_fillrect(struct fb_info *info, const struct fb_fillrect *rect)
1309
{
1310
        struct riva_par *par = (struct riva_par *) info->par;
1311
        u_int color, rop = 0;
1312
 
1313
        if (info->var.bits_per_pixel == 8)
1314
                color = rect->color;
1315
        else
1316
                color = ((u32 *)info->pseudo_palette)[rect->color];
1317
 
1318
        switch (rect->rop) {
1319
        case ROP_XOR:
1320
                rop = 0x66;
1321
                break;
1322
        case ROP_COPY:
1323
        default:
1324
                rop = 0xCC;
1325
                break;
1326
        }
1327
 
1328
        RIVA_FIFO_FREE(par->riva, Rop, 1);
1329
        par->riva.Rop->Rop3 = rop;
1330
 
1331
        RIVA_FIFO_FREE(par->riva, Bitmap, 1);
1332
        par->riva.Bitmap->Color1A = color;
1333
 
1334
        RIVA_FIFO_FREE(par->riva, Bitmap, 2);
1335
        par->riva.Bitmap->UnclippedRectangle[0].TopLeft =
1336
                        (rect->dx << 16) | rect->dy;
1337
        par->riva.Bitmap->UnclippedRectangle[0].WidthHeight =
1338
                        (rect->width << 16) | rect->height;
1339
        RIVA_FIFO_FREE(par->riva, Rop, 1);
1340
        par->riva.Rop->Rop3 = 0xCC;     // back to COPY
1341
}
1342
 
1343
/**
1344
 * rivafb_copyarea - hardware accelerated blit function
1345
 * @info: pointer to fb_info structure
1346
 * @region: pointer to fb_copyarea structure
1347
 *
1348
 * DESCRIPTION:
1349
 * This copies an area of pixels from one location to another
1350
 *
1351
 * CALLED FROM:
1352
 * framebuffer hook
1353
 */
1354
static void rivafb_copyarea(struct fb_info *info, const struct fb_copyarea *region)
1355
{
1356
        struct riva_par *par = (struct riva_par *) info->par;
1357
 
1358
        RIVA_FIFO_FREE(par->riva, Blt, 3);
1359
        par->riva.Blt->TopLeftSrc  = (region->sy << 16) | region->sx;
1360
        par->riva.Blt->TopLeftDst  = (region->dy << 16) | region->dx;
1361
        par->riva.Blt->WidthHeight = (region->height << 16) | region->width;
1362
        wait_for_idle(par);
1363
}
1364
 
1365
static inline void convert_bgcolor_16(u32 *col)
1366
{
1367
        *col = ((*col & 0x00007C00) << 9)
1368
                | ((*col & 0x000003E0) << 6)
1369
                | ((*col & 0x0000001F) << 3)
1370
                |          0xFF000000;
1371
}
1372
 
1373
/**
1374
 * rivafb_imageblit: hardware accelerated color expand function
1375
 * @info: pointer to fb_info structure
1376
 * @image: pointer to fb_image structure
1377
 *
1378
 * DESCRIPTION:
1379
 * If the source is a monochrome bitmap, the function fills up a a region
1380
 * of framebuffer memory with pixels whose color is determined by the bit
1381
 * setting of the bitmap, 1 - foreground, 0 - background.
1382
 *
1383
 * If the source is not a monochrome bitmap, color expansion is not done.
1384
 * In this case, it is channeled to a software function.
1385
 *
1386
 * CALLED FROM:
1387
 * framebuffer hook
1388
 */
1389
static void rivafb_imageblit(struct fb_info *info,
1390
                             const struct fb_image *image)
1391
{
1392
        struct riva_par *par = (struct riva_par *) info->par;
1393
        u32 fgx = 0, bgx = 0, width, tmp;
1394
        u8 *cdat = (u8 *) image->data;
1395
        volatile u32 *d;
1396
        int i, size;
1397
 
1398
        if (image->depth != 1) {
1399
                cfb_imageblit(info, image);
1400
                return;
1401
        }
1402
 
1403
        switch (info->var.bits_per_pixel) {
1404
        case 8:
1405
                fgx = image->fg_color;
1406
                bgx = image->bg_color;
1407
                break;
1408
        case 16:
1409
                fgx = ((u32 *)info->pseudo_palette)[image->fg_color];
1410
                bgx = ((u32 *)info->pseudo_palette)[image->bg_color];
1411
                if (info->var.green.length == 6)
1412
                        convert_bgcolor_16(&bgx);      
1413
                break;
1414
        case 32:
1415
                fgx = ((u32 *)info->pseudo_palette)[image->fg_color];
1416
                bgx = ((u32 *)info->pseudo_palette)[image->bg_color];
1417
                break;
1418
        }
1419
 
1420
        RIVA_FIFO_FREE(par->riva, Bitmap, 7);
1421
        par->riva.Bitmap->ClipE.TopLeft     =
1422
                (image->dy << 16) | (image->dx & 0xFFFF);
1423
        par->riva.Bitmap->ClipE.BottomRight =
1424
                (((image->dy + image->height) << 16) |
1425
                 ((image->dx + image->width) & 0xffff));
1426
        par->riva.Bitmap->Color0E           = bgx;
1427
        par->riva.Bitmap->Color1E           = fgx;
1428
        par->riva.Bitmap->WidthHeightInE    =
1429
                (image->height << 16) | ((image->width + 31) & ~31);
1430
        par->riva.Bitmap->WidthHeightOutE   =
1431
                (image->height << 16) | ((image->width + 31) & ~31);
1432
        par->riva.Bitmap->PointE            =
1433
                (image->dy << 16) | (image->dx & 0xFFFF);
1434
 
1435
        d = &par->riva.Bitmap->MonochromeData01E;
1436
 
1437
        width = (image->width + 31)/32;
1438
        size = width * image->height;
1439
        while (size >= 16) {
1440
                RIVA_FIFO_FREE(par->riva, Bitmap, 16);
1441
                for (i = 0; i < 16; i++) {
1442
                        tmp = *((u32 *)cdat)++;
1443
                        reverse_order(&tmp);
1444
                        d[i] = tmp;
1445
                }
1446
                size -= 16;
1447
        }
1448
        if (size) {
1449
                RIVA_FIFO_FREE(par->riva, Bitmap, size);
1450
                for (i = 0; i < size; i++) {
1451
                        tmp = *((u32 *) cdat)++;
1452
                        reverse_order(&tmp);
1453
                        d[i] = tmp;
1454
                }
1455
        }
1456
}
1457
 
1458
/**
1459
 * rivafb_cursor - hardware cursor function
1460
 * @info: pointer to info structure
1461
 * @cursor: pointer to fbcursor structure
1462
 *
1463
 * DESCRIPTION:
1464
 * A cursor function that supports displaying a cursor image via hardware.
1465
 * Within the kernel, copy and invert rops are supported.  If exported
1466
 * to user space, only the copy rop will be supported.
1467
 *
1468
 * CALLED FROM
1469
 * framebuffer hook
1470
 */
1471
static int rivafb_cursor(struct fb_info *info, struct fb_cursor *cursor)
1472
{
1473
        struct riva_par *par = (struct riva_par *) info->par;
1474
        u8 data[MAX_CURS * MAX_CURS/8];
1475
        u8 mask[MAX_CURS * MAX_CURS/8];
1476
        u16 fg, bg;
1477
        int i;
1478
 
1479
        par->riva.ShowHideCursor(&par->riva, 0);
1480
 
1481
        if (cursor->set & FB_CUR_SETPOS) {
1482
                u32 xx, yy, temp;
1483
 
1484
                info->cursor.image.dx = cursor->image.dx;
1485
                info->cursor.image.dy = cursor->image.dy;
1486
                yy = cursor->image.dy - info->var.yoffset;
1487
                xx = cursor->image.dx - info->var.xoffset;
1488
                temp = xx & 0xFFFF;
1489
                temp |= yy << 16;
1490
 
1491
                par->riva.PRAMDAC[0x0000300/4] = temp;
1492
        }
1493
 
1494
        if (cursor->set & FB_CUR_SETSIZE) {
1495
                info->cursor.image.height = cursor->image.height;
1496
                info->cursor.image.width = cursor->image.width;
1497
                memset_io(par->riva.CURSOR, 0, MAX_CURS * MAX_CURS * 2);
1498
        }
1499
 
1500
        if (cursor->set & FB_CUR_SETCMAP) {
1501
                info->cursor.image.bg_color = cursor->image.bg_color;
1502
                info->cursor.image.fg_color = cursor->image.fg_color;
1503
        }
1504
 
1505
        if (cursor->set & (FB_CUR_SETSHAPE | FB_CUR_SETCMAP)) {
1506
                u32 bg_idx = info->cursor.image.bg_color;
1507
                u32 fg_idx = info->cursor.image.fg_color;
1508
                u32 s_pitch = (info->cursor.image.width+7) >> 3;
1509
                u32 d_pitch = MAX_CURS/8;
1510
                u8 *dat = (u8 *) cursor->image.data;
1511
                u8 *msk = (u8 *) info->cursor.mask;
1512
                u8 src[64];    
1513
 
1514
                switch (info->cursor.rop) {
1515
                case ROP_XOR:
1516
                        for (i = 0; i < s_pitch * info->cursor.image.height; i++)
1517
                                        src[i] = dat[i] ^ msk[i];
1518
                        break;
1519
                case ROP_COPY:
1520
                default:
1521
                        for (i = 0; i < s_pitch * info->cursor.image.height; i++)
1522
 
1523
                                        src[i] = dat[i] & msk[i];
1524
                        break;
1525
                }
1526
 
1527
                move_buf_aligned(info, data, src, d_pitch, s_pitch, info->cursor.image.height);
1528
 
1529
                move_buf_aligned(info, mask, msk, d_pitch, s_pitch, info->cursor.image.height);
1530
 
1531
                bg = ((info->cmap.red[bg_idx] & 0xf8) << 7) |
1532
                     ((info->cmap.green[bg_idx] & 0xf8) << 2) |
1533
                     ((info->cmap.blue[bg_idx] & 0xf8) >> 3);
1534
 
1535
                fg = ((info->cmap.red[fg_idx] & 0xf8) << 7) |
1536
                     ((info->cmap.green[fg_idx] & 0xf8) << 2) |
1537
                     ((info->cmap.blue[fg_idx] & 0xf8) >> 3);
1538
 
1539
                par->riva.LockUnlock(&par->riva, 0);
1540
 
1541
                rivafb_load_cursor_image(par, data, mask, bg, fg,
1542
                                         info->cursor.image.width,
1543
                                         info->cursor.image.height);
1544
        }
1545
        if (info->cursor.enable)
1546
                par->riva.ShowHideCursor(&par->riva, 1);
1547
        return 0;
1548
}
1549
 
1550
static int rivafb_sync(struct fb_info *info)
1551
{
1552
        struct riva_par *par = (struct riva_par *)info->par;
1553
 
1554
        wait_for_idle(par);
1555
        return 0;
1556
}
1557
 
1558
/* ------------------------------------------------------------------------- *
1559
 *
1560
 * initialization helper functions
1561
 *
1562
 * ------------------------------------------------------------------------- */
1563
 
1564
/* kernel interface */
1565
static struct fb_ops riva_fb_ops = {
1566
        .owner          = THIS_MODULE,
1567
        .fb_open        = rivafb_open,
1568
        .fb_release     = rivafb_release,
1569
        .fb_check_var   = rivafb_check_var,
1570
        .fb_set_par     = rivafb_set_par,
1571
        .fb_setcolreg   = rivafb_setcolreg,
1572
        .fb_pan_display = rivafb_pan_display,
1573
        .fb_blank       = rivafb_blank,
1574
        .fb_fillrect    = rivafb_fillrect,
1575
        .fb_copyarea    = rivafb_copyarea,
1576
        .fb_imageblit   = rivafb_imageblit,
1577
        .fb_cursor      = rivafb_cursor,       
1578
        .fb_sync        = rivafb_sync,
1579
};
1580
 
1581
static int __devinit riva_set_fbinfo(struct fb_info *info)
1582
{
1583
        struct riva_par *par = (struct riva_par *) info->par;
1584
        unsigned int cmap_len;
1585
 
1586
        info->flags = FBINFO_FLAG_DEFAULT;
1587
        info->var = rivafb_default_var;
1588
        info->fix = rivafb_fix;
1589
        info->fbops = &riva_fb_ops;
1590
        info->pseudo_palette = pseudo_palette;
1591
 
1592
#ifndef MODULE
1593
        if (mode_option)
1594
                fb_find_mode(&info->var, info, mode_option,
1595
                             NULL, 0, NULL, 8);
1596
#endif
1597
        if (par->use_default_var)
1598
                /* We will use the modified default var */
1599
                info->var = rivafb_default_var;
1600
 
1601
        cmap_len = riva_get_cmap_len(&info->var);
1602
        fb_alloc_cmap(&info->cmap, cmap_len, 0);       
1603
 
1604
        info->pixmap.size = 64 * 1024;
1605
        info->pixmap.buf_align = 4;
1606
        info->pixmap.scan_align = 4;
1607
        info->pixmap.flags = FB_PIXMAP_SYSTEM;
1608
        return 0;
1609
}
1610
 
1611
#ifdef CONFIG_PPC_OF
1612
static int riva_get_EDID_OF(struct riva_par *par, struct pci_dev *pd)
1613
{
1614
        struct device_node *dp;
1615
        unsigned char *pedid = NULL;
1616
 
1617
        dp = pci_device_to_OF_node(pd);
1618
        pedid = (unsigned char *)get_property(dp, "EDID,B", 0);
1619
 
1620
        if (pedid) {
1621
                par->EDID = pedid;
1622
                return 1;
1623
        } else
1624
                return 0;
1625
}
1626
#endif /* CONFIG_PPC_OF */
1627
 
1628
static int riva_dfp_parse_EDID(struct riva_par *par)
1629
{
1630
        unsigned char *block = par->EDID;
1631
 
1632
        if (!block)
1633
                return 0;
1634
 
1635
        /* jump to detailed timing block section */
1636
        block += 54;
1637
 
1638
        par->clock = (block[0] + (block[1] << 8));
1639
        par->panel_xres = (block[2] + ((block[4] & 0xf0) << 4));
1640
        par->hblank = (block[3] + ((block[4] & 0x0f) << 8));
1641
        par->panel_yres = (block[5] + ((block[7] & 0xf0) << 4));
1642
        par->vblank = (block[6] + ((block[7] & 0x0f) << 8));
1643
        par->hOver_plus = (block[8] + ((block[11] & 0xc0) << 2));
1644
        par->hSync_width = (block[9] + ((block[11] & 0x30) << 4));
1645
        par->vOver_plus = ((block[10] >> 4) + ((block[11] & 0x0c) << 2));
1646
        par->vSync_width = ((block[10] & 0x0f) + ((block[11] & 0x03) << 4));
1647
        par->interlaced = ((block[17] & 0x80) >> 7);
1648
        par->synct = ((block[17] & 0x18) >> 3);
1649
        par->misc = ((block[17] & 0x06) >> 1);
1650
        par->hAct_high = par->vAct_high = 0;
1651
        if (par->synct == 3) {
1652
                if (par->misc & 2)
1653
                        par->hAct_high = 1;
1654
                if (par->misc & 1)
1655
                        par->vAct_high = 1;
1656
        }
1657
 
1658
        printk(KERN_INFO PFX
1659
                        "detected DFP panel size from EDID: %dx%d\n",
1660
                        par->panel_xres, par->panel_yres);
1661
        par->got_dfpinfo = 1;
1662
        return 1;
1663
}
1664
 
1665
static void riva_update_default_var(struct fb_info *info)
1666
{
1667
        struct fb_var_screeninfo *var = &rivafb_default_var;
1668
        struct riva_par *par = (struct riva_par *) info->par;
1669
 
1670
        var->xres = par->panel_xres;
1671
        var->yres = par->panel_yres;
1672
        var->xres_virtual = par->panel_xres;
1673
        var->yres_virtual = par->panel_yres;
1674
        var->xoffset = var->yoffset = 0;
1675
        var->bits_per_pixel = 8;
1676
        var->pixclock = 100000000 / par->clock;
1677
        var->left_margin = (par->hblank - par->hOver_plus - par->hSync_width);
1678
        var->right_margin = par->hOver_plus;
1679
        var->upper_margin = (par->vblank - par->vOver_plus - par->vSync_width);
1680
        var->lower_margin = par->vOver_plus;
1681
        var->hsync_len = par->hSync_width;
1682
        var->vsync_len = par->vSync_width;
1683
        var->sync = 0;
1684
 
1685
        if (par->synct == 3) {
1686
                if (par->hAct_high)
1687
                        var->sync |= FB_SYNC_HOR_HIGH_ACT;
1688
                if (par->vAct_high)
1689
                        var->sync |= FB_SYNC_VERT_HIGH_ACT;
1690
        }
1691
 
1692
        var->vmode = 0;
1693
        if (par->interlaced)
1694
                var->vmode |= FB_VMODE_INTERLACED;
1695
 
1696
        var->accel_flags |= FB_ACCELF_TEXT;
1697
 
1698
        par->use_default_var = 1;
1699
}
1700
 
1701
 
1702
static void riva_get_EDID(struct fb_info *info, struct pci_dev *pdev)
1703
{
1704
#ifdef CONFIG_PPC_OF
1705
        if (!riva_get_EDID_OF(info, pdev))
1706
                printk("rivafb: could not retrieve EDID from OF\n");
1707
#else
1708
        /* XXX use other methods later */
1709
#endif
1710
}
1711
 
1712
 
1713
static void riva_get_dfpinfo(struct fb_info *info)
1714
{
1715
        struct riva_par *par = (struct riva_par *) info->par;
1716
 
1717
        if (riva_dfp_parse_EDID(par))
1718
                riva_update_default_var(info);
1719
 
1720
        /* if user specified flatpanel, we respect that */
1721
        if (par->got_dfpinfo == 1)
1722
                par->FlatPanel = 1;
1723
}
1724
 
1725
/* ------------------------------------------------------------------------- *
1726
 *
1727
 * PCI bus
1728
 *
1729
 * ------------------------------------------------------------------------- */
1730
 
1731
static int __devinit rivafb_probe(struct pci_dev *pd,
1732
                                const struct pci_device_id *ent)
1733
{
1734
        struct riva_chip_info *rci = &riva_chip_info[ent->driver_data];
1735
        struct riva_par *default_par;
1736
        struct fb_info *info;
1737
 
1738
        assert(pd != NULL);
1739
        assert(rci != NULL);
1740
 
1741
        info = kmalloc(sizeof(struct fb_info), GFP_KERNEL);
1742
        if (!info)
1743
                goto err_out;
1744
 
1745
        default_par = kmalloc(sizeof(struct riva_par), GFP_KERNEL);
1746
        if (!default_par)
1747
                goto err_out_kfree;
1748
 
1749
        memset(info, 0, sizeof(struct fb_info));
1750
        memset(default_par, 0, sizeof(struct riva_par));
1751
 
1752
        info->pixmap.addr = kmalloc(64 * 1024, GFP_KERNEL);
1753
        if (info->pixmap.addr == NULL)
1754
                goto err_out_kfree1;
1755
        memset(info->pixmap.addr, 0, 64 * 1024);
1756
 
1757
        strcat(rivafb_fix.id, rci->name);
1758
        default_par->riva.Architecture = rci->arch_rev;
1759
 
1760
        default_par->Chipset = (pd->vendor << 16) | pd->device;
1761
        printk(KERN_INFO PFX "nVidia device/chipset %X\n",default_par->Chipset);
1762
 
1763
        default_par->FlatPanel = flatpanel;
1764
        if (flatpanel == 1)
1765
                printk(KERN_INFO PFX "flatpanel support enabled\n");
1766
        default_par->forceCRTC = forceCRTC;
1767
 
1768
        rivafb_fix.mmio_len = pci_resource_len(pd, 0);
1769
        rivafb_fix.smem_len = pci_resource_len(pd, 1);
1770
 
1771
        {
1772
                /* enable IO and mem if not already done */
1773
                unsigned short cmd;
1774
 
1775
                pci_read_config_word(pd, PCI_COMMAND, &cmd);
1776
                cmd |= (PCI_COMMAND_IO | PCI_COMMAND_MEMORY);
1777
                pci_write_config_word(pd, PCI_COMMAND, cmd);
1778
        }
1779
 
1780
        rivafb_fix.mmio_start = pci_resource_start(pd, 0);
1781
        rivafb_fix.smem_start = pci_resource_start(pd, 1);
1782
 
1783
        if (!request_mem_region(rivafb_fix.mmio_start,
1784
                                rivafb_fix.mmio_len, "rivafb")) {
1785
                printk(KERN_ERR PFX "cannot reserve MMIO region\n");
1786
                goto err_out_kfree2;
1787
        }
1788
 
1789
        default_par->ctrl_base = ioremap(rivafb_fix.mmio_start,
1790
                                         rivafb_fix.mmio_len);
1791
        if (!default_par->ctrl_base) {
1792
                printk(KERN_ERR PFX "cannot ioremap MMIO base\n");
1793
                goto err_out_free_base0;
1794
        }
1795
 
1796
        info->par = default_par;
1797
 
1798
        riva_get_EDID(info, pd);
1799
 
1800
        riva_get_dfpinfo(info);
1801
 
1802
        switch (default_par->riva.Architecture) {
1803
        case NV_ARCH_03:
1804
                /* Riva128's PRAMIN is in the "framebuffer" space
1805
                 * Since these cards were never made with more than 8 megabytes
1806
                 * we can safely allocate this separately.
1807
                 */
1808
                if (!request_mem_region(rivafb_fix.smem_start + 0x00C00000,
1809
                                         0x00008000, "rivafb")) {
1810
                        printk(KERN_ERR PFX "cannot reserve PRAMIN region\n");
1811
                        goto err_out_iounmap_ctrl;
1812
                }
1813
                default_par->riva.PRAMIN = ioremap(rivafb_fix.smem_start + 0x00C00000, 0x00008000);
1814
                if (!default_par->riva.PRAMIN) {
1815
                        printk(KERN_ERR PFX "cannot ioremap PRAMIN region\n");
1816
                        goto err_out_free_nv3_pramin;
1817
                }
1818
                rivafb_fix.accel = FB_ACCEL_NV3;
1819
                break;
1820
        case NV_ARCH_04:
1821
        case NV_ARCH_10:
1822
        case NV_ARCH_20:
1823
                default_par->riva.PCRTC0 = (unsigned *)(default_par->ctrl_base + 0x00600000);
1824
                default_par->riva.PRAMIN = (unsigned *)(default_par->ctrl_base + 0x00710000);
1825
                rivafb_fix.accel = FB_ACCEL_NV4;
1826
                break;
1827
        }
1828
 
1829
        riva_common_setup(default_par);
1830
 
1831
        if (default_par->riva.Architecture == NV_ARCH_03) {
1832
                default_par->riva.PCRTC = default_par->riva.PCRTC0 = default_par->riva.PGRAPH;
1833
        }
1834
 
1835
        rivafb_fix.smem_len = riva_get_memlen(default_par) * 1024;
1836
        default_par->dclk_max = riva_get_maxdclk(default_par) * 1000;
1837
 
1838
        if (!request_mem_region(rivafb_fix.smem_start,
1839
                                rivafb_fix.smem_len, "rivafb")) {
1840
                printk(KERN_ERR PFX "cannot reserve FB region\n");
1841
                goto err_out_iounmap_nv3_pramin;
1842
        }
1843
 
1844
        info->screen_base = ioremap(rivafb_fix.smem_start,
1845
                                    rivafb_fix.smem_len);
1846
        if (!info->screen_base) {
1847
                printk(KERN_ERR PFX "cannot ioremap FB base\n");
1848
                goto err_out_free_base1;
1849
        }
1850
 
1851
#ifdef CONFIG_MTRR
1852
        if (!nomtrr) {
1853
                default_par->mtrr.vram = mtrr_add(rivafb_fix.smem_start,
1854
                                                  rivafb_fix.smem_len,
1855
                                                  MTRR_TYPE_WRCOMB, 1);
1856
                if (default_par->mtrr.vram < 0) {
1857
                        printk(KERN_ERR PFX "unable to setup MTRR\n");
1858
                } else {
1859
                        default_par->mtrr.vram_valid = 1;
1860
                        /* let there be speed */
1861
                        printk(KERN_INFO PFX "RIVA MTRR set to ON\n");
1862
                }
1863
        }
1864
#endif /* CONFIG_MTRR */
1865
 
1866
        if (riva_set_fbinfo(info) < 0) {
1867
                printk(KERN_ERR PFX "error setting initial video mode\n");
1868
                goto err_out_iounmap_fb;
1869
        }
1870
 
1871
        if (register_framebuffer(info) < 0) {
1872
                printk(KERN_ERR PFX
1873
                        "error registering riva framebuffer\n");
1874
                goto err_out_iounmap_fb;
1875
        }
1876
 
1877
        pci_set_drvdata(pd, info);
1878
 
1879
        printk(KERN_INFO PFX
1880
                "PCI nVidia NV%x framebuffer ver %s (%s, %dMB @ 0x%lX)\n",
1881
                default_par->riva.Architecture,
1882
                RIVAFB_VERSION,
1883
                info->fix.id,
1884
                info->fix.smem_len / (1024 * 1024),
1885
                info->fix.smem_start);
1886
        return 0;
1887
 
1888
err_out_iounmap_fb:
1889
        iounmap(info->screen_base);
1890
err_out_free_base1:
1891
        release_mem_region(rivafb_fix.smem_start, rivafb_fix.smem_len);
1892
err_out_iounmap_nv3_pramin:
1893
        if (default_par->riva.Architecture == NV_ARCH_03)
1894
                iounmap((caddr_t)default_par->riva.PRAMIN);
1895
err_out_free_nv3_pramin:
1896
        if (default_par->riva.Architecture == NV_ARCH_03)
1897
                release_mem_region(rivafb_fix.smem_start + 0x00C00000, 0x00008000);
1898
err_out_iounmap_ctrl:
1899
        iounmap(default_par->ctrl_base);
1900
err_out_free_base0:
1901
        release_mem_region(rivafb_fix.mmio_start, rivafb_fix.mmio_len);
1902
err_out_kfree2:
1903
        kfree(info->pixmap.addr);
1904
err_out_kfree1:
1905
        kfree(default_par);
1906
err_out_kfree:
1907
        kfree(info);
1908
err_out:
1909
        return -ENODEV;
1910
}
1911
 
1912
static void __exit rivafb_remove(struct pci_dev *pd)
1913
{
1914
        struct fb_info *info = pci_get_drvdata(pd);
1915
        struct riva_par *par = (struct riva_par *) info->par;
1916
 
1917
        if (!info)
1918
                return;
1919
 
1920
        unregister_framebuffer(info);
1921
#ifdef CONFIG_MTRR
1922
        if (par->mtrr.vram_valid)
1923
                mtrr_del(par->mtrr.vram, info->fix.smem_start,
1924
                         info->fix.smem_len);
1925
#endif /* CONFIG_MTRR */
1926
 
1927
        iounmap(par->ctrl_base);
1928
        iounmap(info->screen_base);
1929
 
1930
        release_mem_region(info->fix.mmio_start,
1931
                           info->fix.mmio_len);
1932
        release_mem_region(info->fix.smem_start,
1933
                           info->fix.smem_len);
1934
 
1935
        if (par->riva.Architecture == NV_ARCH_03) {
1936
                iounmap((caddr_t)par->riva.PRAMIN);
1937
                release_mem_region(info->fix.smem_start + 0x00C00000, 0x00008000);
1938
        }
1939
        kfree(info->pixmap.addr);
1940
        kfree(par);
1941
        kfree(info);
1942
        pci_set_drvdata(pd, NULL);
1943
}
1944
 
1945
/* ------------------------------------------------------------------------- *
1946
 *
1947
 * initialization
1948
 *
1949
 * ------------------------------------------------------------------------- */
1950
 
1951
#ifndef MODULE
1952
int __init rivafb_setup(char *options)
1953
{
1954
        char *this_opt;
1955
 
1956
        if (!options || !*options)
1957
                return 0;
1958
 
1959
        while ((this_opt = strsep(&options, ",")) != NULL) {
1960
                if (!strncmp(this_opt, "forceCRTC", 9)) {
1961
                        char *p;
1962
 
1963
                        p = this_opt + 9;
1964
                        if (!*p || !*(++p)) continue;
1965
                        forceCRTC = *p - '0';
1966
                        if (forceCRTC < 0 || forceCRTC > 1)
1967
                                forceCRTC = -1;
1968
                } else if (!strncmp(this_opt, "flatpanel", 9)) {
1969
                        flatpanel = 1;
1970
#ifdef CONFIG_MTRR
1971
                } else if (!strncmp(this_opt, "nomtrr", 6)) {
1972
                        nomtrr = 1;
1973
#endif
1974
                } else
1975
                        mode_option = this_opt;
1976
        }
1977
        return 0;
1978
}
1979
#endif /* !MODULE */
1980
 
1981
static struct pci_driver rivafb_driver = {
1982
        .name           = "rivafb",
1983
        .id_table       = rivafb_pci_tbl,
1984
        .probe          = rivafb_probe,
1985
        .remove         = __exit_p(rivafb_remove),
1986
};
1987
 
1988
 
1989
 
1990
/* ------------------------------------------------------------------------- *
1991
 *
1992
 * modularization
1993
 *
1994
 * ------------------------------------------------------------------------- */
1995
 
1996
int __init rivafb_init(void)
1997
{
1998
        if (pci_register_driver(&rivafb_driver) > 0)
1999
                return 0;
2000
        pci_unregister_driver(&rivafb_driver);
2001
        return -ENODEV;
2002
}
2003
 
2004
 
2005
#ifdef MODULE
2006
static void __exit rivafb_exit(void)
2007
{
2008
        pci_unregister_driver(&rivafb_driver);
2009
}
2010
 
2011
module_init(rivafb_init);
2012
module_exit(rivafb_exit);
2013
 
2014
MODULE_PARM(flatpanel, "i");
2015
MODULE_PARM_DESC(flatpanel, "Enables experimental flat panel support for some chipsets. (0 or 1=enabled) (default=0)");
2016
MODULE_PARM(forceCRTC, "i");
2017
MODULE_PARM_DESC(forceCRTC, "Forces usage of a particular CRTC in case autodetection fails. (0 or 1) (default=autodetect)");
2018
 
2019
#ifdef CONFIG_MTRR
2020
MODULE_PARM(nomtrr, "i");
2021
MODULE_PARM_DESC(nomtrr, "Disables MTRR support (0 or 1=disabled) (default=0)");
2022
#endif
2023
#endif /* MODULE */
2024
 
2025
MODULE_AUTHOR("Ani Joshi, maintainer");
2026
MODULE_DESCRIPTION("Framebuffer driver for nVidia Riva 128, TNT, TNT2, and the GeForce series");
2027
MODULE_LICENSE("GPL");