cirrusfb: do not calculate line length twice
[linux-2.6.git] / drivers / video / cirrusfb.c
1 /*
2  * drivers/video/cirrusfb.c - driver for Cirrus Logic chipsets
3  *
4  * Copyright 1999-2001 Jeff Garzik <jgarzik@pobox.com>
5  *
6  * Contributors (thanks, all!)
7  *
8  *      David Eger:
9  *      Overhaul for Linux 2.6
10  *
11  *      Jeff Rugen:
12  *      Major contributions;  Motorola PowerStack (PPC and PCI) support,
13  *      GD54xx, 1280x1024 mode support, change MCLK based on VCLK.
14  *
15  *      Geert Uytterhoeven:
16  *      Excellent code review.
17  *
18  *      Lars Hecking:
19  *      Amiga updates and testing.
20  *
21  * Original cirrusfb author:  Frank Neumann
22  *
23  * Based on retz3fb.c and cirrusfb.c:
24  *      Copyright (C) 1997 Jes Sorensen
25  *      Copyright (C) 1996 Frank Neumann
26  *
27  ***************************************************************
28  *
29  * Format this code with GNU indent '-kr -i8 -pcs' options.
30  *
31  * This file is subject to the terms and conditions of the GNU General Public
32  * License.  See the file COPYING in the main directory of this archive
33  * for more details.
34  *
35  */
36
37 #include <linux/module.h>
38 #include <linux/kernel.h>
39 #include <linux/errno.h>
40 #include <linux/string.h>
41 #include <linux/mm.h>
42 #include <linux/slab.h>
43 #include <linux/delay.h>
44 #include <linux/fb.h>
45 #include <linux/init.h>
46 #include <asm/pgtable.h>
47
48 #ifdef CONFIG_ZORRO
49 #include <linux/zorro.h>
50 #endif
51 #ifdef CONFIG_PCI
52 #include <linux/pci.h>
53 #endif
54 #ifdef CONFIG_AMIGA
55 #include <asm/amigahw.h>
56 #endif
57 #ifdef CONFIG_PPC_PREP
58 #include <asm/machdep.h>
59 #define isPReP machine_is(prep)
60 #else
61 #define isPReP 0
62 #endif
63
64 #include <video/vga.h>
65 #include <video/cirrus.h>
66
67 /*****************************************************************
68  *
69  * debugging and utility macros
70  *
71  */
72
73 /* disable runtime assertions? */
74 /* #define CIRRUSFB_NDEBUG */
75
76 /* debugging assertions */
77 #ifndef CIRRUSFB_NDEBUG
78 #define assert(expr) \
79         if (!(expr)) { \
80                 printk("Assertion failed! %s,%s,%s,line=%d\n", \
81                 #expr, __FILE__, __func__, __LINE__); \
82         }
83 #else
84 #define assert(expr)
85 #endif
86
87 #define MB_ (1024 * 1024)
88
89 /*****************************************************************
90  *
91  * chipset information
92  *
93  */
94
95 /* board types */
96 enum cirrus_board {
97         BT_NONE = 0,
98         BT_SD64,
99         BT_PICCOLO,
100         BT_PICASSO,
101         BT_SPECTRUM,
102         BT_PICASSO4,    /* GD5446 */
103         BT_ALPINE,      /* GD543x/4x */
104         BT_GD5480,
105         BT_LAGUNA,      /* GD546x */
106 };
107
108 /*
109  * per-board-type information, used for enumerating and abstracting
110  * chip-specific information
111  * NOTE: MUST be in the same order as enum cirrus_board in order to
112  * use direct indexing on this array
113  * NOTE: '__initdata' cannot be used as some of this info
114  * is required at runtime.  Maybe separate into an init-only and
115  * a run-time table?
116  */
117 static const struct cirrusfb_board_info_rec {
118         char *name;             /* ASCII name of chipset */
119         long maxclock[5];               /* maximum video clock */
120         /* for  1/4bpp, 8bpp 15/16bpp, 24bpp, 32bpp - numbers from xorg code */
121         bool init_sr07 : 1; /* init SR07 during init_vgachip() */
122         bool init_sr1f : 1; /* write SR1F during init_vgachip() */
123         /* construct bit 19 of screen start address */
124         bool scrn_start_bit19 : 1;
125
126         /* initial SR07 value, then for each mode */
127         unsigned char sr07;
128         unsigned char sr07_1bpp;
129         unsigned char sr07_1bpp_mux;
130         unsigned char sr07_8bpp;
131         unsigned char sr07_8bpp_mux;
132
133         unsigned char sr1f;     /* SR1F VGA initial register value */
134 } cirrusfb_board_info[] = {
135         [BT_SD64] = {
136                 .name                   = "CL SD64",
137                 .maxclock               = {
138                         /* guess */
139                         /* the SD64/P4 have a higher max. videoclock */
140                         135100, 135100, 85500, 85500, 0
141                 },
142                 .init_sr07              = true,
143                 .init_sr1f              = true,
144                 .scrn_start_bit19       = true,
145                 .sr07                   = 0xF0,
146                 .sr07_1bpp              = 0xF0,
147                 .sr07_8bpp              = 0xF1,
148                 .sr1f                   = 0x20
149         },
150         [BT_PICCOLO] = {
151                 .name                   = "CL Piccolo",
152                 .maxclock               = {
153                         /* guess */
154                         90000, 90000, 90000, 90000, 90000
155                 },
156                 .init_sr07              = true,
157                 .init_sr1f              = true,
158                 .scrn_start_bit19       = false,
159                 .sr07                   = 0x80,
160                 .sr07_1bpp              = 0x80,
161                 .sr07_8bpp              = 0x81,
162                 .sr1f                   = 0x22
163         },
164         [BT_PICASSO] = {
165                 .name                   = "CL Picasso",
166                 .maxclock               = {
167                         /* guess */
168                         90000, 90000, 90000, 90000, 90000
169                 },
170                 .init_sr07              = true,
171                 .init_sr1f              = true,
172                 .scrn_start_bit19       = false,
173                 .sr07                   = 0x20,
174                 .sr07_1bpp              = 0x20,
175                 .sr07_8bpp              = 0x21,
176                 .sr1f                   = 0x22
177         },
178         [BT_SPECTRUM] = {
179                 .name                   = "CL Spectrum",
180                 .maxclock               = {
181                         /* guess */
182                         90000, 90000, 90000, 90000, 90000
183                 },
184                 .init_sr07              = true,
185                 .init_sr1f              = true,
186                 .scrn_start_bit19       = false,
187                 .sr07                   = 0x80,
188                 .sr07_1bpp              = 0x80,
189                 .sr07_8bpp              = 0x81,
190                 .sr1f                   = 0x22
191         },
192         [BT_PICASSO4] = {
193                 .name                   = "CL Picasso4",
194                 .maxclock               = {
195                         135100, 135100, 85500, 85500, 0
196                 },
197                 .init_sr07              = true,
198                 .init_sr1f              = false,
199                 .scrn_start_bit19       = true,
200                 .sr07                   = 0x20,
201                 .sr07_1bpp              = 0x20,
202                 .sr07_8bpp              = 0x21,
203                 .sr1f                   = 0
204         },
205         [BT_ALPINE] = {
206                 .name                   = "CL Alpine",
207                 .maxclock               = {
208                         /* for the GD5430.  GD5446 can do more... */
209                         85500, 85500, 50000, 28500, 0
210                 },
211                 .init_sr07              = true,
212                 .init_sr1f              = true,
213                 .scrn_start_bit19       = true,
214                 .sr07                   = 0xA0,
215                 .sr07_1bpp              = 0xA1,
216                 .sr07_1bpp_mux          = 0xA7,
217                 .sr07_8bpp              = 0xA1,
218                 .sr07_8bpp_mux          = 0xA7,
219                 .sr1f                   = 0x1C
220         },
221         [BT_GD5480] = {
222                 .name                   = "CL GD5480",
223                 .maxclock               = {
224                         135100, 200000, 200000, 135100, 135100
225                 },
226                 .init_sr07              = true,
227                 .init_sr1f              = true,
228                 .scrn_start_bit19       = true,
229                 .sr07                   = 0x10,
230                 .sr07_1bpp              = 0x11,
231                 .sr07_8bpp              = 0x11,
232                 .sr1f                   = 0x1C
233         },
234         [BT_LAGUNA] = {
235                 .name                   = "CL Laguna",
236                 .maxclock               = {
237                         /* guess */
238                         135100, 135100, 135100, 135100, 135100,
239                 },
240                 .init_sr07              = false,
241                 .init_sr1f              = false,
242                 .scrn_start_bit19       = true,
243         }
244 };
245
246 #ifdef CONFIG_PCI
247 #define CHIP(id, btype) \
248         { PCI_VENDOR_ID_CIRRUS, id, PCI_ANY_ID, PCI_ANY_ID, 0, 0, (btype) }
249
250 static struct pci_device_id cirrusfb_pci_table[] = {
251         CHIP(PCI_DEVICE_ID_CIRRUS_5436, BT_ALPINE),
252         CHIP(PCI_DEVICE_ID_CIRRUS_5434_8, BT_ALPINE),
253         CHIP(PCI_DEVICE_ID_CIRRUS_5434_4, BT_ALPINE),
254         CHIP(PCI_DEVICE_ID_CIRRUS_5430, BT_ALPINE), /* GD-5440 is same id */
255         CHIP(PCI_DEVICE_ID_CIRRUS_7543, BT_ALPINE),
256         CHIP(PCI_DEVICE_ID_CIRRUS_7548, BT_ALPINE),
257         CHIP(PCI_DEVICE_ID_CIRRUS_5480, BT_GD5480), /* MacPicasso likely */
258         CHIP(PCI_DEVICE_ID_CIRRUS_5446, BT_PICASSO4), /* Picasso 4 is 5446 */
259         CHIP(PCI_DEVICE_ID_CIRRUS_5462, BT_LAGUNA), /* CL Laguna */
260         CHIP(PCI_DEVICE_ID_CIRRUS_5464, BT_LAGUNA), /* CL Laguna 3D */
261         CHIP(PCI_DEVICE_ID_CIRRUS_5465, BT_LAGUNA), /* CL Laguna 3DA*/
262         { 0, }
263 };
264 MODULE_DEVICE_TABLE(pci, cirrusfb_pci_table);
265 #undef CHIP
266 #endif /* CONFIG_PCI */
267
268 #ifdef CONFIG_ZORRO
269 static const struct zorro_device_id cirrusfb_zorro_table[] = {
270         {
271                 .id             = ZORRO_PROD_HELFRICH_SD64_RAM,
272                 .driver_data    = BT_SD64,
273         }, {
274                 .id             = ZORRO_PROD_HELFRICH_PICCOLO_RAM,
275                 .driver_data    = BT_PICCOLO,
276         }, {
277                 .id     = ZORRO_PROD_VILLAGE_TRONIC_PICASSO_II_II_PLUS_RAM,
278                 .driver_data    = BT_PICASSO,
279         }, {
280                 .id             = ZORRO_PROD_GVP_EGS_28_24_SPECTRUM_RAM,
281                 .driver_data    = BT_SPECTRUM,
282         }, {
283                 .id             = ZORRO_PROD_VILLAGE_TRONIC_PICASSO_IV_Z3,
284                 .driver_data    = BT_PICASSO4,
285         },
286         { 0 }
287 };
288
289 static const struct {
290         zorro_id id2;
291         unsigned long size;
292 } cirrusfb_zorro_table2[] = {
293         [BT_SD64] = {
294                 .id2    = ZORRO_PROD_HELFRICH_SD64_REG,
295                 .size   = 0x400000
296         },
297         [BT_PICCOLO] = {
298                 .id2    = ZORRO_PROD_HELFRICH_PICCOLO_REG,
299                 .size   = 0x200000
300         },
301         [BT_PICASSO] = {
302                 .id2    = ZORRO_PROD_VILLAGE_TRONIC_PICASSO_II_II_PLUS_REG,
303                 .size   = 0x200000
304         },
305         [BT_SPECTRUM] = {
306                 .id2    = ZORRO_PROD_GVP_EGS_28_24_SPECTRUM_REG,
307                 .size   = 0x200000
308         },
309         [BT_PICASSO4] = {
310                 .id2    = 0,
311                 .size   = 0x400000
312         }
313 };
314 #endif /* CONFIG_ZORRO */
315
316 struct cirrusfb_regs {
317         int multiplexing;
318 };
319
320 #ifdef CIRRUSFB_DEBUG
321 enum cirrusfb_dbg_reg_class {
322         CRT,
323         SEQ
324 };
325 #endif          /* CIRRUSFB_DEBUG */
326
327 /* info about board */
328 struct cirrusfb_info {
329         u8 __iomem *regbase;
330         u8 __iomem *laguna_mmio;
331         enum cirrus_board btype;
332         unsigned char SFR;      /* Shadow of special function register */
333
334         struct cirrusfb_regs currentmode;
335         int blank_mode;
336         u32 pseudo_palette[16];
337
338         void (*unmap)(struct fb_info *info);
339 };
340
341 static int noaccel __devinitdata;
342 static char *mode_option __devinitdata = "640x480@60";
343
344 /****************************************************************************/
345 /**** BEGIN PROTOTYPES ******************************************************/
346
347 /*--- Interface used by the world ------------------------------------------*/
348 static int cirrusfb_init(void);
349 #ifndef MODULE
350 static int cirrusfb_setup(char *options);
351 #endif
352
353 static int cirrusfb_open(struct fb_info *info, int user);
354 static int cirrusfb_release(struct fb_info *info, int user);
355 static int cirrusfb_setcolreg(unsigned regno, unsigned red, unsigned green,
356                               unsigned blue, unsigned transp,
357                               struct fb_info *info);
358 static int cirrusfb_check_var(struct fb_var_screeninfo *var,
359                               struct fb_info *info);
360 static int cirrusfb_set_par(struct fb_info *info);
361 static int cirrusfb_pan_display(struct fb_var_screeninfo *var,
362                                 struct fb_info *info);
363 static int cirrusfb_blank(int blank_mode, struct fb_info *info);
364 static void cirrusfb_fillrect(struct fb_info *info,
365                               const struct fb_fillrect *region);
366 static void cirrusfb_copyarea(struct fb_info *info,
367                               const struct fb_copyarea *area);
368 static void cirrusfb_imageblit(struct fb_info *info,
369                                const struct fb_image *image);
370
371 /* function table of the above functions */
372 static struct fb_ops cirrusfb_ops = {
373         .owner          = THIS_MODULE,
374         .fb_open        = cirrusfb_open,
375         .fb_release     = cirrusfb_release,
376         .fb_setcolreg   = cirrusfb_setcolreg,
377         .fb_check_var   = cirrusfb_check_var,
378         .fb_set_par     = cirrusfb_set_par,
379         .fb_pan_display = cirrusfb_pan_display,
380         .fb_blank       = cirrusfb_blank,
381         .fb_fillrect    = cirrusfb_fillrect,
382         .fb_copyarea    = cirrusfb_copyarea,
383         .fb_imageblit   = cirrusfb_imageblit,
384 };
385
386 /*--- Internal routines ----------------------------------------------------*/
387 static void init_vgachip(struct fb_info *info);
388 static void switch_monitor(struct cirrusfb_info *cinfo, int on);
389 static void WGen(const struct cirrusfb_info *cinfo,
390                  int regnum, unsigned char val);
391 static unsigned char RGen(const struct cirrusfb_info *cinfo, int regnum);
392 static void AttrOn(const struct cirrusfb_info *cinfo);
393 static void WHDR(const struct cirrusfb_info *cinfo, unsigned char val);
394 static void WSFR(struct cirrusfb_info *cinfo, unsigned char val);
395 static void WSFR2(struct cirrusfb_info *cinfo, unsigned char val);
396 static void WClut(struct cirrusfb_info *cinfo, unsigned char regnum,
397                   unsigned char red, unsigned char green, unsigned char blue);
398 #if 0
399 static void RClut(struct cirrusfb_info *cinfo, unsigned char regnum,
400                   unsigned char *red, unsigned char *green,
401                   unsigned char *blue);
402 #endif
403 static void cirrusfb_WaitBLT(u8 __iomem *regbase);
404 static void cirrusfb_BitBLT(u8 __iomem *regbase, int bits_per_pixel,
405                             u_short curx, u_short cury,
406                             u_short destx, u_short desty,
407                             u_short width, u_short height,
408                             u_short line_length);
409 static void cirrusfb_RectFill(u8 __iomem *regbase, int bits_per_pixel,
410                               u_short x, u_short y,
411                               u_short width, u_short height,
412                               u_char color, u_short line_length);
413
414 static void bestclock(long freq, int *nom, int *den, int *div);
415
416 #ifdef CIRRUSFB_DEBUG
417 static void cirrusfb_dbg_reg_dump(struct fb_info *info, caddr_t regbase);
418 static void cirrusfb_dbg_print_regs(struct fb_info *info,
419                                     caddr_t regbase,
420                                     enum cirrusfb_dbg_reg_class reg_class, ...);
421 #endif /* CIRRUSFB_DEBUG */
422
423 /*** END   PROTOTYPES ********************************************************/
424 /*****************************************************************************/
425 /*** BEGIN Interface Used by the World ***************************************/
426
427 static int opencount;
428
429 /*--- Open /dev/fbx ---------------------------------------------------------*/
430 static int cirrusfb_open(struct fb_info *info, int user)
431 {
432         if (opencount++ == 0)
433                 switch_monitor(info->par, 1);
434         return 0;
435 }
436
437 /*--- Close /dev/fbx --------------------------------------------------------*/
438 static int cirrusfb_release(struct fb_info *info, int user)
439 {
440         if (--opencount == 0)
441                 switch_monitor(info->par, 0);
442         return 0;
443 }
444
445 /**** END   Interface used by the World *************************************/
446 /****************************************************************************/
447 /**** BEGIN Hardware specific Routines **************************************/
448
449 /* Check if the MCLK is not a better clock source */
450 static int cirrusfb_check_mclk(struct fb_info *info, long freq)
451 {
452         struct cirrusfb_info *cinfo = info->par;
453         long mclk = vga_rseq(cinfo->regbase, CL_SEQR1F) & 0x3f;
454
455         /* Read MCLK value */
456         mclk = (14318 * mclk) >> 3;
457         dev_dbg(info->device, "Read MCLK of %ld kHz\n", mclk);
458
459         /* Determine if we should use MCLK instead of VCLK, and if so, what we
460          * should divide it by to get VCLK
461          */
462
463         if (abs(freq - mclk) < 250) {
464                 dev_dbg(info->device, "Using VCLK = MCLK\n");
465                 return 1;
466         } else if (abs(freq - (mclk / 2)) < 250) {
467                 dev_dbg(info->device, "Using VCLK = MCLK/2\n");
468                 return 2;
469         }
470
471         return 0;
472 }
473
474 static int cirrusfb_check_var(struct fb_var_screeninfo *var,
475                               struct fb_info *info)
476 {
477         int yres;
478         /* memory size in pixels */
479         unsigned pixels = info->screen_size * 8 / var->bits_per_pixel;
480
481         switch (var->bits_per_pixel) {
482         case 1:
483                 var->red.offset = 0;
484                 var->red.length = 1;
485                 var->green = var->red;
486                 var->blue = var->red;
487                 break;
488
489         case 8:
490                 var->red.offset = 0;
491                 var->red.length = 6;
492                 var->green = var->red;
493                 var->blue = var->red;
494                 break;
495
496         case 16:
497                 if (isPReP) {
498                         var->red.offset = 2;
499                         var->green.offset = -3;
500                         var->blue.offset = 8;
501                 } else {
502                         var->red.offset = 10;
503                         var->green.offset = 5;
504                         var->blue.offset = 0;
505                 }
506                 var->red.length = 5;
507                 var->green.length = 5;
508                 var->blue.length = 5;
509                 break;
510
511         case 32:
512                 if (isPReP) {
513                         var->red.offset = 8;
514                         var->green.offset = 16;
515                         var->blue.offset = 24;
516                 } else {
517                         var->red.offset = 16;
518                         var->green.offset = 8;
519                         var->blue.offset = 0;
520                 }
521                 var->red.length = 8;
522                 var->green.length = 8;
523                 var->blue.length = 8;
524                 break;
525
526         default:
527                 dev_dbg(info->device,
528                         "Unsupported bpp size: %d\n", var->bits_per_pixel);
529                 assert(false);
530                 /* should never occur */
531                 break;
532         }
533
534         if (var->xres_virtual < var->xres)
535                 var->xres_virtual = var->xres;
536         /* use highest possible virtual resolution */
537         if (var->yres_virtual == -1) {
538                 var->yres_virtual = pixels / var->xres_virtual;
539
540                 dev_info(info->device,
541                          "virtual resolution set to maximum of %dx%d\n",
542                          var->xres_virtual, var->yres_virtual);
543         }
544         if (var->yres_virtual < var->yres)
545                 var->yres_virtual = var->yres;
546
547         if (var->xres_virtual * var->yres_virtual > pixels) {
548                 dev_err(info->device, "mode %dx%dx%d rejected... "
549                       "virtual resolution too high to fit into video memory!\n",
550                         var->xres_virtual, var->yres_virtual,
551                         var->bits_per_pixel);
552                 return -EINVAL;
553         }
554
555
556         if (var->xoffset < 0)
557                 var->xoffset = 0;
558         if (var->yoffset < 0)
559                 var->yoffset = 0;
560
561         /* truncate xoffset and yoffset to maximum if too high */
562         if (var->xoffset > var->xres_virtual - var->xres)
563                 var->xoffset = var->xres_virtual - var->xres - 1;
564         if (var->yoffset > var->yres_virtual - var->yres)
565                 var->yoffset = var->yres_virtual - var->yres - 1;
566
567         var->red.msb_right =
568             var->green.msb_right =
569             var->blue.msb_right =
570             var->transp.offset =
571             var->transp.length =
572             var->transp.msb_right = 0;
573
574         yres = var->yres;
575         if (var->vmode & FB_VMODE_DOUBLE)
576                 yres *= 2;
577         else if (var->vmode & FB_VMODE_INTERLACED)
578                 yres = (yres + 1) / 2;
579
580         if (yres >= 1280) {
581                 dev_err(info->device, "ERROR: VerticalTotal >= 1280; "
582                         "special treatment required! (TODO)\n");
583                 return -EINVAL;
584         }
585
586         return 0;
587 }
588
589 static int cirrusfb_decode_var(const struct fb_var_screeninfo *var,
590                                 struct cirrusfb_regs *regs,
591                                 struct fb_info *info)
592 {
593         long freq;
594         long maxclock;
595         int maxclockidx = var->bits_per_pixel >> 3;
596         struct cirrusfb_info *cinfo = info->par;
597
598         switch (var->bits_per_pixel) {
599         case 1:
600                 info->fix.line_length = var->xres_virtual / 8;
601                 info->fix.visual = FB_VISUAL_MONO10;
602                 break;
603
604         case 8:
605                 info->fix.line_length = var->xres_virtual;
606                 info->fix.visual = FB_VISUAL_PSEUDOCOLOR;
607                 break;
608
609         case 16:
610         case 32:
611                 info->fix.line_length = var->xres_virtual * maxclockidx;
612                 info->fix.visual = FB_VISUAL_TRUECOLOR;
613                 break;
614
615         default:
616                 dev_dbg(info->device,
617                         "Unsupported bpp size: %d\n", var->bits_per_pixel);
618                 assert(false);
619                 /* should never occur */
620                 break;
621         }
622
623         info->fix.type = FB_TYPE_PACKED_PIXELS;
624
625         /* convert from ps to kHz */
626         freq = PICOS2KHZ(var->pixclock);
627
628         dev_dbg(info->device, "desired pixclock: %ld kHz\n", freq);
629
630         maxclock = cirrusfb_board_info[cinfo->btype].maxclock[maxclockidx];
631         regs->multiplexing = 0;
632
633         /* If the frequency is greater than we can support, we might be able
634          * to use multiplexing for the video mode */
635         if (freq > maxclock) {
636                 switch (cinfo->btype) {
637                 case BT_ALPINE:
638                 case BT_GD5480:
639                         regs->multiplexing = 1;
640                         break;
641
642                 default:
643                         dev_err(info->device,
644                                 "Frequency greater than maxclock (%ld kHz)\n",
645                                 maxclock);
646                         return -EINVAL;
647                 }
648         }
649 #if 0
650         /* TODO: If we have a 1MB 5434, we need to put ourselves in a mode where
651          * the VCLK is double the pixel clock. */
652         switch (var->bits_per_pixel) {
653         case 16:
654         case 32:
655                 if (var->xres <= 800)
656                         /* Xbh has this type of clock for 32-bit */
657                         freq /= 2;
658                 break;
659         }
660 #endif
661         return 0;
662 }
663
664 static void cirrusfb_set_mclk_as_source(const struct fb_info *info, int div)
665 {
666         struct cirrusfb_info *cinfo = info->par;
667         unsigned char old1f, old1e;
668
669         assert(cinfo != NULL);
670         old1f = vga_rseq(cinfo->regbase, CL_SEQR1F) & ~0x40;
671
672         if (div) {
673                 dev_dbg(info->device, "Set %s as pixclock source.\n",
674                         (div == 2) ? "MCLK/2" : "MCLK");
675                 old1f |= 0x40;
676                 old1e = vga_rseq(cinfo->regbase, CL_SEQR1E) & ~0x1;
677                 if (div == 2)
678                         old1e |= 1;
679
680                 vga_wseq(cinfo->regbase, CL_SEQR1E, old1e);
681         }
682         vga_wseq(cinfo->regbase, CL_SEQR1F, old1f);
683 }
684
685 /*************************************************************************
686         cirrusfb_set_par_foo()
687
688         actually writes the values for a new video mode into the hardware,
689 **************************************************************************/
690 static int cirrusfb_set_par_foo(struct fb_info *info)
691 {
692         struct cirrusfb_info *cinfo = info->par;
693         struct fb_var_screeninfo *var = &info->var;
694         struct cirrusfb_regs regs;
695         u8 __iomem *regbase = cinfo->regbase;
696         unsigned char tmp;
697         int err;
698         int pitch;
699         const struct cirrusfb_board_info_rec *bi;
700         int hdispend, hsyncstart, hsyncend, htotal;
701         int yres, vdispend, vsyncstart, vsyncend, vtotal;
702         long freq;
703         int nom, den, div;
704         unsigned int control, format, threshold;
705
706         dev_dbg(info->device, "Requested mode: %dx%dx%d\n",
707                var->xres, var->yres, var->bits_per_pixel);
708         dev_dbg(info->device, "pixclock: %d\n", var->pixclock);
709
710         init_vgachip(info);
711
712         err = cirrusfb_decode_var(var, &regs, info);
713         if (err) {
714                 /* should never happen */
715                 dev_dbg(info->device, "mode change aborted.  invalid var.\n");
716                 return -EINVAL;
717         }
718
719         bi = &cirrusfb_board_info[cinfo->btype];
720
721         hsyncstart = var->xres + var->right_margin;
722         hsyncend = hsyncstart + var->hsync_len;
723         htotal = (hsyncend + var->left_margin) / 8 - 5;
724         hdispend = var->xres / 8 - 1;
725         hsyncstart = hsyncstart / 8 + 1;
726         hsyncend = hsyncend / 8 + 1;
727
728         yres = var->yres;
729         vsyncstart = yres + var->lower_margin;
730         vsyncend = vsyncstart + var->vsync_len;
731         vtotal = vsyncend + var->upper_margin;
732         vdispend = yres - 1;
733
734         if (var->vmode & FB_VMODE_DOUBLE) {
735                 yres *= 2;
736                 vsyncstart *= 2;
737                 vsyncend *= 2;
738                 vtotal *= 2;
739         } else if (var->vmode & FB_VMODE_INTERLACED) {
740                 yres = (yres + 1) / 2;
741                 vsyncstart = (vsyncstart + 1) / 2;
742                 vsyncend = (vsyncend + 1) / 2;
743                 vtotal = (vtotal + 1) / 2;
744         }
745
746         vtotal -= 2;
747         vsyncstart -= 1;
748         vsyncend -= 1;
749
750         if (yres >= 1024) {
751                 vtotal /= 2;
752                 vsyncstart /= 2;
753                 vsyncend /= 2;
754                 vdispend /= 2;
755         }
756         if (regs.multiplexing) {
757                 htotal /= 2;
758                 hsyncstart /= 2;
759                 hsyncend /= 2;
760                 hdispend /= 2;
761         }
762         /* unlock register VGA_CRTC_H_TOTAL..CRT7 */
763         vga_wcrt(regbase, VGA_CRTC_V_SYNC_END, 0x20);   /* previously: 0x00) */
764
765         /* if debugging is enabled, all parameters get output before writing */
766         dev_dbg(info->device, "CRT0: %d\n", htotal);
767         vga_wcrt(regbase, VGA_CRTC_H_TOTAL, htotal);
768
769         dev_dbg(info->device, "CRT1: %d\n", hdispend);
770         vga_wcrt(regbase, VGA_CRTC_H_DISP, hdispend);
771
772         dev_dbg(info->device, "CRT2: %d\n", var->xres / 8);
773         vga_wcrt(regbase, VGA_CRTC_H_BLANK_START, var->xres / 8);
774
775         /*  + 128: Compatible read */
776         dev_dbg(info->device, "CRT3: 128+%d\n", (htotal + 5) % 32);
777         vga_wcrt(regbase, VGA_CRTC_H_BLANK_END,
778                  128 + ((htotal + 5) % 32));
779
780         dev_dbg(info->device, "CRT4: %d\n", hsyncstart);
781         vga_wcrt(regbase, VGA_CRTC_H_SYNC_START, hsyncstart);
782
783         tmp = hsyncend % 32;
784         if ((htotal + 5) & 32)
785                 tmp += 128;
786         dev_dbg(info->device, "CRT5: %d\n", tmp);
787         vga_wcrt(regbase, VGA_CRTC_H_SYNC_END, tmp);
788
789         dev_dbg(info->device, "CRT6: %d\n", vtotal & 0xff);
790         vga_wcrt(regbase, VGA_CRTC_V_TOTAL, vtotal & 0xff);
791
792         tmp = 16;               /* LineCompare bit #9 */
793         if (vtotal & 256)
794                 tmp |= 1;
795         if (vdispend & 256)
796                 tmp |= 2;
797         if (vsyncstart & 256)
798                 tmp |= 4;
799         if ((vdispend + 1) & 256)
800                 tmp |= 8;
801         if (vtotal & 512)
802                 tmp |= 32;
803         if (vdispend & 512)
804                 tmp |= 64;
805         if (vsyncstart & 512)
806                 tmp |= 128;
807         dev_dbg(info->device, "CRT7: %d\n", tmp);
808         vga_wcrt(regbase, VGA_CRTC_OVERFLOW, tmp);
809
810         tmp = 0x40;             /* LineCompare bit #8 */
811         if ((vdispend + 1) & 512)
812                 tmp |= 0x20;
813         if (var->vmode & FB_VMODE_DOUBLE)
814                 tmp |= 0x80;
815         dev_dbg(info->device, "CRT9: %d\n", tmp);
816         vga_wcrt(regbase, VGA_CRTC_MAX_SCAN, tmp);
817
818         dev_dbg(info->device, "CRT10: %d\n", vsyncstart & 0xff);
819         vga_wcrt(regbase, VGA_CRTC_V_SYNC_START, vsyncstart & 0xff);
820
821         dev_dbg(info->device, "CRT11: 64+32+%d\n", vsyncend % 16);
822         vga_wcrt(regbase, VGA_CRTC_V_SYNC_END, vsyncend % 16 + 64 + 32);
823
824         dev_dbg(info->device, "CRT12: %d\n", vdispend & 0xff);
825         vga_wcrt(regbase, VGA_CRTC_V_DISP_END, vdispend & 0xff);
826
827         dev_dbg(info->device, "CRT15: %d\n", (vdispend + 1) & 0xff);
828         vga_wcrt(regbase, VGA_CRTC_V_BLANK_START, (vdispend + 1) & 0xff);
829
830         dev_dbg(info->device, "CRT16: %d\n", vtotal & 0xff);
831         vga_wcrt(regbase, VGA_CRTC_V_BLANK_END, vtotal & 0xff);
832
833         dev_dbg(info->device, "CRT18: 0xff\n");
834         vga_wcrt(regbase, VGA_CRTC_LINE_COMPARE, 0xff);
835
836         tmp = 0;
837         if (var->vmode & FB_VMODE_INTERLACED)
838                 tmp |= 1;
839         if ((htotal + 5) & 64)
840                 tmp |= 16;
841         if ((htotal + 5) & 128)
842                 tmp |= 32;
843         if (vtotal & 256)
844                 tmp |= 64;
845         if (vtotal & 512)
846                 tmp |= 128;
847
848         dev_dbg(info->device, "CRT1a: %d\n", tmp);
849         vga_wcrt(regbase, CL_CRT1A, tmp);
850
851         freq = PICOS2KHZ(var->pixclock);
852         bestclock(freq, &nom, &den, &div);
853
854         dev_dbg(info->device, "VCLK freq: %ld kHz  nom: %d  den: %d  div: %d\n",
855                 freq, nom, den, div);
856
857         /* set VCLK0 */
858         /* hardware RefClock: 14.31818 MHz */
859         /* formula: VClk = (OSC * N) / (D * (1+P)) */
860         /* Example: VClk = (14.31818 * 91) / (23 * (1+1)) = 28.325 MHz */
861
862         if (cinfo->btype == BT_ALPINE) {
863                 /* if freq is close to mclk or mclk/2 select mclk
864                  * as clock source
865                  */
866                 int divMCLK = cirrusfb_check_mclk(info, freq);
867                 if (divMCLK)  {
868                         nom = 0;
869                         cirrusfb_set_mclk_as_source(info, divMCLK);
870                 }
871         }
872         if (cinfo->btype == BT_LAGUNA) {
873                 long pcifc = fb_readl(cinfo->laguna_mmio + 0x3fc);
874                 unsigned char tile = fb_readb(cinfo->laguna_mmio + 0x407);
875                 unsigned short tile_control;
876
877                 tile_control = fb_readw(cinfo->laguna_mmio + 0x2c4);
878                 fb_writew(tile_control & ~0x80, cinfo->laguna_mmio + 0x2c4);
879
880                 fb_writel(pcifc | 0x10000000l, cinfo->laguna_mmio + 0x3fc);
881                 fb_writeb(tile & 0x3f, cinfo->laguna_mmio + 0x407);
882                 control = fb_readw(cinfo->laguna_mmio + 0x402);
883                 threshold = fb_readw(cinfo->laguna_mmio + 0xea);
884                 control &= ~0x6800;
885                 format = 0;
886                 threshold &= 0xffe0;
887                 threshold &= 0x3fbf;
888         }
889         if (nom) {
890                 tmp = den << 1;
891                 if (div != 0)
892                         tmp |= 1;
893                 /* 6 bit denom; ONLY 5434!!! (bugged me 10 days) */
894                 if ((cinfo->btype == BT_SD64) ||
895                     (cinfo->btype == BT_ALPINE) ||
896                     (cinfo->btype == BT_GD5480))
897                         tmp |= 0x80;
898
899                 dev_dbg(info->device, "CL_SEQR1B: %d\n", (int) tmp);
900                 /* Laguna chipset has reversed clock registers */
901                 if (cinfo->btype == BT_LAGUNA) {
902                         vga_wseq(regbase, CL_SEQRE, tmp);
903                         vga_wseq(regbase, CL_SEQR1E, nom);
904                 } else {
905                         vga_wseq(regbase, CL_SEQRB, nom);
906                         vga_wseq(regbase, CL_SEQR1B, tmp);
907                 }
908         }
909
910         if (yres >= 1024)
911                 /* 1280x1024 */
912                 vga_wcrt(regbase, VGA_CRTC_MODE, 0xc7);
913         else
914                 /* mode control: VGA_CRTC_START_HI enable, ROTATE(?), 16bit
915                  * address wrap, no compat. */
916                 vga_wcrt(regbase, VGA_CRTC_MODE, 0xc3);
917
918 /* HAEH?        vga_wcrt(regbase, VGA_CRTC_V_SYNC_END, 0x20);
919  * previously: 0x00  unlock VGA_CRTC_H_TOTAL..CRT7 */
920
921         /* don't know if it would hurt to also program this if no interlaced */
922         /* mode is used, but I feel better this way.. :-) */
923         if (var->vmode & FB_VMODE_INTERLACED)
924                 vga_wcrt(regbase, VGA_CRTC_REGS, htotal / 2);
925         else
926                 vga_wcrt(regbase, VGA_CRTC_REGS, 0x00); /* interlace control */
927
928         vga_wseq(regbase, VGA_SEQ_CHARACTER_MAP, 0);
929
930         /* adjust horizontal/vertical sync type (low/high) */
931         /* enable display memory & CRTC I/O address for color mode */
932         tmp = 0x03;
933         if (var->sync & FB_SYNC_HOR_HIGH_ACT)
934                 tmp |= 0x40;
935         if (var->sync & FB_SYNC_VERT_HIGH_ACT)
936                 tmp |= 0x80;
937         WGen(cinfo, VGA_MIS_W, tmp);
938
939         /* Screen A Preset Row-Scan register */
940         vga_wcrt(regbase, VGA_CRTC_PRESET_ROW, 0);
941         /* text cursor on and start line */
942         vga_wcrt(regbase, VGA_CRTC_CURSOR_START, 0);
943         /* text cursor end line */
944         vga_wcrt(regbase, VGA_CRTC_CURSOR_END, 31);
945
946         /******************************************************
947          *
948          * 1 bpp
949          *
950          */
951
952         /* programming for different color depths */
953         if (var->bits_per_pixel == 1) {
954                 dev_dbg(info->device, "preparing for 1 bit deep display\n");
955                 vga_wgfx(regbase, VGA_GFX_MODE, 0);     /* mode register */
956
957                 /* SR07 */
958                 switch (cinfo->btype) {
959                 case BT_SD64:
960                 case BT_PICCOLO:
961                 case BT_PICASSO:
962                 case BT_SPECTRUM:
963                 case BT_PICASSO4:
964                 case BT_ALPINE:
965                 case BT_GD5480:
966                         vga_wseq(regbase, CL_SEQR7,
967                                  regs.multiplexing ?
968                                         bi->sr07_1bpp_mux : bi->sr07_1bpp);
969                         break;
970
971                 case BT_LAGUNA:
972                         vga_wseq(regbase, CL_SEQR7,
973                                 vga_rseq(regbase, CL_SEQR7) & ~0x01);
974                         break;
975
976                 default:
977                         dev_warn(info->device, "unknown Board\n");
978                         break;
979                 }
980
981                 /* Extended Sequencer Mode */
982                 switch (cinfo->btype) {
983                 case BT_SD64:
984                         /* setting the SEQRF on SD64 is not necessary
985                          * (only during init)
986                          */
987                         /*  MCLK select */
988                         vga_wseq(regbase, CL_SEQR1F, 0x1a);
989                         break;
990
991                 case BT_PICCOLO:
992                 case BT_SPECTRUM:
993                         /* ### ueberall 0x22? */
994                         /* ##vorher 1c MCLK select */
995                         vga_wseq(regbase, CL_SEQR1F, 0x22);
996                         /* evtl d0 bei 1 bit? avoid FIFO underruns..? */
997                         vga_wseq(regbase, CL_SEQRF, 0xb0);
998                         break;
999
1000                 case BT_PICASSO:
1001                         /* ##vorher 22 MCLK select */
1002                         vga_wseq(regbase, CL_SEQR1F, 0x22);
1003                         /* ## vorher d0 avoid FIFO underruns..? */
1004                         vga_wseq(regbase, CL_SEQRF, 0xd0);
1005                         break;
1006
1007                 case BT_PICASSO4:
1008                 case BT_ALPINE:
1009                 case BT_GD5480:
1010                 case BT_LAGUNA:
1011                         /* do nothing */
1012                         break;
1013
1014                 default:
1015                         dev_warn(info->device, "unknown Board\n");
1016                         break;
1017                 }
1018
1019                 /* pixel mask: pass-through for first plane */
1020                 WGen(cinfo, VGA_PEL_MSK, 0x01);
1021                 if (regs.multiplexing)
1022                         /* hidden dac reg: 1280x1024 */
1023                         WHDR(cinfo, 0x4a);
1024                 else
1025                         /* hidden dac: nothing */
1026                         WHDR(cinfo, 0);
1027                 /* memory mode: odd/even, ext. memory */
1028                 vga_wseq(regbase, VGA_SEQ_MEMORY_MODE, 0x06);
1029                 /* plane mask: only write to first plane */
1030                 vga_wseq(regbase, VGA_SEQ_PLANE_WRITE, 0x01);
1031         }
1032
1033         /******************************************************
1034          *
1035          * 8 bpp
1036          *
1037          */
1038
1039         else if (var->bits_per_pixel == 8) {
1040                 dev_dbg(info->device, "preparing for 8 bit deep display\n");
1041                 switch (cinfo->btype) {
1042                 case BT_SD64:
1043                 case BT_PICCOLO:
1044                 case BT_PICASSO:
1045                 case BT_SPECTRUM:
1046                 case BT_PICASSO4:
1047                 case BT_ALPINE:
1048                 case BT_GD5480:
1049                         vga_wseq(regbase, CL_SEQR7,
1050                                   regs.multiplexing ?
1051                                         bi->sr07_8bpp_mux : bi->sr07_8bpp);
1052                         break;
1053
1054                 case BT_LAGUNA:
1055                         vga_wseq(regbase, CL_SEQR7,
1056                                 vga_rseq(regbase, CL_SEQR7) | 0x01);
1057                         threshold |= 0x10;
1058                         break;
1059
1060                 default:
1061                         dev_warn(info->device, "unknown Board\n");
1062                         break;
1063                 }
1064
1065                 switch (cinfo->btype) {
1066                 case BT_SD64:
1067                         /* MCLK select */
1068                         vga_wseq(regbase, CL_SEQR1F, 0x1d);
1069                         break;
1070
1071                 case BT_PICCOLO:
1072                 case BT_PICASSO:
1073                 case BT_SPECTRUM:
1074                         /* ### vorher 1c MCLK select */
1075                         vga_wseq(regbase, CL_SEQR1F, 0x22);
1076                         /* Fast Page-Mode writes */
1077                         vga_wseq(regbase, CL_SEQRF, 0xb0);
1078                         break;
1079
1080                 case BT_PICASSO4:
1081 #ifdef CONFIG_ZORRO
1082                         /* ### INCOMPLETE!! */
1083                         vga_wseq(regbase, CL_SEQRF, 0xb8);
1084 #endif
1085 /*                      vga_wseq(regbase, CL_SEQR1F, 0x1c); */
1086                         break;
1087
1088                 case BT_ALPINE:
1089                         /* We already set SRF and SR1F */
1090                         break;
1091
1092                 case BT_GD5480:
1093                 case BT_LAGUNA:
1094                         /* do nothing */
1095                         break;
1096
1097                 default:
1098                         dev_warn(info->device, "unknown board\n");
1099                         break;
1100                 }
1101
1102                 /* mode register: 256 color mode */
1103                 vga_wgfx(regbase, VGA_GFX_MODE, 64);
1104                 /* pixel mask: pass-through all planes */
1105                 WGen(cinfo, VGA_PEL_MSK, 0xff);
1106                 if (regs.multiplexing)
1107                         /* hidden dac reg: 1280x1024 */
1108                         WHDR(cinfo, 0x4a);
1109                 else
1110                         /* hidden dac: nothing */
1111                         WHDR(cinfo, 0);
1112                 /* memory mode: chain4, ext. memory */
1113                 vga_wseq(regbase, VGA_SEQ_MEMORY_MODE, 0x0a);
1114                 /* plane mask: enable writing to all 4 planes */
1115                 vga_wseq(regbase, VGA_SEQ_PLANE_WRITE, 0xff);
1116         }
1117
1118         /******************************************************
1119          *
1120          * 16 bpp
1121          *
1122          */
1123
1124         else if (var->bits_per_pixel == 16) {
1125                 dev_dbg(info->device, "preparing for 16 bit deep display\n");
1126                 switch (cinfo->btype) {
1127                 case BT_SD64:
1128                         /* Extended Sequencer Mode: 256c col. mode */
1129                         vga_wseq(regbase, CL_SEQR7, 0xf7);
1130                         /* MCLK select */
1131                         vga_wseq(regbase, CL_SEQR1F, 0x1e);
1132                         break;
1133
1134                 case BT_PICCOLO:
1135                 case BT_SPECTRUM:
1136                         vga_wseq(regbase, CL_SEQR7, 0x87);
1137                         /* Fast Page-Mode writes */
1138                         vga_wseq(regbase, CL_SEQRF, 0xb0);
1139                         /* MCLK select */
1140                         vga_wseq(regbase, CL_SEQR1F, 0x22);
1141                         break;
1142
1143                 case BT_PICASSO:
1144                         vga_wseq(regbase, CL_SEQR7, 0x27);
1145                         /* Fast Page-Mode writes */
1146                         vga_wseq(regbase, CL_SEQRF, 0xb0);
1147                         /* MCLK select */
1148                         vga_wseq(regbase, CL_SEQR1F, 0x22);
1149                         break;
1150
1151                 case BT_PICASSO4:
1152                         vga_wseq(regbase, CL_SEQR7, 0x27);
1153 /*                      vga_wseq(regbase, CL_SEQR1F, 0x1c);  */
1154                         break;
1155
1156                 case BT_ALPINE:
1157                         vga_wseq(regbase, CL_SEQR7, 0xa7);
1158                         break;
1159
1160                 case BT_GD5480:
1161                         vga_wseq(regbase, CL_SEQR7, 0x17);
1162                         /* We already set SRF and SR1F */
1163                         break;
1164
1165                 case BT_LAGUNA:
1166                         vga_wseq(regbase, CL_SEQR7,
1167                                 vga_rseq(regbase, CL_SEQR7) & ~0x01);
1168                         control |= 0x2000;
1169                         format |= 0x1400;
1170                         threshold |= 0x10;
1171                         break;
1172
1173                 default:
1174                         dev_warn(info->device, "unknown Board\n");
1175                         break;
1176                 }
1177
1178                 /* mode register: 256 color mode */
1179                 vga_wgfx(regbase, VGA_GFX_MODE, 64);
1180                 /* pixel mask: pass-through all planes */
1181                 WGen(cinfo, VGA_PEL_MSK, 0xff);
1182 #ifdef CONFIG_PCI
1183                 WHDR(cinfo, 0xc0);      /* Copy Xbh */
1184 #elif defined(CONFIG_ZORRO)
1185                 /* FIXME: CONFIG_PCI and CONFIG_ZORRO may be defined both */
1186                 WHDR(cinfo, 0xa0);      /* hidden dac reg: nothing special */
1187 #endif
1188                 /* memory mode: chain4, ext. memory */
1189                 vga_wseq(regbase, VGA_SEQ_MEMORY_MODE, 0x0a);
1190                 /* plane mask: enable writing to all 4 planes */
1191                 vga_wseq(regbase, VGA_SEQ_PLANE_WRITE, 0xff);
1192         }
1193
1194         /******************************************************
1195          *
1196          * 32 bpp
1197          *
1198          */
1199
1200         else if (var->bits_per_pixel == 32) {
1201                 dev_dbg(info->device, "preparing for 32 bit deep display\n");
1202                 switch (cinfo->btype) {
1203                 case BT_SD64:
1204                         /* Extended Sequencer Mode: 256c col. mode */
1205                         vga_wseq(regbase, CL_SEQR7, 0xf9);
1206                         /* MCLK select */
1207                         vga_wseq(regbase, CL_SEQR1F, 0x1e);
1208                         break;
1209
1210                 case BT_PICCOLO:
1211                 case BT_SPECTRUM:
1212                         vga_wseq(regbase, CL_SEQR7, 0x85);
1213                         /* Fast Page-Mode writes */
1214                         vga_wseq(regbase, CL_SEQRF, 0xb0);
1215                         /* MCLK select */
1216                         vga_wseq(regbase, CL_SEQR1F, 0x22);
1217                         break;
1218
1219                 case BT_PICASSO:
1220                         vga_wseq(regbase, CL_SEQR7, 0x25);
1221                         /* Fast Page-Mode writes */
1222                         vga_wseq(regbase, CL_SEQRF, 0xb0);
1223                         /* MCLK select */
1224                         vga_wseq(regbase, CL_SEQR1F, 0x22);
1225                         break;
1226
1227                 case BT_PICASSO4:
1228                         vga_wseq(regbase, CL_SEQR7, 0x25);
1229 /*                      vga_wseq(regbase, CL_SEQR1F, 0x1c);  */
1230                         break;
1231
1232                 case BT_ALPINE:
1233                         vga_wseq(regbase, CL_SEQR7, 0xa9);
1234                         break;
1235
1236                 case BT_GD5480:
1237                         vga_wseq(regbase, CL_SEQR7, 0x19);
1238                         /* We already set SRF and SR1F */
1239                         break;
1240
1241                 case BT_LAGUNA:
1242                         vga_wseq(regbase, CL_SEQR7,
1243                                 vga_rseq(regbase, CL_SEQR7) & ~0x01);
1244                         control |= 0x6000;
1245                         format |= 0x3400;
1246                         threshold |= 0x20;
1247                         break;
1248
1249                 default:
1250                         dev_warn(info->device, "unknown Board\n");
1251                         break;
1252                 }
1253
1254                 /* mode register: 256 color mode */
1255                 vga_wgfx(regbase, VGA_GFX_MODE, 64);
1256                 /* pixel mask: pass-through all planes */
1257                 WGen(cinfo, VGA_PEL_MSK, 0xff);
1258                 /* hidden dac reg: 8-8-8 mode (24 or 32) */
1259                 WHDR(cinfo, 0xc5);
1260                 /* memory mode: chain4, ext. memory */
1261                 vga_wseq(regbase, VGA_SEQ_MEMORY_MODE, 0x0a);
1262                 /* plane mask: enable writing to all 4 planes */
1263                 vga_wseq(regbase, VGA_SEQ_PLANE_WRITE, 0xff);
1264         }
1265
1266         /******************************************************
1267          *
1268          * unknown/unsupported bpp
1269          *
1270          */
1271
1272         else
1273                 dev_err(info->device,
1274                         "What's this? requested color depth == %d.\n",
1275                         var->bits_per_pixel);
1276
1277         pitch = info->fix.line_length >> 3;
1278         vga_wcrt(regbase, VGA_CRTC_OFFSET, pitch & 0xff);
1279         tmp = 0x22;
1280         if (pitch & 0x100)
1281                 tmp |= 0x10;    /* offset overflow bit */
1282
1283         /* screen start addr #16-18, fastpagemode cycles */
1284         vga_wcrt(regbase, CL_CRT1B, tmp);
1285
1286         /* screen start address bit 19 */
1287         if (cirrusfb_board_info[cinfo->btype].scrn_start_bit19)
1288                 vga_wcrt(regbase, CL_CRT1D, (pitch >> 9) & 1);
1289
1290         if (cinfo->btype == BT_LAGUNA ||
1291             cinfo->btype == BT_GD5480) {
1292
1293                 tmp = 0;
1294                 if ((htotal + 5) & 256)
1295                         tmp |= 128;
1296                 if (hdispend & 256)
1297                         tmp |= 64;
1298                 if (hsyncstart & 256)
1299                         tmp |= 48;
1300                 if (vtotal & 1024)
1301                         tmp |= 8;
1302                 if (vdispend & 1024)
1303                         tmp |= 4;
1304                 if (vsyncstart & 1024)
1305                         tmp |= 3;
1306
1307                 vga_wcrt(regbase, CL_CRT1E, tmp);
1308                 dev_dbg(info->device, "CRT1e: %d\n", tmp);
1309         }
1310
1311
1312         /* text cursor location high */
1313         vga_wcrt(regbase, VGA_CRTC_CURSOR_HI, 0);
1314         /* text cursor location low */
1315         vga_wcrt(regbase, VGA_CRTC_CURSOR_LO, 0);
1316         /* underline row scanline = at very bottom */
1317         vga_wcrt(regbase, VGA_CRTC_UNDERLINE, 0);
1318
1319         /* controller mode */
1320         vga_wattr(regbase, VGA_ATC_MODE, 1);
1321         /* overscan (border) color */
1322         vga_wattr(regbase, VGA_ATC_OVERSCAN, 0);
1323         /* color plane enable */
1324         vga_wattr(regbase, VGA_ATC_PLANE_ENABLE, 15);
1325         /* pixel panning */
1326         vga_wattr(regbase, CL_AR33, 0);
1327         /* color select */
1328         vga_wattr(regbase, VGA_ATC_COLOR_PAGE, 0);
1329
1330         /* [ EGS: SetOffset(); ] */
1331         /* From SetOffset(): Turn on VideoEnable bit in Attribute controller */
1332         AttrOn(cinfo);
1333
1334         /* set/reset register */
1335         vga_wgfx(regbase, VGA_GFX_SR_VALUE, 0);
1336         /* set/reset enable */
1337         vga_wgfx(regbase, VGA_GFX_SR_ENABLE, 0);
1338         /* color compare */
1339         vga_wgfx(regbase, VGA_GFX_COMPARE_VALUE, 0);
1340         /* data rotate */
1341         vga_wgfx(regbase, VGA_GFX_DATA_ROTATE, 0);
1342         /* read map select */
1343         vga_wgfx(regbase, VGA_GFX_PLANE_READ, 0);
1344         /* miscellaneous register */
1345         vga_wgfx(regbase, VGA_GFX_MISC, 1);
1346         /* color don't care */
1347         vga_wgfx(regbase, VGA_GFX_COMPARE_MASK, 15);
1348         /* bit mask */
1349         vga_wgfx(regbase, VGA_GFX_BIT_MASK, 255);
1350
1351         /* graphics cursor attributes: nothing special */
1352         vga_wseq(regbase, CL_SEQR12, 0x0);
1353
1354         if (cinfo->btype == BT_LAGUNA) {
1355                 /* no tiles */
1356                 fb_writew(control | 0x1000, cinfo->laguna_mmio + 0x402);
1357                 fb_writew(format, cinfo->laguna_mmio + 0xc0);
1358                 fb_writew(threshold, cinfo->laguna_mmio + 0xea);
1359         }
1360         /* finally, turn on everything - turn off "FullBandwidth" bit */
1361         /* also, set "DotClock%2" bit where requested */
1362         tmp = 0x01;
1363
1364 /*** FB_VMODE_CLOCK_HALVE in linux/fb.h not defined anymore ?
1365     if (var->vmode & FB_VMODE_CLOCK_HALVE)
1366         tmp |= 0x08;
1367 */
1368
1369         vga_wseq(regbase, VGA_SEQ_CLOCK_MODE, tmp);
1370         dev_dbg(info->device, "CL_SEQR1: %d\n", tmp);
1371
1372         cinfo->currentmode = regs;
1373
1374         /* pan to requested offset */
1375         cirrusfb_pan_display(var, info);
1376
1377 #ifdef CIRRUSFB_DEBUG
1378         cirrusfb_dbg_reg_dump(info, NULL);
1379 #endif
1380
1381         return 0;
1382 }
1383
1384 /* for some reason incomprehensible to me, cirrusfb requires that you write
1385  * the registers twice for the settings to take..grr. -dte */
1386 static int cirrusfb_set_par(struct fb_info *info)
1387 {
1388         cirrusfb_set_par_foo(info);
1389         return cirrusfb_set_par_foo(info);
1390 }
1391
1392 static int cirrusfb_setcolreg(unsigned regno, unsigned red, unsigned green,
1393                               unsigned blue, unsigned transp,
1394                               struct fb_info *info)
1395 {
1396         struct cirrusfb_info *cinfo = info->par;
1397
1398         if (regno > 255)
1399                 return -EINVAL;
1400
1401         if (info->fix.visual == FB_VISUAL_TRUECOLOR) {
1402                 u32 v;
1403                 red >>= (16 - info->var.red.length);
1404                 green >>= (16 - info->var.green.length);
1405                 blue >>= (16 - info->var.blue.length);
1406
1407                 if (regno >= 16)
1408                         return 1;
1409                 v = (red << info->var.red.offset) |
1410                     (green << info->var.green.offset) |
1411                     (blue << info->var.blue.offset);
1412
1413                 cinfo->pseudo_palette[regno] = v;
1414                 return 0;
1415         }
1416
1417         if (info->var.bits_per_pixel == 8)
1418                 WClut(cinfo, regno, red >> 10, green >> 10, blue >> 10);
1419
1420         return 0;
1421
1422 }
1423
1424 /*************************************************************************
1425         cirrusfb_pan_display()
1426
1427         performs display panning - provided hardware permits this
1428 **************************************************************************/
1429 static int cirrusfb_pan_display(struct fb_var_screeninfo *var,
1430                                 struct fb_info *info)
1431 {
1432         int xoffset = 0;
1433         int yoffset = 0;
1434         unsigned long base;
1435         unsigned char tmp, xpix;
1436         struct cirrusfb_info *cinfo = info->par;
1437
1438         dev_dbg(info->device,
1439                 "virtual offset: (%d,%d)\n", var->xoffset, var->yoffset);
1440
1441         /* no range checks for xoffset and yoffset,   */
1442         /* as fb_pan_display has already done this */
1443         if (var->vmode & FB_VMODE_YWRAP)
1444                 return -EINVAL;
1445
1446         info->var.xoffset = var->xoffset;
1447         info->var.yoffset = var->yoffset;
1448
1449         xoffset = var->xoffset * info->var.bits_per_pixel / 8;
1450         yoffset = var->yoffset;
1451
1452         base = yoffset * info->fix.line_length + xoffset;
1453
1454         if (info->var.bits_per_pixel == 1) {
1455                 /* base is already correct */
1456                 xpix = (unsigned char) (var->xoffset % 8);
1457         } else {
1458                 base /= 4;
1459                 xpix = (unsigned char) ((xoffset % 4) * 2);
1460         }
1461
1462         cirrusfb_WaitBLT(cinfo->regbase); /* make sure all the BLT's are done */
1463
1464         /* lower 8 + 8 bits of screen start address */
1465         vga_wcrt(cinfo->regbase, VGA_CRTC_START_LO,
1466                  (unsigned char) (base & 0xff));
1467         vga_wcrt(cinfo->regbase, VGA_CRTC_START_HI,
1468                  (unsigned char) (base >> 8));
1469
1470         /* 0xf2 is %11110010, exclude tmp bits */
1471         tmp = vga_rcrt(cinfo->regbase, CL_CRT1B) & 0xf2;
1472         /* construct bits 16, 17 and 18 of screen start address */
1473         if (base & 0x10000)
1474                 tmp |= 0x01;
1475         if (base & 0x20000)
1476                 tmp |= 0x04;
1477         if (base & 0x40000)
1478                 tmp |= 0x08;
1479
1480         vga_wcrt(cinfo->regbase, CL_CRT1B, tmp);
1481
1482         /* construct bit 19 of screen start address */
1483         if (cirrusfb_board_info[cinfo->btype].scrn_start_bit19)
1484                 vga_wcrt(cinfo->regbase, CL_CRT1D, (base >> 12) & 0x80);
1485
1486         /* write pixel panning value to AR33; this does not quite work in 8bpp
1487          *
1488          * ### Piccolo..? Will this work?
1489          */
1490         if (info->var.bits_per_pixel == 1)
1491                 vga_wattr(cinfo->regbase, CL_AR33, xpix);
1492
1493         cirrusfb_WaitBLT(cinfo->regbase);
1494
1495         return 0;
1496 }
1497
1498 static int cirrusfb_blank(int blank_mode, struct fb_info *info)
1499 {
1500         /*
1501          * Blank the screen if blank_mode != 0, else unblank. If blank == NULL
1502          * then the caller blanks by setting the CLUT (Color Look Up Table)
1503          * to all black. Return 0 if blanking succeeded, != 0 if un-/blanking
1504          * failed due to e.g. a video mode which doesn't support it.
1505          * Implements VESA suspend and powerdown modes on hardware that
1506          * supports disabling hsync/vsync:
1507          *   blank_mode == 2: suspend vsync
1508          *   blank_mode == 3: suspend hsync
1509          *   blank_mode == 4: powerdown
1510          */
1511         unsigned char val;
1512         struct cirrusfb_info *cinfo = info->par;
1513         int current_mode = cinfo->blank_mode;
1514
1515         dev_dbg(info->device, "ENTER, blank mode = %d\n", blank_mode);
1516
1517         if (info->state != FBINFO_STATE_RUNNING ||
1518             current_mode == blank_mode) {
1519                 dev_dbg(info->device, "EXIT, returning 0\n");
1520                 return 0;
1521         }
1522
1523         /* Undo current */
1524         if (current_mode == FB_BLANK_NORMAL ||
1525             current_mode == FB_BLANK_UNBLANK)
1526                 /* clear "FullBandwidth" bit */
1527                 val = 0;
1528         else
1529                 /* set "FullBandwidth" bit */
1530                 val = 0x20;
1531
1532         val |= vga_rseq(cinfo->regbase, VGA_SEQ_CLOCK_MODE) & 0xdf;
1533         vga_wseq(cinfo->regbase, VGA_SEQ_CLOCK_MODE, val);
1534
1535         switch (blank_mode) {
1536         case FB_BLANK_UNBLANK:
1537         case FB_BLANK_NORMAL:
1538                 val = 0x00;
1539                 break;
1540         case FB_BLANK_VSYNC_SUSPEND:
1541                 val = 0x04;
1542                 break;
1543         case FB_BLANK_HSYNC_SUSPEND:
1544                 val = 0x02;
1545                 break;
1546         case FB_BLANK_POWERDOWN:
1547                 val = 0x06;
1548                 break;
1549         default:
1550                 dev_dbg(info->device, "EXIT, returning 1\n");
1551                 return 1;
1552         }
1553
1554         vga_wgfx(cinfo->regbase, CL_GRE, val);
1555
1556         cinfo->blank_mode = blank_mode;
1557         dev_dbg(info->device, "EXIT, returning 0\n");
1558
1559         /* Let fbcon do a soft blank for us */
1560         return (blank_mode == FB_BLANK_NORMAL) ? 1 : 0;
1561 }
1562
1563 /**** END   Hardware specific Routines **************************************/
1564 /****************************************************************************/
1565 /**** BEGIN Internal Routines ***********************************************/
1566
1567 static void init_vgachip(struct fb_info *info)
1568 {
1569         struct cirrusfb_info *cinfo = info->par;
1570         const struct cirrusfb_board_info_rec *bi;
1571
1572         assert(cinfo != NULL);
1573
1574         bi = &cirrusfb_board_info[cinfo->btype];
1575
1576         /* reset board globally */
1577         switch (cinfo->btype) {
1578         case BT_PICCOLO:
1579                 WSFR(cinfo, 0x01);
1580                 udelay(500);
1581                 WSFR(cinfo, 0x51);
1582                 udelay(500);
1583                 break;
1584         case BT_PICASSO:
1585                 WSFR2(cinfo, 0xff);
1586                 udelay(500);
1587                 break;
1588         case BT_SD64:
1589         case BT_SPECTRUM:
1590                 WSFR(cinfo, 0x1f);
1591                 udelay(500);
1592                 WSFR(cinfo, 0x4f);
1593                 udelay(500);
1594                 break;
1595         case BT_PICASSO4:
1596                 /* disable flickerfixer */
1597                 vga_wcrt(cinfo->regbase, CL_CRT51, 0x00);
1598                 mdelay(100);
1599                 /* from Klaus' NetBSD driver: */
1600                 vga_wgfx(cinfo->regbase, CL_GR2F, 0x00);
1601                 /* put blitter into 542x compat */
1602                 vga_wgfx(cinfo->regbase, CL_GR33, 0x00);
1603                 /* mode */
1604                 vga_wgfx(cinfo->regbase, CL_GR31, 0x00);
1605                 break;
1606
1607         case BT_GD5480:
1608                 /* from Klaus' NetBSD driver: */
1609                 vga_wgfx(cinfo->regbase, CL_GR2F, 0x00);
1610                 break;
1611
1612         case BT_ALPINE:
1613                 /* Nothing to do to reset the board. */
1614                 break;
1615
1616         default:
1617                 dev_err(info->device, "Warning: Unknown board type\n");
1618                 break;
1619         }
1620
1621         /* make sure RAM size set by this point */
1622         assert(info->screen_size > 0);
1623
1624         /* the P4 is not fully initialized here; I rely on it having been */
1625         /* inited under AmigaOS already, which seems to work just fine    */
1626         /* (Klaus advised to do it this way)                          */
1627
1628         if (cinfo->btype != BT_PICASSO4) {
1629                 WGen(cinfo, CL_VSSM, 0x10);     /* EGS: 0x16 */
1630                 WGen(cinfo, CL_POS102, 0x01);
1631                 WGen(cinfo, CL_VSSM, 0x08);     /* EGS: 0x0e */
1632
1633                 if (cinfo->btype != BT_SD64)
1634                         WGen(cinfo, CL_VSSM2, 0x01);
1635
1636                 /* reset sequencer logic */
1637                 vga_wseq(cinfo->regbase, CL_SEQR0, 0x03);
1638
1639                 /* FullBandwidth (video off) and 8/9 dot clock */
1640                 vga_wseq(cinfo->regbase, VGA_SEQ_CLOCK_MODE, 0x21);
1641                 /* polarity (-/-), disable access to display memory,
1642                  * VGA_CRTC_START_HI base address: color
1643                  */
1644                 WGen(cinfo, VGA_MIS_W, 0xc1);
1645
1646                 /* "magic cookie" - doesn't make any sense to me.. */
1647 /*      vga_wgfx(cinfo->regbase, CL_GRA, 0xce);   */
1648                 /* unlock all extension registers */
1649                 vga_wseq(cinfo->regbase, CL_SEQR6, 0x12);
1650
1651                 /* reset blitter */
1652                 vga_wgfx(cinfo->regbase, CL_GR31, 0x04);
1653
1654                 switch (cinfo->btype) {
1655                 case BT_GD5480:
1656                         vga_wseq(cinfo->regbase, CL_SEQRF, 0x98);
1657                         break;
1658                 case BT_ALPINE:
1659                         break;
1660                 case BT_SD64:
1661                         vga_wseq(cinfo->regbase, CL_SEQRF, 0xb8);
1662                         break;
1663                 default:
1664                         vga_wseq(cinfo->regbase, CL_SEQR16, 0x0f);
1665                         vga_wseq(cinfo->regbase, CL_SEQRF, 0xb0);
1666                         break;
1667                 }
1668         }
1669         /* plane mask: nothing */
1670         vga_wseq(cinfo->regbase, VGA_SEQ_PLANE_WRITE, 0xff);
1671         /* character map select: doesn't even matter in gx mode */
1672         vga_wseq(cinfo->regbase, VGA_SEQ_CHARACTER_MAP, 0x00);
1673         /* memory mode: chain-4, no odd/even, ext. memory */
1674         vga_wseq(cinfo->regbase, VGA_SEQ_MEMORY_MODE, 0x0e);
1675
1676         /* controller-internal base address of video memory */
1677         if (bi->init_sr07)
1678                 vga_wseq(cinfo->regbase, CL_SEQR7, bi->sr07);
1679
1680         /*  vga_wseq(cinfo->regbase, CL_SEQR8, 0x00); */
1681         /* EEPROM control: shouldn't be necessary to write to this at all.. */
1682
1683         /* graphics cursor X position (incomplete; position gives rem. 3 bits */
1684         vga_wseq(cinfo->regbase, CL_SEQR10, 0x00);
1685         /* graphics cursor Y position (..."... ) */
1686         vga_wseq(cinfo->regbase, CL_SEQR11, 0x00);
1687         /* graphics cursor attributes */
1688         vga_wseq(cinfo->regbase, CL_SEQR12, 0x00);
1689         /* graphics cursor pattern address */
1690         vga_wseq(cinfo->regbase, CL_SEQR13, 0x00);
1691
1692         /* writing these on a P4 might give problems..  */
1693         if (cinfo->btype != BT_PICASSO4) {
1694                 /* configuration readback and ext. color */
1695                 vga_wseq(cinfo->regbase, CL_SEQR17, 0x00);
1696                 /* signature generator */
1697                 vga_wseq(cinfo->regbase, CL_SEQR18, 0x02);
1698         }
1699
1700         /* MCLK select etc. */
1701         if (bi->init_sr1f)
1702                 vga_wseq(cinfo->regbase, CL_SEQR1F, bi->sr1f);
1703
1704         /* Screen A preset row scan: none */
1705         vga_wcrt(cinfo->regbase, VGA_CRTC_PRESET_ROW, 0x00);
1706         /* Text cursor start: disable text cursor */
1707         vga_wcrt(cinfo->regbase, VGA_CRTC_CURSOR_START, 0x20);
1708         /* Text cursor end: - */
1709         vga_wcrt(cinfo->regbase, VGA_CRTC_CURSOR_END, 0x00);
1710         /* Screen start address high: 0 */
1711         vga_wcrt(cinfo->regbase, VGA_CRTC_START_HI, 0x00);
1712         /* Screen start address low: 0 */
1713         vga_wcrt(cinfo->regbase, VGA_CRTC_START_LO, 0x00);
1714         /* text cursor location high: 0 */
1715         vga_wcrt(cinfo->regbase, VGA_CRTC_CURSOR_HI, 0x00);
1716         /* text cursor location low: 0 */
1717         vga_wcrt(cinfo->regbase, VGA_CRTC_CURSOR_LO, 0x00);
1718
1719         /* Underline Row scanline: - */
1720         vga_wcrt(cinfo->regbase, VGA_CRTC_UNDERLINE, 0x00);
1721         /* mode control: timing enable, byte mode, no compat modes */
1722         vga_wcrt(cinfo->regbase, VGA_CRTC_MODE, 0xc3);
1723         /* Line Compare: not needed */
1724         vga_wcrt(cinfo->regbase, VGA_CRTC_LINE_COMPARE, 0x00);
1725         /* ### add 0x40 for text modes with > 30 MHz pixclock */
1726         /* ext. display controls: ext.adr. wrap */
1727         vga_wcrt(cinfo->regbase, CL_CRT1B, 0x02);
1728
1729         /* Set/Reset registes: - */
1730         vga_wgfx(cinfo->regbase, VGA_GFX_SR_VALUE, 0x00);
1731         /* Set/Reset enable: - */
1732         vga_wgfx(cinfo->regbase, VGA_GFX_SR_ENABLE, 0x00);
1733         /* Color Compare: - */
1734         vga_wgfx(cinfo->regbase, VGA_GFX_COMPARE_VALUE, 0x00);
1735         /* Data Rotate: - */
1736         vga_wgfx(cinfo->regbase, VGA_GFX_DATA_ROTATE, 0x00);
1737         /* Read Map Select: - */
1738         vga_wgfx(cinfo->regbase, VGA_GFX_PLANE_READ, 0x00);
1739         /* Mode: conf. for 16/4/2 color mode, no odd/even, read/write mode 0 */
1740         vga_wgfx(cinfo->regbase, VGA_GFX_MODE, 0x00);
1741         /* Miscellaneous: memory map base address, graphics mode */
1742         vga_wgfx(cinfo->regbase, VGA_GFX_MISC, 0x01);
1743         /* Color Don't care: involve all planes */
1744         vga_wgfx(cinfo->regbase, VGA_GFX_COMPARE_MASK, 0x0f);
1745         /* Bit Mask: no mask at all */
1746         vga_wgfx(cinfo->regbase, VGA_GFX_BIT_MASK, 0xff);
1747         if (cinfo->btype == BT_ALPINE)
1748                 /* (5434 can't have bit 3 set for bitblt) */
1749                 vga_wgfx(cinfo->regbase, CL_GRB, 0x20);
1750         else
1751         /* Graphics controller mode extensions: finer granularity,
1752          * 8byte data latches
1753          */
1754                 vga_wgfx(cinfo->regbase, CL_GRB, 0x28);
1755
1756         vga_wgfx(cinfo->regbase, CL_GRC, 0xff); /* Color Key compare: - */
1757         vga_wgfx(cinfo->regbase, CL_GRD, 0x00); /* Color Key compare mask: - */
1758         vga_wgfx(cinfo->regbase, CL_GRE, 0x00); /* Miscellaneous control: - */
1759         /* Background color byte 1: - */
1760         /*  vga_wgfx (cinfo->regbase, CL_GR10, 0x00); */
1761         /*  vga_wgfx (cinfo->regbase, CL_GR11, 0x00); */
1762
1763         /* Attribute Controller palette registers: "identity mapping" */
1764         vga_wattr(cinfo->regbase, VGA_ATC_PALETTE0, 0x00);
1765         vga_wattr(cinfo->regbase, VGA_ATC_PALETTE1, 0x01);
1766         vga_wattr(cinfo->regbase, VGA_ATC_PALETTE2, 0x02);
1767         vga_wattr(cinfo->regbase, VGA_ATC_PALETTE3, 0x03);
1768         vga_wattr(cinfo->regbase, VGA_ATC_PALETTE4, 0x04);
1769         vga_wattr(cinfo->regbase, VGA_ATC_PALETTE5, 0x05);
1770         vga_wattr(cinfo->regbase, VGA_ATC_PALETTE6, 0x06);
1771         vga_wattr(cinfo->regbase, VGA_ATC_PALETTE7, 0x07);
1772         vga_wattr(cinfo->regbase, VGA_ATC_PALETTE8, 0x08);
1773         vga_wattr(cinfo->regbase, VGA_ATC_PALETTE9, 0x09);
1774         vga_wattr(cinfo->regbase, VGA_ATC_PALETTEA, 0x0a);
1775         vga_wattr(cinfo->regbase, VGA_ATC_PALETTEB, 0x0b);
1776         vga_wattr(cinfo->regbase, VGA_ATC_PALETTEC, 0x0c);
1777         vga_wattr(cinfo->regbase, VGA_ATC_PALETTED, 0x0d);
1778         vga_wattr(cinfo->regbase, VGA_ATC_PALETTEE, 0x0e);
1779         vga_wattr(cinfo->regbase, VGA_ATC_PALETTEF, 0x0f);
1780
1781         /* Attribute Controller mode: graphics mode */
1782         vga_wattr(cinfo->regbase, VGA_ATC_MODE, 0x01);
1783         /* Overscan color reg.: reg. 0 */
1784         vga_wattr(cinfo->regbase, VGA_ATC_OVERSCAN, 0x00);
1785         /* Color Plane enable: Enable all 4 planes */
1786         vga_wattr(cinfo->regbase, VGA_ATC_PLANE_ENABLE, 0x0f);
1787 /* ###  vga_wattr(cinfo->regbase, CL_AR33, 0x00); * Pixel Panning: - */
1788         /* Color Select: - */
1789         vga_wattr(cinfo->regbase, VGA_ATC_COLOR_PAGE, 0x00);
1790
1791         WGen(cinfo, VGA_PEL_MSK, 0xff); /* Pixel mask: no mask */
1792
1793         if (cinfo->btype != BT_ALPINE && cinfo->btype != BT_GD5480)
1794         /* polarity (-/-), enable display mem,
1795          * VGA_CRTC_START_HI i/o base = color
1796          */
1797                 WGen(cinfo, VGA_MIS_W, 0xc3);
1798
1799         /* BLT Start/status: Blitter reset */
1800         vga_wgfx(cinfo->regbase, CL_GR31, 0x04);
1801         /* - " -           : "end-of-reset" */
1802         vga_wgfx(cinfo->regbase, CL_GR31, 0x00);
1803
1804         /* misc... */
1805         WHDR(cinfo, 0); /* Hidden DAC register: - */
1806         return;
1807 }
1808
1809 static void switch_monitor(struct cirrusfb_info *cinfo, int on)
1810 {
1811 #ifdef CONFIG_ZORRO /* only works on Zorro boards */
1812         static int IsOn = 0;    /* XXX not ok for multiple boards */
1813
1814         if (cinfo->btype == BT_PICASSO4)
1815                 return;         /* nothing to switch */
1816         if (cinfo->btype == BT_ALPINE)
1817                 return;         /* nothing to switch */
1818         if (cinfo->btype == BT_GD5480)
1819                 return;         /* nothing to switch */
1820         if (cinfo->btype == BT_PICASSO) {
1821                 if ((on && !IsOn) || (!on && IsOn))
1822                         WSFR(cinfo, 0xff);
1823                 return;
1824         }
1825         if (on) {
1826                 switch (cinfo->btype) {
1827                 case BT_SD64:
1828                         WSFR(cinfo, cinfo->SFR | 0x21);
1829                         break;
1830                 case BT_PICCOLO:
1831                         WSFR(cinfo, cinfo->SFR | 0x28);
1832                         break;
1833                 case BT_SPECTRUM:
1834                         WSFR(cinfo, 0x6f);
1835                         break;
1836                 default: /* do nothing */ break;
1837                 }
1838         } else {
1839                 switch (cinfo->btype) {
1840                 case BT_SD64:
1841                         WSFR(cinfo, cinfo->SFR & 0xde);
1842                         break;
1843                 case BT_PICCOLO:
1844                         WSFR(cinfo, cinfo->SFR & 0xd7);
1845                         break;
1846                 case BT_SPECTRUM:
1847                         WSFR(cinfo, 0x4f);
1848                         break;
1849                 default: /* do nothing */
1850                         break;
1851                 }
1852         }
1853 #endif /* CONFIG_ZORRO */
1854 }
1855
1856 /******************************************/
1857 /* Linux 2.6-style  accelerated functions */
1858 /******************************************/
1859
1860 static void cirrusfb_fillrect(struct fb_info *info,
1861                               const struct fb_fillrect *region)
1862 {
1863         struct fb_fillrect modded;
1864         int vxres, vyres;
1865         struct cirrusfb_info *cinfo = info->par;
1866         int m = info->var.bits_per_pixel;
1867         u32 color = (info->fix.visual == FB_VISUAL_TRUECOLOR) ?
1868                 cinfo->pseudo_palette[region->color] : region->color;
1869
1870         if (info->state != FBINFO_STATE_RUNNING)
1871                 return;
1872         if (info->flags & FBINFO_HWACCEL_DISABLED) {
1873                 cfb_fillrect(info, region);
1874                 return;
1875         }
1876
1877         vxres = info->var.xres_virtual;
1878         vyres = info->var.yres_virtual;
1879
1880         memcpy(&modded, region, sizeof(struct fb_fillrect));
1881
1882         if (!modded.width || !modded.height ||
1883            modded.dx >= vxres || modded.dy >= vyres)
1884                 return;
1885
1886         if (modded.dx + modded.width  > vxres)
1887                 modded.width  = vxres - modded.dx;
1888         if (modded.dy + modded.height > vyres)
1889                 modded.height = vyres - modded.dy;
1890
1891         cirrusfb_RectFill(cinfo->regbase,
1892                           info->var.bits_per_pixel,
1893                           (region->dx * m) / 8, region->dy,
1894                           (region->width * m) / 8, region->height,
1895                           color,
1896                           info->fix.line_length);
1897 }
1898
1899 static void cirrusfb_copyarea(struct fb_info *info,
1900                               const struct fb_copyarea *area)
1901 {
1902         struct fb_copyarea modded;
1903         u32 vxres, vyres;
1904         struct cirrusfb_info *cinfo = info->par;
1905         int m = info->var.bits_per_pixel;
1906
1907         if (info->state != FBINFO_STATE_RUNNING)
1908                 return;
1909         if (info->flags & FBINFO_HWACCEL_DISABLED) {
1910                 cfb_copyarea(info, area);
1911                 return;
1912         }
1913
1914         vxres = info->var.xres_virtual;
1915         vyres = info->var.yres_virtual;
1916         memcpy(&modded, area, sizeof(struct fb_copyarea));
1917
1918         if (!modded.width || !modded.height ||
1919            modded.sx >= vxres || modded.sy >= vyres ||
1920            modded.dx >= vxres || modded.dy >= vyres)
1921                 return;
1922
1923         if (modded.sx + modded.width > vxres)
1924                 modded.width = vxres - modded.sx;
1925         if (modded.dx + modded.width > vxres)
1926                 modded.width = vxres - modded.dx;
1927         if (modded.sy + modded.height > vyres)
1928                 modded.height = vyres - modded.sy;
1929         if (modded.dy + modded.height > vyres)
1930                 modded.height = vyres - modded.dy;
1931
1932         cirrusfb_BitBLT(cinfo->regbase, info->var.bits_per_pixel,
1933                         (area->sx * m) / 8, area->sy,
1934                         (area->dx * m) / 8, area->dy,
1935                         (area->width * m) / 8, area->height,
1936                         info->fix.line_length);
1937
1938 }
1939
1940 static void cirrusfb_imageblit(struct fb_info *info,
1941                                const struct fb_image *image)
1942 {
1943         struct cirrusfb_info *cinfo = info->par;
1944
1945         cirrusfb_WaitBLT(cinfo->regbase);
1946         cfb_imageblit(info, image);
1947 }
1948
1949 #ifdef CONFIG_PPC_PREP
1950 #define PREP_VIDEO_BASE ((volatile unsigned long) 0xC0000000)
1951 #define PREP_IO_BASE    ((volatile unsigned char *) 0x80000000)
1952 static void get_prep_addrs(unsigned long *display, unsigned long *registers)
1953 {
1954         *display = PREP_VIDEO_BASE;
1955         *registers = (unsigned long) PREP_IO_BASE;
1956 }
1957
1958 #endif                          /* CONFIG_PPC_PREP */
1959
1960 #ifdef CONFIG_PCI
1961 static int release_io_ports;
1962
1963 /* Pulled the logic from XFree86 Cirrus driver to get the memory size,
1964  * based on the DRAM bandwidth bit and DRAM bank switching bit.  This
1965  * works with 1MB, 2MB and 4MB configurations (which the Motorola boards
1966  * seem to have. */
1967 static unsigned int __devinit cirrusfb_get_memsize(struct fb_info *info,
1968                                                    u8 __iomem *regbase)
1969 {
1970         unsigned long mem;
1971         struct cirrusfb_info *cinfo = info->par;
1972
1973         if (cinfo->btype == BT_LAGUNA) {
1974                 unsigned char SR14 = vga_rseq(regbase, CL_SEQR14);
1975
1976                 mem = ((SR14 & 7) + 1) << 20;
1977         } else {
1978                 unsigned char SRF = vga_rseq(regbase, CL_SEQRF);
1979                 switch ((SRF & 0x18)) {
1980                 case 0x08:
1981                         mem = 512 * 1024;
1982                         break;
1983                 case 0x10:
1984                         mem = 1024 * 1024;
1985                         break;
1986                 /* 64-bit DRAM data bus width; assume 2MB.
1987                  * Also indicates 2MB memory on the 5430.
1988                  */
1989                 case 0x18:
1990                         mem = 2048 * 1024;
1991                         break;
1992                 default:
1993                         dev_warn(info->device, "Unknown memory size!\n");
1994                         mem = 1024 * 1024;
1995                 }
1996                 /* If DRAM bank switching is enabled, there must be
1997                  * twice as much memory installed. (4MB on the 5434)
1998                  */
1999                 if (SRF & 0x80)
2000                         mem *= 2;
2001         }
2002
2003         /* TODO: Handling of GD5446/5480 (see XF86 sources ...) */
2004         return mem;
2005 }
2006
2007 static void get_pci_addrs(const struct pci_dev *pdev,
2008                           unsigned long *display, unsigned long *registers)
2009 {
2010         assert(pdev != NULL);
2011         assert(display != NULL);
2012         assert(registers != NULL);
2013
2014         *display = 0;
2015         *registers = 0;
2016
2017         /* This is a best-guess for now */
2018
2019         if (pci_resource_flags(pdev, 0) & IORESOURCE_IO) {
2020                 *display = pci_resource_start(pdev, 1);
2021                 *registers = pci_resource_start(pdev, 0);
2022         } else {
2023                 *display = pci_resource_start(pdev, 0);
2024                 *registers = pci_resource_start(pdev, 1);
2025         }
2026
2027         assert(*display != 0);
2028 }
2029
2030 static void cirrusfb_pci_unmap(struct fb_info *info)
2031 {
2032         struct pci_dev *pdev = to_pci_dev(info->device);
2033         struct cirrusfb_info *cinfo = info->par;
2034
2035         if (cinfo->laguna_mmio == NULL)
2036                 iounmap(cinfo->laguna_mmio);
2037         iounmap(info->screen_base);
2038 #if 0 /* if system didn't claim this region, we would... */
2039         release_mem_region(0xA0000, 65535);
2040 #endif
2041         if (release_io_ports)
2042                 release_region(0x3C0, 32);
2043         pci_release_regions(pdev);
2044 }
2045 #endif /* CONFIG_PCI */
2046
2047 #ifdef CONFIG_ZORRO
2048 static void cirrusfb_zorro_unmap(struct fb_info *info)
2049 {
2050         struct cirrusfb_info *cinfo = info->par;
2051         struct zorro_dev *zdev = to_zorro_dev(info->device);
2052
2053         zorro_release_device(zdev);
2054
2055         if (cinfo->btype == BT_PICASSO4) {
2056                 cinfo->regbase -= 0x600000;
2057                 iounmap((void *)cinfo->regbase);
2058                 iounmap(info->screen_base);
2059         } else {
2060                 if (zorro_resource_start(zdev) > 0x01000000)
2061                         iounmap(info->screen_base);
2062         }
2063 }
2064 #endif /* CONFIG_ZORRO */
2065
2066 static int __devinit cirrusfb_set_fbinfo(struct fb_info *info)
2067 {
2068         struct cirrusfb_info *cinfo = info->par;
2069         struct fb_var_screeninfo *var = &info->var;
2070
2071         info->pseudo_palette = cinfo->pseudo_palette;
2072         info->flags = FBINFO_DEFAULT
2073                     | FBINFO_HWACCEL_XPAN
2074                     | FBINFO_HWACCEL_YPAN
2075                     | FBINFO_HWACCEL_FILLRECT
2076                     | FBINFO_HWACCEL_COPYAREA;
2077         if (noaccel)
2078                 info->flags |= FBINFO_HWACCEL_DISABLED;
2079         info->fbops = &cirrusfb_ops;
2080         if (cinfo->btype == BT_GD5480) {
2081                 if (var->bits_per_pixel == 16)
2082                         info->screen_base += 1 * MB_;
2083                 if (var->bits_per_pixel == 32)
2084                         info->screen_base += 2 * MB_;
2085         }
2086
2087         /* Fill fix common fields */
2088         strlcpy(info->fix.id, cirrusfb_board_info[cinfo->btype].name,
2089                 sizeof(info->fix.id));
2090
2091         /* monochrome: only 1 memory plane */
2092         /* 8 bit and above: Use whole memory area */
2093         info->fix.smem_len   = info->screen_size;
2094         if (var->bits_per_pixel == 1)
2095                 info->fix.smem_len /= 4;
2096         info->fix.type_aux   = 0;
2097         info->fix.xpanstep   = 1;
2098         info->fix.ypanstep   = 1;
2099         info->fix.ywrapstep  = 0;
2100
2101         /* FIXME: map region at 0xB8000 if available, fill in here */
2102         info->fix.mmio_len   = 0;
2103         info->fix.accel = FB_ACCEL_NONE;
2104
2105         fb_alloc_cmap(&info->cmap, 256, 0);
2106
2107         return 0;
2108 }
2109
2110 static int __devinit cirrusfb_register(struct fb_info *info)
2111 {
2112         struct cirrusfb_info *cinfo = info->par;
2113         int err;
2114         enum cirrus_board btype;
2115
2116         btype = cinfo->btype;
2117
2118         /* sanity checks */
2119         assert(btype != BT_NONE);
2120
2121         /* set all the vital stuff */
2122         cirrusfb_set_fbinfo(info);
2123
2124         dev_dbg(info->device, "(RAM start set to: 0x%p)\n", info->screen_base);
2125
2126         err = fb_find_mode(&info->var, info, mode_option, NULL, 0, NULL, 8);
2127         if (!err) {
2128                 dev_dbg(info->device, "wrong initial video mode\n");
2129                 err = -EINVAL;
2130                 goto err_dealloc_cmap;
2131         }
2132
2133         info->var.activate = FB_ACTIVATE_NOW;
2134
2135         err = cirrusfb_decode_var(&info->var, &cinfo->currentmode, info);
2136         if (err < 0) {
2137                 /* should never happen */
2138                 dev_dbg(info->device,
2139                         "choking on default var... umm, no good.\n");
2140                 goto err_dealloc_cmap;
2141         }
2142
2143         err = register_framebuffer(info);
2144         if (err < 0) {
2145                 dev_err(info->device,
2146                         "could not register fb device; err = %d!\n", err);
2147                 goto err_dealloc_cmap;
2148         }
2149
2150         return 0;
2151
2152 err_dealloc_cmap:
2153         fb_dealloc_cmap(&info->cmap);
2154         cinfo->unmap(info);
2155         framebuffer_release(info);
2156         return err;
2157 }
2158
2159 static void __devexit cirrusfb_cleanup(struct fb_info *info)
2160 {
2161         struct cirrusfb_info *cinfo = info->par;
2162
2163         switch_monitor(cinfo, 0);
2164         unregister_framebuffer(info);
2165         fb_dealloc_cmap(&info->cmap);
2166         dev_dbg(info->device, "Framebuffer unregistered\n");
2167         cinfo->unmap(info);
2168         framebuffer_release(info);
2169 }
2170
2171 #ifdef CONFIG_PCI
2172 static int __devinit cirrusfb_pci_register(struct pci_dev *pdev,
2173                                            const struct pci_device_id *ent)
2174 {
2175         struct cirrusfb_info *cinfo;
2176         struct fb_info *info;
2177         enum cirrus_board btype;
2178         unsigned long board_addr, board_size;
2179         int ret;
2180
2181         ret = pci_enable_device(pdev);
2182         if (ret < 0) {
2183                 printk(KERN_ERR "cirrusfb: Cannot enable PCI device\n");
2184                 goto err_out;
2185         }
2186
2187         info = framebuffer_alloc(sizeof(struct cirrusfb_info), &pdev->dev);
2188         if (!info) {
2189                 printk(KERN_ERR "cirrusfb: could not allocate memory\n");
2190                 ret = -ENOMEM;
2191                 goto err_disable;
2192         }
2193
2194         cinfo = info->par;
2195         cinfo->btype = btype = (enum cirrus_board) ent->driver_data;
2196
2197         dev_dbg(info->device,
2198                 " Found PCI device, base address 0 is 0x%Lx, btype set to %d\n",
2199                 (unsigned long long)pdev->resource[0].start, btype);
2200         dev_dbg(info->device, " base address 1 is 0x%Lx\n",
2201                 (unsigned long long)pdev->resource[1].start);
2202
2203         if (isPReP) {
2204                 pci_write_config_dword(pdev, PCI_BASE_ADDRESS_0, 0x00000000);
2205 #ifdef CONFIG_PPC_PREP
2206                 get_prep_addrs(&board_addr, &info->fix.mmio_start);
2207 #endif
2208         /* PReP dies if we ioremap the IO registers, but it works w/out... */
2209                 cinfo->regbase = (char __iomem *) info->fix.mmio_start;
2210         } else {
2211                 dev_dbg(info->device,
2212                         "Attempt to get PCI info for Cirrus Graphics Card\n");
2213                 get_pci_addrs(pdev, &board_addr, &info->fix.mmio_start);
2214                 /* FIXME: this forces VGA.  alternatives? */
2215                 cinfo->regbase = NULL;
2216                 cinfo->laguna_mmio = ioremap(info->fix.mmio_start, 0x1000);
2217         }
2218
2219         dev_dbg(info->device, "Board address: 0x%lx, register address: 0x%lx\n",
2220                 board_addr, info->fix.mmio_start);
2221
2222         board_size = (btype == BT_GD5480) ?
2223                 32 * MB_ : cirrusfb_get_memsize(info, cinfo->regbase);
2224
2225         ret = pci_request_regions(pdev, "cirrusfb");
2226         if (ret < 0) {
2227                 dev_err(info->device, "cannot reserve region 0x%lx, abort\n",
2228                         board_addr);
2229                 goto err_release_fb;
2230         }
2231 #if 0 /* if the system didn't claim this region, we would... */
2232         if (!request_mem_region(0xA0000, 65535, "cirrusfb")) {
2233                 dev_err(info->device, "cannot reserve region 0x%lx, abort\n",
2234                         0xA0000L);
2235                 ret = -EBUSY;
2236                 goto err_release_regions;
2237         }
2238 #endif
2239         if (request_region(0x3C0, 32, "cirrusfb"))
2240                 release_io_ports = 1;
2241
2242         info->screen_base = ioremap(board_addr, board_size);
2243         if (!info->screen_base) {
2244                 ret = -EIO;
2245                 goto err_release_legacy;
2246         }
2247
2248         info->fix.smem_start = board_addr;
2249         info->screen_size = board_size;
2250         cinfo->unmap = cirrusfb_pci_unmap;
2251
2252         dev_info(info->device,
2253                  "Cirrus Logic chipset on PCI bus, RAM (%lu kB) at 0x%lx\n",
2254                  info->screen_size >> 10, board_addr);
2255         pci_set_drvdata(pdev, info);
2256
2257         ret = cirrusfb_register(info);
2258         if (ret)
2259                 iounmap(info->screen_base);
2260         return ret;
2261
2262 err_release_legacy:
2263         if (release_io_ports)
2264                 release_region(0x3C0, 32);
2265 #if 0
2266         release_mem_region(0xA0000, 65535);
2267 err_release_regions:
2268 #endif
2269         pci_release_regions(pdev);
2270 err_release_fb:
2271         if (cinfo->laguna_mmio == NULL)
2272                 iounmap(cinfo->laguna_mmio);
2273         framebuffer_release(info);
2274 err_disable:
2275 err_out:
2276         return ret;
2277 }
2278
2279 static void __devexit cirrusfb_pci_unregister(struct pci_dev *pdev)
2280 {
2281         struct fb_info *info = pci_get_drvdata(pdev);
2282
2283         cirrusfb_cleanup(info);
2284 }
2285
2286 static struct pci_driver cirrusfb_pci_driver = {
2287         .name           = "cirrusfb",
2288         .id_table       = cirrusfb_pci_table,
2289         .probe          = cirrusfb_pci_register,
2290         .remove         = __devexit_p(cirrusfb_pci_unregister),
2291 #ifdef CONFIG_PM
2292 #if 0
2293         .suspend        = cirrusfb_pci_suspend,
2294         .resume         = cirrusfb_pci_resume,
2295 #endif
2296 #endif
2297 };
2298 #endif /* CONFIG_PCI */
2299
2300 #ifdef CONFIG_ZORRO
2301 static int __devinit cirrusfb_zorro_register(struct zorro_dev *z,
2302                                              const struct zorro_device_id *ent)
2303 {
2304         struct cirrusfb_info *cinfo;
2305         struct fb_info *info;
2306         enum cirrus_board btype;
2307         struct zorro_dev *z2 = NULL;
2308         unsigned long board_addr, board_size, size;
2309         int ret;
2310
2311         btype = ent->driver_data;
2312         if (cirrusfb_zorro_table2[btype].id2)
2313                 z2 = zorro_find_device(cirrusfb_zorro_table2[btype].id2, NULL);
2314         size = cirrusfb_zorro_table2[btype].size;
2315
2316         info = framebuffer_alloc(sizeof(struct cirrusfb_info), &z->dev);
2317         if (!info) {
2318                 printk(KERN_ERR "cirrusfb: could not allocate memory\n");
2319                 ret = -ENOMEM;
2320                 goto err_out;
2321         }
2322
2323         dev_info(info->device, "%s board detected\n",
2324                  cirrusfb_board_info[btype].name);
2325
2326         cinfo = info->par;
2327         cinfo->btype = btype;
2328
2329         assert(z);
2330         assert(btype != BT_NONE);
2331
2332         board_addr = zorro_resource_start(z);
2333         board_size = zorro_resource_len(z);
2334         info->screen_size = size;
2335
2336         if (!zorro_request_device(z, "cirrusfb")) {
2337                 dev_err(info->device, "cannot reserve region 0x%lx, abort\n",
2338                         board_addr);
2339                 ret = -EBUSY;
2340                 goto err_release_fb;
2341         }
2342
2343         ret = -EIO;
2344
2345         if (btype == BT_PICASSO4) {
2346                 dev_info(info->device, " REG at $%lx\n", board_addr + 0x600000);
2347
2348                 /* To be precise, for the P4 this is not the */
2349                 /* begin of the board, but the begin of RAM. */
2350                 /* for P4, map in its address space in 2 chunks (### TEST! ) */
2351                 /* (note the ugly hardcoded 16M number) */
2352                 cinfo->regbase = ioremap(board_addr, 16777216);
2353                 if (!cinfo->regbase)
2354                         goto err_release_region;
2355
2356                 dev_dbg(info->device, "Virtual address for board set to: $%p\n",
2357                         cinfo->regbase);
2358                 cinfo->regbase += 0x600000;
2359                 info->fix.mmio_start = board_addr + 0x600000;
2360
2361                 info->fix.smem_start = board_addr + 16777216;
2362                 info->screen_base = ioremap(info->fix.smem_start, 16777216);
2363                 if (!info->screen_base)
2364                         goto err_unmap_regbase;
2365         } else {
2366                 dev_info(info->device, " REG at $%lx\n",
2367                          (unsigned long) z2->resource.start);
2368
2369                 info->fix.smem_start = board_addr;
2370                 if (board_addr > 0x01000000)
2371                         info->screen_base = ioremap(board_addr, board_size);
2372                 else
2373                         info->screen_base = (caddr_t) ZTWO_VADDR(board_addr);
2374                 if (!info->screen_base)
2375                         goto err_release_region;
2376
2377                 /* set address for REG area of board */
2378                 cinfo->regbase = (caddr_t) ZTWO_VADDR(z2->resource.start);
2379                 info->fix.mmio_start = z2->resource.start;
2380
2381                 dev_dbg(info->device, "Virtual address for board set to: $%p\n",
2382                         cinfo->regbase);
2383         }
2384         cinfo->unmap = cirrusfb_zorro_unmap;
2385
2386         dev_info(info->device,
2387                  "Cirrus Logic chipset on Zorro bus, RAM (%lu MB) at $%lx\n",
2388                  board_size / MB_, board_addr);
2389
2390         zorro_set_drvdata(z, info);
2391
2392         ret = cirrusfb_register(info);
2393         if (ret) {
2394                 if (btype == BT_PICASSO4) {
2395                         iounmap(info->screen_base);
2396                         iounmap(cinfo->regbase - 0x600000);
2397                 } else if (board_addr > 0x01000000)
2398                         iounmap(info->screen_base);
2399         }
2400         return ret;
2401
2402 err_unmap_regbase:
2403         /* Parental advisory: explicit hack */
2404         iounmap(cinfo->regbase - 0x600000);
2405 err_release_region:
2406         release_region(board_addr, board_size);
2407 err_release_fb:
2408         framebuffer_release(info);
2409 err_out:
2410         return ret;
2411 }
2412
2413 void __devexit cirrusfb_zorro_unregister(struct zorro_dev *z)
2414 {
2415         struct fb_info *info = zorro_get_drvdata(z);
2416
2417         cirrusfb_cleanup(info);
2418 }
2419
2420 static struct zorro_driver cirrusfb_zorro_driver = {
2421         .name           = "cirrusfb",
2422         .id_table       = cirrusfb_zorro_table,
2423         .probe          = cirrusfb_zorro_register,
2424         .remove         = __devexit_p(cirrusfb_zorro_unregister),
2425 };
2426 #endif /* CONFIG_ZORRO */
2427
2428 static int __init cirrusfb_init(void)
2429 {
2430         int error = 0;
2431
2432 #ifndef MODULE
2433         char *option = NULL;
2434
2435         if (fb_get_options("cirrusfb", &option))
2436                 return -ENODEV;
2437         cirrusfb_setup(option);
2438 #endif
2439
2440 #ifdef CONFIG_ZORRO
2441         error |= zorro_register_driver(&cirrusfb_zorro_driver);
2442 #endif
2443 #ifdef CONFIG_PCI
2444         error |= pci_register_driver(&cirrusfb_pci_driver);
2445 #endif
2446         return error;
2447 }
2448
2449 #ifndef MODULE
2450 static int __init cirrusfb_setup(char *options)
2451 {
2452         char *this_opt;
2453
2454         if (!options || !*options)
2455                 return 0;
2456
2457         while ((this_opt = strsep(&options, ",")) != NULL) {
2458                 if (!*this_opt)
2459                         continue;
2460
2461                 if (!strcmp(this_opt, "noaccel"))
2462                         noaccel = 1;
2463                 else if (!strncmp(this_opt, "mode:", 5))
2464                         mode_option = this_opt + 5;
2465                 else
2466                         mode_option = this_opt;
2467         }
2468         return 0;
2469 }
2470 #endif
2471
2472     /*
2473      *  Modularization
2474      */
2475
2476 MODULE_AUTHOR("Copyright 1999,2000 Jeff Garzik <jgarzik@pobox.com>");
2477 MODULE_DESCRIPTION("Accelerated FBDev driver for Cirrus Logic chips");
2478 MODULE_LICENSE("GPL");
2479
2480 static void __exit cirrusfb_exit(void)
2481 {
2482 #ifdef CONFIG_PCI
2483         pci_unregister_driver(&cirrusfb_pci_driver);
2484 #endif
2485 #ifdef CONFIG_ZORRO
2486         zorro_unregister_driver(&cirrusfb_zorro_driver);
2487 #endif
2488 }
2489
2490 module_init(cirrusfb_init);
2491
2492 module_param(mode_option, charp, 0);
2493 MODULE_PARM_DESC(mode_option, "Initial video mode e.g. '648x480-8@60'");
2494 module_param(noaccel, bool, 0);
2495 MODULE_PARM_DESC(noaccel, "Disable acceleration");
2496
2497 #ifdef MODULE
2498 module_exit(cirrusfb_exit);
2499 #endif
2500
2501 /**********************************************************************/
2502 /* about the following functions - I have used the same names for the */
2503 /* functions as Markus Wild did in his Retina driver for NetBSD as    */
2504 /* they just made sense for this purpose. Apart from that, I wrote    */
2505 /* these functions myself.                                          */
2506 /**********************************************************************/
2507
2508 /*** WGen() - write into one of the external/general registers ***/
2509 static void WGen(const struct cirrusfb_info *cinfo,
2510                   int regnum, unsigned char val)
2511 {
2512         unsigned long regofs = 0;
2513
2514         if (cinfo->btype == BT_PICASSO) {
2515                 /* Picasso II specific hack */
2516 /*            if (regnum == VGA_PEL_IR || regnum == VGA_PEL_D ||
2517                   regnum == CL_VSSM2) */
2518                 if (regnum == VGA_PEL_IR || regnum == VGA_PEL_D)
2519                         regofs = 0xfff;
2520         }
2521
2522         vga_w(cinfo->regbase, regofs + regnum, val);
2523 }
2524
2525 /*** RGen() - read out one of the external/general registers ***/
2526 static unsigned char RGen(const struct cirrusfb_info *cinfo, int regnum)
2527 {
2528         unsigned long regofs = 0;
2529
2530         if (cinfo->btype == BT_PICASSO) {
2531                 /* Picasso II specific hack */
2532 /*            if (regnum == VGA_PEL_IR || regnum == VGA_PEL_D ||
2533                   regnum == CL_VSSM2) */
2534                 if (regnum == VGA_PEL_IR || regnum == VGA_PEL_D)
2535                         regofs = 0xfff;
2536         }
2537
2538         return vga_r(cinfo->regbase, regofs + regnum);
2539 }
2540
2541 /*** AttrOn() - turn on VideoEnable for Attribute controller ***/
2542 static void AttrOn(const struct cirrusfb_info *cinfo)
2543 {
2544         assert(cinfo != NULL);
2545
2546         if (vga_rcrt(cinfo->regbase, CL_CRT24) & 0x80) {
2547                 /* if we're just in "write value" mode, write back the */
2548                 /* same value as before to not modify anything */
2549                 vga_w(cinfo->regbase, VGA_ATT_IW,
2550                       vga_r(cinfo->regbase, VGA_ATT_R));
2551         }
2552         /* turn on video bit */
2553 /*      vga_w(cinfo->regbase, VGA_ATT_IW, 0x20); */
2554         vga_w(cinfo->regbase, VGA_ATT_IW, 0x33);
2555
2556         /* dummy write on Reg0 to be on "write index" mode next time */
2557         vga_w(cinfo->regbase, VGA_ATT_IW, 0x00);
2558 }
2559
2560 /*** WHDR() - write into the Hidden DAC register ***/
2561 /* as the HDR is the only extension register that requires special treatment
2562  * (the other extension registers are accessible just like the "ordinary"
2563  * registers of their functional group) here is a specialized routine for
2564  * accessing the HDR
2565  */
2566 static void WHDR(const struct cirrusfb_info *cinfo, unsigned char val)
2567 {
2568         unsigned char dummy;
2569
2570         if (cinfo->btype == BT_PICASSO) {
2571                 /* Klaus' hint for correct access to HDR on some boards */
2572                 /* first write 0 to pixel mask (3c6) */
2573                 WGen(cinfo, VGA_PEL_MSK, 0x00);
2574                 udelay(200);
2575                 /* next read dummy from pixel address (3c8) */
2576                 dummy = RGen(cinfo, VGA_PEL_IW);
2577                 udelay(200);
2578         }
2579         /* now do the usual stuff to access the HDR */
2580
2581         dummy = RGen(cinfo, VGA_PEL_MSK);
2582         udelay(200);
2583         dummy = RGen(cinfo, VGA_PEL_MSK);
2584         udelay(200);
2585         dummy = RGen(cinfo, VGA_PEL_MSK);
2586         udelay(200);
2587         dummy = RGen(cinfo, VGA_PEL_MSK);
2588         udelay(200);
2589
2590         WGen(cinfo, VGA_PEL_MSK, val);
2591         udelay(200);
2592
2593         if (cinfo->btype == BT_PICASSO) {
2594                 /* now first reset HDR access counter */
2595                 dummy = RGen(cinfo, VGA_PEL_IW);
2596                 udelay(200);
2597
2598                 /* and at the end, restore the mask value */
2599                 /* ## is this mask always 0xff? */
2600                 WGen(cinfo, VGA_PEL_MSK, 0xff);
2601                 udelay(200);
2602         }
2603 }
2604
2605 /*** WSFR() - write to the "special function register" (SFR) ***/
2606 static void WSFR(struct cirrusfb_info *cinfo, unsigned char val)
2607 {
2608 #ifdef CONFIG_ZORRO
2609         assert(cinfo->regbase != NULL);
2610         cinfo->SFR = val;
2611         z_writeb(val, cinfo->regbase + 0x8000);
2612 #endif
2613 }
2614
2615 /* The Picasso has a second register for switching the monitor bit */
2616 static void WSFR2(struct cirrusfb_info *cinfo, unsigned char val)
2617 {
2618 #ifdef CONFIG_ZORRO
2619         /* writing an arbitrary value to this one causes the monitor switcher */
2620         /* to flip to Amiga display */
2621         assert(cinfo->regbase != NULL);
2622         cinfo->SFR = val;
2623         z_writeb(val, cinfo->regbase + 0x9000);
2624 #endif
2625 }
2626
2627 /*** WClut - set CLUT entry (range: 0..63) ***/
2628 static void WClut(struct cirrusfb_info *cinfo, unsigned char regnum, unsigned char red,
2629             unsigned char green, unsigned char blue)
2630 {
2631         unsigned int data = VGA_PEL_D;
2632
2633         /* address write mode register is not translated.. */
2634         vga_w(cinfo->regbase, VGA_PEL_IW, regnum);
2635
2636         if (cinfo->btype == BT_PICASSO || cinfo->btype == BT_PICASSO4 ||
2637             cinfo->btype == BT_ALPINE || cinfo->btype == BT_GD5480) {
2638                 /* but DAC data register IS, at least for Picasso II */
2639                 if (cinfo->btype == BT_PICASSO)
2640                         data += 0xfff;
2641                 vga_w(cinfo->regbase, data, red);
2642                 vga_w(cinfo->regbase, data, green);
2643                 vga_w(cinfo->regbase, data, blue);
2644         } else {
2645                 vga_w(cinfo->regbase, data, blue);
2646                 vga_w(cinfo->regbase, data, green);
2647                 vga_w(cinfo->regbase, data, red);
2648         }
2649 }
2650
2651 #if 0
2652 /*** RClut - read CLUT entry (range 0..63) ***/
2653 static void RClut(struct cirrusfb_info *cinfo, unsigned char regnum, unsigned char *red,
2654             unsigned char *green, unsigned char *blue)
2655 {
2656         unsigned int data = VGA_PEL_D;
2657
2658         vga_w(cinfo->regbase, VGA_PEL_IR, regnum);
2659
2660         if (cinfo->btype == BT_PICASSO || cinfo->btype == BT_PICASSO4 ||
2661             cinfo->btype == BT_ALPINE || cinfo->btype == BT_GD5480) {
2662                 if (cinfo->btype == BT_PICASSO)
2663                         data += 0xfff;
2664                 *red = vga_r(cinfo->regbase, data);
2665                 *green = vga_r(cinfo->regbase, data);
2666                 *blue = vga_r(cinfo->regbase, data);
2667         } else {
2668                 *blue = vga_r(cinfo->regbase, data);
2669                 *green = vga_r(cinfo->regbase, data);
2670                 *red = vga_r(cinfo->regbase, data);
2671         }
2672 }
2673 #endif
2674
2675 /*******************************************************************
2676         cirrusfb_WaitBLT()
2677
2678         Wait for the BitBLT engine to complete a possible earlier job
2679 *********************************************************************/
2680
2681 /* FIXME: use interrupts instead */
2682 static void cirrusfb_WaitBLT(u8 __iomem *regbase)
2683 {
2684         /* now busy-wait until we're done */
2685         while (vga_rgfx(regbase, CL_GR31) & 0x08)
2686                 /* do nothing */ ;
2687 }
2688
2689 /*******************************************************************
2690         cirrusfb_BitBLT()
2691
2692         perform accelerated "scrolling"
2693 ********************************************************************/
2694
2695 static void cirrusfb_BitBLT(u8 __iomem *regbase, int bits_per_pixel,
2696                             u_short curx, u_short cury,
2697                             u_short destx, u_short desty,
2698                             u_short width, u_short height,
2699                             u_short line_length)
2700 {
2701         u_short nwidth, nheight;
2702         u_long nsrc, ndest;
2703         u_char bltmode;
2704
2705         nwidth = width - 1;
2706         nheight = height - 1;
2707
2708         bltmode = 0x00;
2709         /* if source adr < dest addr, do the Blt backwards */
2710         if (cury <= desty) {
2711                 if (cury == desty) {
2712                         /* if src and dest are on the same line, check x */
2713                         if (curx < destx)
2714                                 bltmode |= 0x01;
2715                 } else
2716                         bltmode |= 0x01;
2717         }
2718         if (!bltmode) {
2719                 /* standard case: forward blitting */
2720                 nsrc = (cury * line_length) + curx;
2721                 ndest = (desty * line_length) + destx;
2722         } else {
2723                 /* this means start addresses are at the end,
2724                  * counting backwards
2725                  */
2726                 nsrc = cury * line_length + curx +
2727                         nheight * line_length + nwidth;
2728                 ndest = desty * line_length + destx +
2729                         nheight * line_length + nwidth;
2730         }
2731
2732         /*
2733            run-down of registers to be programmed:
2734            destination pitch
2735            source pitch
2736            BLT width/height
2737            source start
2738            destination start
2739            BLT mode
2740            BLT ROP
2741            VGA_GFX_SR_VALUE / VGA_GFX_SR_ENABLE: "fill color"
2742            start/stop
2743          */
2744
2745         cirrusfb_WaitBLT(regbase);
2746
2747         /* pitch: set to line_length */
2748         /* dest pitch low */
2749         vga_wgfx(regbase, CL_GR24, line_length & 0xff);
2750         /* dest pitch hi */
2751         vga_wgfx(regbase, CL_GR25, line_length >> 8);
2752         /* source pitch low */
2753         vga_wgfx(regbase, CL_GR26, line_length & 0xff);
2754         /* source pitch hi */
2755         vga_wgfx(regbase, CL_GR27, line_length >> 8);
2756
2757         /* BLT width: actual number of pixels - 1 */
2758         /* BLT width low */
2759         vga_wgfx(regbase, CL_GR20, nwidth & 0xff);
2760         /* BLT width hi */
2761         vga_wgfx(regbase, CL_GR21, nwidth >> 8);
2762
2763         /* BLT height: actual number of lines -1 */
2764         /* BLT height low */
2765         vga_wgfx(regbase, CL_GR22, nheight & 0xff);
2766         /* BLT width hi */
2767         vga_wgfx(regbase, CL_GR23, nheight >> 8);
2768
2769         /* BLT destination */
2770         /* BLT dest low */
2771         vga_wgfx(regbase, CL_GR28, (u_char) (ndest & 0xff));
2772         /* BLT dest mid */
2773         vga_wgfx(regbase, CL_GR29, (u_char) (ndest >> 8));
2774         /* BLT dest hi */
2775         vga_wgfx(regbase, CL_GR2A, (u_char) (ndest >> 16));
2776
2777         /* BLT source */
2778         /* BLT src low */
2779         vga_wgfx(regbase, CL_GR2C, (u_char) (nsrc & 0xff));
2780         /* BLT src mid */
2781         vga_wgfx(regbase, CL_GR2D, (u_char) (nsrc >> 8));
2782         /* BLT src hi */
2783         vga_wgfx(regbase, CL_GR2E, (u_char) (nsrc >> 16));
2784
2785         /* BLT mode */
2786         vga_wgfx(regbase, CL_GR30, bltmode);    /* BLT mode */
2787
2788         /* BLT ROP: SrcCopy */
2789         vga_wgfx(regbase, CL_GR32, 0x0d);       /* BLT ROP */
2790
2791         /* and finally: GO! */
2792         vga_wgfx(regbase, CL_GR31, 0x02);       /* BLT Start/status */
2793 }
2794
2795 /*******************************************************************
2796         cirrusfb_RectFill()
2797
2798         perform accelerated rectangle fill
2799 ********************************************************************/
2800
2801 static void cirrusfb_RectFill(u8 __iomem *regbase, int bits_per_pixel,
2802                      u_short x, u_short y, u_short width, u_short height,
2803                      u_char color, u_short line_length)
2804 {
2805         u_short nwidth, nheight;
2806         u_long ndest;
2807         u_char op;
2808
2809         nwidth = width - 1;
2810         nheight = height - 1;
2811
2812         ndest = (y * line_length) + x;
2813
2814         cirrusfb_WaitBLT(regbase);
2815
2816         /* pitch: set to line_length */
2817         vga_wgfx(regbase, CL_GR24, line_length & 0xff); /* dest pitch low */
2818         vga_wgfx(regbase, CL_GR25, line_length >> 8);   /* dest pitch hi */
2819         vga_wgfx(regbase, CL_GR26, line_length & 0xff); /* source pitch low */
2820         vga_wgfx(regbase, CL_GR27, line_length >> 8);   /* source pitch hi */
2821
2822         /* BLT width: actual number of pixels - 1 */
2823         vga_wgfx(regbase, CL_GR20, nwidth & 0xff);      /* BLT width low */
2824         vga_wgfx(regbase, CL_GR21, nwidth >> 8);        /* BLT width hi */
2825
2826         /* BLT height: actual number of lines -1 */
2827         vga_wgfx(regbase, CL_GR22, nheight & 0xff);     /* BLT height low */
2828         vga_wgfx(regbase, CL_GR23, nheight >> 8);       /* BLT width hi */
2829
2830         /* BLT destination */
2831         /* BLT dest low */
2832         vga_wgfx(regbase, CL_GR28, (u_char) (ndest & 0xff));
2833         /* BLT dest mid */
2834         vga_wgfx(regbase, CL_GR29, (u_char) (ndest >> 8));
2835         /* BLT dest hi */
2836         vga_wgfx(regbase, CL_GR2A, (u_char) (ndest >> 16));
2837
2838         /* BLT source: set to 0 (is a dummy here anyway) */
2839         vga_wgfx(regbase, CL_GR2C, 0x00);       /* BLT src low */
2840         vga_wgfx(regbase, CL_GR2D, 0x00);       /* BLT src mid */
2841         vga_wgfx(regbase, CL_GR2E, 0x00);       /* BLT src hi */
2842
2843         /* This is a ColorExpand Blt, using the */
2844         /* same color for foreground and background */
2845         vga_wgfx(regbase, VGA_GFX_SR_VALUE, color);     /* foreground color */
2846         vga_wgfx(regbase, VGA_GFX_SR_ENABLE, color);    /* background color */
2847
2848         op = 0xc0;
2849         if (bits_per_pixel == 16) {
2850                 vga_wgfx(regbase, CL_GR10, color);      /* foreground color */
2851                 vga_wgfx(regbase, CL_GR11, color);      /* background color */
2852                 op = 0x50;
2853                 op = 0xd0;
2854         } else if (bits_per_pixel == 32) {
2855                 vga_wgfx(regbase, CL_GR10, color);      /* foreground color */
2856                 vga_wgfx(regbase, CL_GR11, color);      /* background color */
2857                 vga_wgfx(regbase, CL_GR12, color);      /* foreground color */
2858                 vga_wgfx(regbase, CL_GR13, color);      /* background color */
2859                 vga_wgfx(regbase, CL_GR14, 0);  /* foreground color */
2860                 vga_wgfx(regbase, CL_GR15, 0);  /* background color */
2861                 op = 0x50;
2862                 op = 0xf0;
2863         }
2864         /* BLT mode: color expand, Enable 8x8 copy (faster?) */
2865         vga_wgfx(regbase, CL_GR30, op); /* BLT mode */
2866
2867         /* BLT ROP: SrcCopy */
2868         vga_wgfx(regbase, CL_GR32, 0x0d);       /* BLT ROP */
2869
2870         /* and finally: GO! */
2871         vga_wgfx(regbase, CL_GR31, 0x02);       /* BLT Start/status */
2872 }
2873
2874 /**************************************************************************
2875  * bestclock() - determine closest possible clock lower(?) than the
2876  * desired pixel clock
2877  **************************************************************************/
2878 static void bestclock(long freq, int *nom, int *den, int *div)
2879 {
2880         int n, d;
2881         long h, diff;
2882
2883         assert(nom != NULL);
2884         assert(den != NULL);
2885         assert(div != NULL);
2886
2887         *nom = 0;
2888         *den = 0;
2889         *div = 0;
2890
2891         if (freq < 8000)
2892                 freq = 8000;
2893
2894         diff = freq;
2895
2896         for (n = 32; n < 128; n++) {
2897                 int s = 0;
2898
2899                 d = (14318 * n) / freq;
2900                 if ((d >= 7) && (d <= 63)) {
2901                         int temp = d;
2902
2903                         if (temp > 31) {
2904                                 s = 1;
2905                                 temp >>= 1;
2906                         }
2907                         h = ((14318 * n) / temp) >> s;
2908                         h = h > freq ? h - freq : freq - h;
2909                         if (h < diff) {
2910                                 diff = h;
2911                                 *nom = n;
2912                                 *den = temp;
2913                                 *div = s;
2914                         }
2915                 }
2916                 d++;
2917                 if ((d >= 7) && (d <= 63)) {
2918                         if (d > 31) {
2919                                 s = 1;
2920                                 d >>= 1;
2921                         }
2922                         h = ((14318 * n) / d) >> s;
2923                         h = h > freq ? h - freq : freq - h;
2924                         if (h < diff) {
2925                                 diff = h;
2926                                 *nom = n;
2927                                 *den = d;
2928                                 *div = s;
2929                         }
2930                 }
2931         }
2932 }
2933
2934 /* -------------------------------------------------------------------------
2935  *
2936  * debugging functions
2937  *
2938  * -------------------------------------------------------------------------
2939  */
2940
2941 #ifdef CIRRUSFB_DEBUG
2942
2943 /**
2944  * cirrusfb_dbg_print_regs
2945  * @base: If using newmmio, the newmmio base address, otherwise %NULL
2946  * @reg_class: type of registers to read: %CRT, or %SEQ
2947  *
2948  * DESCRIPTION:
2949  * Dumps the given list of VGA CRTC registers.  If @base is %NULL,
2950  * old-style I/O ports are queried for information, otherwise MMIO is
2951  * used at the given @base address to query the information.
2952  */
2953
2954 static void cirrusfb_dbg_print_regs(struct fb_info *info,
2955                                     caddr_t regbase,
2956                                     enum cirrusfb_dbg_reg_class reg_class, ...)
2957 {
2958         va_list list;
2959         unsigned char val = 0;
2960         unsigned reg;
2961         char *name;
2962
2963         va_start(list, reg_class);
2964
2965         name = va_arg(list, char *);
2966         while (name != NULL) {
2967                 reg = va_arg(list, int);
2968
2969                 switch (reg_class) {
2970                 case CRT:
2971                         val = vga_rcrt(regbase, (unsigned char) reg);
2972                         break;
2973                 case SEQ:
2974                         val = vga_rseq(regbase, (unsigned char) reg);
2975                         break;
2976                 default:
2977                         /* should never occur */
2978                         assert(false);
2979                         break;
2980                 }
2981
2982                 dev_dbg(info->device, "%8s = 0x%02X\n", name, val);
2983
2984                 name = va_arg(list, char *);
2985         }
2986
2987         va_end(list);
2988 }
2989
2990 /**
2991  * cirrusfb_dbg_reg_dump
2992  * @base: If using newmmio, the newmmio base address, otherwise %NULL
2993  *
2994  * DESCRIPTION:
2995  * Dumps a list of interesting VGA and CIRRUSFB registers.  If @base is %NULL,
2996  * old-style I/O ports are queried for information, otherwise MMIO is
2997  * used at the given @base address to query the information.
2998  */
2999
3000 static void cirrusfb_dbg_reg_dump(struct fb_info *info, caddr_t regbase)
3001 {
3002         dev_dbg(info->device, "VGA CRTC register dump:\n");
3003
3004         cirrusfb_dbg_print_regs(info, regbase, CRT,
3005                            "CR00", 0x00,
3006                            "CR01", 0x01,
3007                            "CR02", 0x02,
3008                            "CR03", 0x03,
3009                            "CR04", 0x04,
3010                            "CR05", 0x05,
3011                            "CR06", 0x06,
3012                            "CR07", 0x07,
3013                            "CR08", 0x08,
3014                            "CR09", 0x09,
3015                            "CR0A", 0x0A,
3016                            "CR0B", 0x0B,
3017                            "CR0C", 0x0C,
3018                            "CR0D", 0x0D,
3019                            "CR0E", 0x0E,
3020                            "CR0F", 0x0F,
3021                            "CR10", 0x10,
3022                            "CR11", 0x11,
3023                            "CR12", 0x12,
3024                            "CR13", 0x13,
3025                            "CR14", 0x14,
3026                            "CR15", 0x15,
3027                            "CR16", 0x16,
3028                            "CR17", 0x17,
3029                            "CR18", 0x18,
3030                            "CR22", 0x22,
3031                            "CR24", 0x24,
3032                            "CR26", 0x26,
3033                            "CR2D", 0x2D,
3034                            "CR2E", 0x2E,
3035                            "CR2F", 0x2F,
3036                            "CR30", 0x30,
3037                            "CR31", 0x31,
3038                            "CR32", 0x32,
3039                            "CR33", 0x33,
3040                            "CR34", 0x34,
3041                            "CR35", 0x35,
3042                            "CR36", 0x36,
3043                            "CR37", 0x37,
3044                            "CR38", 0x38,
3045                            "CR39", 0x39,
3046                            "CR3A", 0x3A,
3047                            "CR3B", 0x3B,
3048                            "CR3C", 0x3C,
3049                            "CR3D", 0x3D,
3050                            "CR3E", 0x3E,
3051                            "CR3F", 0x3F,
3052                            NULL);
3053
3054         dev_dbg(info->device, "\n");
3055
3056         dev_dbg(info->device, "VGA SEQ register dump:\n");
3057
3058         cirrusfb_dbg_print_regs(info, regbase, SEQ,
3059                            "SR00", 0x00,
3060                            "SR01", 0x01,
3061                            "SR02", 0x02,
3062                            "SR03", 0x03,
3063                            "SR04", 0x04,
3064                            "SR08", 0x08,
3065                            "SR09", 0x09,
3066                            "SR0A", 0x0A,
3067                            "SR0B", 0x0B,
3068                            "SR0D", 0x0D,
3069                            "SR10", 0x10,
3070                            "SR11", 0x11,
3071                            "SR12", 0x12,
3072                            "SR13", 0x13,
3073                            "SR14", 0x14,
3074                            "SR15", 0x15,
3075                            "SR16", 0x16,
3076                            "SR17", 0x17,
3077                            "SR18", 0x18,
3078                            "SR19", 0x19,
3079                            "SR1A", 0x1A,
3080                            "SR1B", 0x1B,
3081                            "SR1C", 0x1C,
3082                            "SR1D", 0x1D,
3083                            "SR1E", 0x1E,
3084                            "SR1F", 0x1F,
3085                            NULL);
3086
3087         dev_dbg(info->device, "\n");
3088 }
3089
3090 #endif                          /* CIRRUSFB_DEBUG */
3091