cirrusfb: add mmio registers for Laguna chipsets
[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 offset = 0, err;
698         const struct cirrusfb_board_info_rec *bi;
699         int hdispend, hsyncstart, hsyncend, htotal;
700         int yres, vdispend, vsyncstart, vsyncend, vtotal;
701         long freq;
702         int nom, den, div;
703         unsigned int control, format, threshold;
704
705         dev_dbg(info->device, "Requested mode: %dx%dx%d\n",
706                var->xres, var->yres, var->bits_per_pixel);
707         dev_dbg(info->device, "pixclock: %d\n", var->pixclock);
708
709         init_vgachip(info);
710
711         err = cirrusfb_decode_var(var, &regs, info);
712         if (err) {
713                 /* should never happen */
714                 dev_dbg(info->device, "mode change aborted.  invalid var.\n");
715                 return -EINVAL;
716         }
717
718         bi = &cirrusfb_board_info[cinfo->btype];
719
720         hsyncstart = var->xres + var->right_margin;
721         hsyncend = hsyncstart + var->hsync_len;
722         htotal = (hsyncend + var->left_margin) / 8 - 5;
723         hdispend = var->xres / 8 - 1;
724         hsyncstart = hsyncstart / 8 + 1;
725         hsyncend = hsyncend / 8 + 1;
726
727         yres = var->yres;
728         vsyncstart = yres + var->lower_margin;
729         vsyncend = vsyncstart + var->vsync_len;
730         vtotal = vsyncend + var->upper_margin;
731         vdispend = yres - 1;
732
733         if (var->vmode & FB_VMODE_DOUBLE) {
734                 yres *= 2;
735                 vsyncstart *= 2;
736                 vsyncend *= 2;
737                 vtotal *= 2;
738         } else if (var->vmode & FB_VMODE_INTERLACED) {
739                 yres = (yres + 1) / 2;
740                 vsyncstart = (vsyncstart + 1) / 2;
741                 vsyncend = (vsyncend + 1) / 2;
742                 vtotal = (vtotal + 1) / 2;
743         }
744
745         vtotal -= 2;
746         vsyncstart -= 1;
747         vsyncend -= 1;
748
749         if (yres >= 1024) {
750                 vtotal /= 2;
751                 vsyncstart /= 2;
752                 vsyncend /= 2;
753                 vdispend /= 2;
754         }
755         if (regs.multiplexing) {
756                 htotal /= 2;
757                 hsyncstart /= 2;
758                 hsyncend /= 2;
759                 hdispend /= 2;
760         }
761         /* unlock register VGA_CRTC_H_TOTAL..CRT7 */
762         vga_wcrt(regbase, VGA_CRTC_V_SYNC_END, 0x20);   /* previously: 0x00) */
763
764         /* if debugging is enabled, all parameters get output before writing */
765         dev_dbg(info->device, "CRT0: %d\n", htotal);
766         vga_wcrt(regbase, VGA_CRTC_H_TOTAL, htotal);
767
768         dev_dbg(info->device, "CRT1: %d\n", hdispend);
769         vga_wcrt(regbase, VGA_CRTC_H_DISP, hdispend);
770
771         dev_dbg(info->device, "CRT2: %d\n", var->xres / 8);
772         vga_wcrt(regbase, VGA_CRTC_H_BLANK_START, var->xres / 8);
773
774         /*  + 128: Compatible read */
775         dev_dbg(info->device, "CRT3: 128+%d\n", (htotal + 5) % 32);
776         vga_wcrt(regbase, VGA_CRTC_H_BLANK_END,
777                  128 + ((htotal + 5) % 32));
778
779         dev_dbg(info->device, "CRT4: %d\n", hsyncstart);
780         vga_wcrt(regbase, VGA_CRTC_H_SYNC_START, hsyncstart);
781
782         tmp = hsyncend % 32;
783         if ((htotal + 5) & 32)
784                 tmp += 128;
785         dev_dbg(info->device, "CRT5: %d\n", tmp);
786         vga_wcrt(regbase, VGA_CRTC_H_SYNC_END, tmp);
787
788         dev_dbg(info->device, "CRT6: %d\n", vtotal & 0xff);
789         vga_wcrt(regbase, VGA_CRTC_V_TOTAL, vtotal & 0xff);
790
791         tmp = 16;               /* LineCompare bit #9 */
792         if (vtotal & 256)
793                 tmp |= 1;
794         if (vdispend & 256)
795                 tmp |= 2;
796         if (vsyncstart & 256)
797                 tmp |= 4;
798         if ((vdispend + 1) & 256)
799                 tmp |= 8;
800         if (vtotal & 512)
801                 tmp |= 32;
802         if (vdispend & 512)
803                 tmp |= 64;
804         if (vsyncstart & 512)
805                 tmp |= 128;
806         dev_dbg(info->device, "CRT7: %d\n", tmp);
807         vga_wcrt(regbase, VGA_CRTC_OVERFLOW, tmp);
808
809         tmp = 0x40;             /* LineCompare bit #8 */
810         if ((vdispend + 1) & 512)
811                 tmp |= 0x20;
812         if (var->vmode & FB_VMODE_DOUBLE)
813                 tmp |= 0x80;
814         dev_dbg(info->device, "CRT9: %d\n", tmp);
815         vga_wcrt(regbase, VGA_CRTC_MAX_SCAN, tmp);
816
817         dev_dbg(info->device, "CRT10: %d\n", vsyncstart & 0xff);
818         vga_wcrt(regbase, VGA_CRTC_V_SYNC_START, vsyncstart & 0xff);
819
820         dev_dbg(info->device, "CRT11: 64+32+%d\n", vsyncend % 16);
821         vga_wcrt(regbase, VGA_CRTC_V_SYNC_END, vsyncend % 16 + 64 + 32);
822
823         dev_dbg(info->device, "CRT12: %d\n", vdispend & 0xff);
824         vga_wcrt(regbase, VGA_CRTC_V_DISP_END, vdispend & 0xff);
825
826         dev_dbg(info->device, "CRT15: %d\n", (vdispend + 1) & 0xff);
827         vga_wcrt(regbase, VGA_CRTC_V_BLANK_START, (vdispend + 1) & 0xff);
828
829         dev_dbg(info->device, "CRT16: %d\n", vtotal & 0xff);
830         vga_wcrt(regbase, VGA_CRTC_V_BLANK_END, vtotal & 0xff);
831
832         dev_dbg(info->device, "CRT18: 0xff\n");
833         vga_wcrt(regbase, VGA_CRTC_LINE_COMPARE, 0xff);
834
835         tmp = 0;
836         if (var->vmode & FB_VMODE_INTERLACED)
837                 tmp |= 1;
838         if ((htotal + 5) & 64)
839                 tmp |= 16;
840         if ((htotal + 5) & 128)
841                 tmp |= 32;
842         if (vtotal & 256)
843                 tmp |= 64;
844         if (vtotal & 512)
845                 tmp |= 128;
846
847         dev_dbg(info->device, "CRT1a: %d\n", tmp);
848         vga_wcrt(regbase, CL_CRT1A, tmp);
849
850         freq = PICOS2KHZ(var->pixclock);
851         bestclock(freq, &nom, &den, &div);
852
853         dev_dbg(info->device, "VCLK freq: %ld kHz  nom: %d  den: %d  div: %d\n",
854                 freq, nom, den, div);
855
856         /* set VCLK0 */
857         /* hardware RefClock: 14.31818 MHz */
858         /* formula: VClk = (OSC * N) / (D * (1+P)) */
859         /* Example: VClk = (14.31818 * 91) / (23 * (1+1)) = 28.325 MHz */
860
861         if (cinfo->btype == BT_ALPINE) {
862                 /* if freq is close to mclk or mclk/2 select mclk
863                  * as clock source
864                  */
865                 int divMCLK = cirrusfb_check_mclk(info, freq);
866                 if (divMCLK)  {
867                         nom = 0;
868                         cirrusfb_set_mclk_as_source(info, divMCLK);
869                 }
870         }
871         if (cinfo->btype == BT_LAGUNA) {
872                 long pcifc = fb_readl(cinfo->laguna_mmio + 0x3fc);
873                 unsigned char tile = fb_readb(cinfo->laguna_mmio + 0x407);
874                 unsigned short tile_control;
875
876                 tile_control = fb_readw(cinfo->laguna_mmio + 0x2c4);
877                 fb_writew(tile_control & ~0x80, cinfo->laguna_mmio + 0x2c4);
878
879                 fb_writel(pcifc | 0x10000000l, cinfo->laguna_mmio + 0x3fc);
880                 fb_writeb(tile & 0x3f, cinfo->laguna_mmio + 0x407);
881                 control = fb_readw(cinfo->laguna_mmio + 0x402);
882                 threshold = fb_readw(cinfo->laguna_mmio + 0xea);
883                 control &= ~0x6800;
884                 format = 0;
885                 threshold &= 0xffe0;
886                 threshold &= 0x3fbf;
887         }
888         if (nom) {
889                 tmp = den << 1;
890                 if (div != 0)
891                         tmp |= 1;
892                 /* 6 bit denom; ONLY 5434!!! (bugged me 10 days) */
893                 if ((cinfo->btype == BT_SD64) ||
894                     (cinfo->btype == BT_ALPINE) ||
895                     (cinfo->btype == BT_GD5480))
896                         tmp |= 0x80;
897
898                 dev_dbg(info->device, "CL_SEQR1B: %d\n", (int) tmp);
899                 /* Laguna chipset has reversed clock registers */
900                 if (cinfo->btype == BT_LAGUNA) {
901                         vga_wseq(regbase, CL_SEQRE, tmp);
902                         vga_wseq(regbase, CL_SEQR1E, nom);
903                 } else {
904                         vga_wseq(regbase, CL_SEQRB, nom);
905                         vga_wseq(regbase, CL_SEQR1B, tmp);
906                 }
907         }
908
909         if (yres >= 1024)
910                 /* 1280x1024 */
911                 vga_wcrt(regbase, VGA_CRTC_MODE, 0xc7);
912         else
913                 /* mode control: VGA_CRTC_START_HI enable, ROTATE(?), 16bit
914                  * address wrap, no compat. */
915                 vga_wcrt(regbase, VGA_CRTC_MODE, 0xc3);
916
917 /* HAEH?        vga_wcrt(regbase, VGA_CRTC_V_SYNC_END, 0x20);
918  * previously: 0x00  unlock VGA_CRTC_H_TOTAL..CRT7 */
919
920         /* don't know if it would hurt to also program this if no interlaced */
921         /* mode is used, but I feel better this way.. :-) */
922         if (var->vmode & FB_VMODE_INTERLACED)
923                 vga_wcrt(regbase, VGA_CRTC_REGS, htotal / 2);
924         else
925                 vga_wcrt(regbase, VGA_CRTC_REGS, 0x00); /* interlace control */
926
927         vga_wseq(regbase, VGA_SEQ_CHARACTER_MAP, 0);
928
929         /* adjust horizontal/vertical sync type (low/high) */
930         /* enable display memory & CRTC I/O address for color mode */
931         tmp = 0x03;
932         if (var->sync & FB_SYNC_HOR_HIGH_ACT)
933                 tmp |= 0x40;
934         if (var->sync & FB_SYNC_VERT_HIGH_ACT)
935                 tmp |= 0x80;
936         WGen(cinfo, VGA_MIS_W, tmp);
937
938         /* Screen A Preset Row-Scan register */
939         vga_wcrt(regbase, VGA_CRTC_PRESET_ROW, 0);
940         /* text cursor on and start line */
941         vga_wcrt(regbase, VGA_CRTC_CURSOR_START, 0);
942         /* text cursor end line */
943         vga_wcrt(regbase, VGA_CRTC_CURSOR_END, 31);
944
945         /******************************************************
946          *
947          * 1 bpp
948          *
949          */
950
951         /* programming for different color depths */
952         if (var->bits_per_pixel == 1) {
953                 dev_dbg(info->device, "preparing for 1 bit deep display\n");
954                 vga_wgfx(regbase, VGA_GFX_MODE, 0);     /* mode register */
955
956                 /* SR07 */
957                 switch (cinfo->btype) {
958                 case BT_SD64:
959                 case BT_PICCOLO:
960                 case BT_PICASSO:
961                 case BT_SPECTRUM:
962                 case BT_PICASSO4:
963                 case BT_ALPINE:
964                 case BT_GD5480:
965                         vga_wseq(regbase, CL_SEQR7,
966                                  regs.multiplexing ?
967                                         bi->sr07_1bpp_mux : bi->sr07_1bpp);
968                         break;
969
970                 case BT_LAGUNA:
971                         vga_wseq(regbase, CL_SEQR7,
972                                 vga_rseq(regbase, CL_SEQR7) & ~0x01);
973                         break;
974
975                 default:
976                         dev_warn(info->device, "unknown Board\n");
977                         break;
978                 }
979
980                 /* Extended Sequencer Mode */
981                 switch (cinfo->btype) {
982                 case BT_SD64:
983                         /* setting the SEQRF on SD64 is not necessary
984                          * (only during init)
985                          */
986                         /*  MCLK select */
987                         vga_wseq(regbase, CL_SEQR1F, 0x1a);
988                         break;
989
990                 case BT_PICCOLO:
991                 case BT_SPECTRUM:
992                         /* ### ueberall 0x22? */
993                         /* ##vorher 1c MCLK select */
994                         vga_wseq(regbase, CL_SEQR1F, 0x22);
995                         /* evtl d0 bei 1 bit? avoid FIFO underruns..? */
996                         vga_wseq(regbase, CL_SEQRF, 0xb0);
997                         break;
998
999                 case BT_PICASSO:
1000                         /* ##vorher 22 MCLK select */
1001                         vga_wseq(regbase, CL_SEQR1F, 0x22);
1002                         /* ## vorher d0 avoid FIFO underruns..? */
1003                         vga_wseq(regbase, CL_SEQRF, 0xd0);
1004                         break;
1005
1006                 case BT_PICASSO4:
1007                 case BT_ALPINE:
1008                 case BT_GD5480:
1009                 case BT_LAGUNA:
1010                         /* do nothing */
1011                         break;
1012
1013                 default:
1014                         dev_warn(info->device, "unknown Board\n");
1015                         break;
1016                 }
1017
1018                 /* pixel mask: pass-through for first plane */
1019                 WGen(cinfo, VGA_PEL_MSK, 0x01);
1020                 if (regs.multiplexing)
1021                         /* hidden dac reg: 1280x1024 */
1022                         WHDR(cinfo, 0x4a);
1023                 else
1024                         /* hidden dac: nothing */
1025                         WHDR(cinfo, 0);
1026                 /* memory mode: odd/even, ext. memory */
1027                 vga_wseq(regbase, VGA_SEQ_MEMORY_MODE, 0x06);
1028                 /* plane mask: only write to first plane */
1029                 vga_wseq(regbase, VGA_SEQ_PLANE_WRITE, 0x01);
1030                 offset = var->xres_virtual / 16;
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                 offset = var->xres_virtual / 8;
1117         }
1118
1119         /******************************************************
1120          *
1121          * 16 bpp
1122          *
1123          */
1124
1125         else if (var->bits_per_pixel == 16) {
1126                 dev_dbg(info->device, "preparing for 16 bit deep display\n");
1127                 switch (cinfo->btype) {
1128                 case BT_SD64:
1129                         /* Extended Sequencer Mode: 256c col. mode */
1130                         vga_wseq(regbase, CL_SEQR7, 0xf7);
1131                         /* MCLK select */
1132                         vga_wseq(regbase, CL_SEQR1F, 0x1e);
1133                         break;
1134
1135                 case BT_PICCOLO:
1136                 case BT_SPECTRUM:
1137                         vga_wseq(regbase, CL_SEQR7, 0x87);
1138                         /* Fast Page-Mode writes */
1139                         vga_wseq(regbase, CL_SEQRF, 0xb0);
1140                         /* MCLK select */
1141                         vga_wseq(regbase, CL_SEQR1F, 0x22);
1142                         break;
1143
1144                 case BT_PICASSO:
1145                         vga_wseq(regbase, CL_SEQR7, 0x27);
1146                         /* Fast Page-Mode writes */
1147                         vga_wseq(regbase, CL_SEQRF, 0xb0);
1148                         /* MCLK select */
1149                         vga_wseq(regbase, CL_SEQR1F, 0x22);
1150                         break;
1151
1152                 case BT_PICASSO4:
1153                         vga_wseq(regbase, CL_SEQR7, 0x27);
1154 /*                      vga_wseq(regbase, CL_SEQR1F, 0x1c);  */
1155                         break;
1156
1157                 case BT_ALPINE:
1158                         vga_wseq(regbase, CL_SEQR7, 0xa7);
1159                         break;
1160
1161                 case BT_GD5480:
1162                         vga_wseq(regbase, CL_SEQR7, 0x17);
1163                         /* We already set SRF and SR1F */
1164                         break;
1165
1166                 case BT_LAGUNA:
1167                         vga_wseq(regbase, CL_SEQR7,
1168                                 vga_rseq(regbase, CL_SEQR7) & ~0x01);
1169                         control |= 0x2000;
1170                         format |= 0x1400;
1171                         threshold |= 0x10;
1172                         break;
1173
1174                 default:
1175                         dev_warn(info->device, "unknown Board\n");
1176                         break;
1177                 }
1178
1179                 /* mode register: 256 color mode */
1180                 vga_wgfx(regbase, VGA_GFX_MODE, 64);
1181                 /* pixel mask: pass-through all planes */
1182                 WGen(cinfo, VGA_PEL_MSK, 0xff);
1183 #ifdef CONFIG_PCI
1184                 WHDR(cinfo, 0xc0);      /* Copy Xbh */
1185 #elif defined(CONFIG_ZORRO)
1186                 /* FIXME: CONFIG_PCI and CONFIG_ZORRO may be defined both */
1187                 WHDR(cinfo, 0xa0);      /* hidden dac reg: nothing special */
1188 #endif
1189                 /* memory mode: chain4, ext. memory */
1190                 vga_wseq(regbase, VGA_SEQ_MEMORY_MODE, 0x0a);
1191                 /* plane mask: enable writing to all 4 planes */
1192                 vga_wseq(regbase, VGA_SEQ_PLANE_WRITE, 0xff);
1193                 offset = var->xres_virtual / 4;
1194         }
1195
1196         /******************************************************
1197          *
1198          * 32 bpp
1199          *
1200          */
1201
1202         else if (var->bits_per_pixel == 32) {
1203                 dev_dbg(info->device, "preparing for 32 bit deep display\n");
1204                 switch (cinfo->btype) {
1205                 case BT_SD64:
1206                         /* Extended Sequencer Mode: 256c col. mode */
1207                         vga_wseq(regbase, CL_SEQR7, 0xf9);
1208                         /* MCLK select */
1209                         vga_wseq(regbase, CL_SEQR1F, 0x1e);
1210                         break;
1211
1212                 case BT_PICCOLO:
1213                 case BT_SPECTRUM:
1214                         vga_wseq(regbase, CL_SEQR7, 0x85);
1215                         /* Fast Page-Mode writes */
1216                         vga_wseq(regbase, CL_SEQRF, 0xb0);
1217                         /* MCLK select */
1218                         vga_wseq(regbase, CL_SEQR1F, 0x22);
1219                         break;
1220
1221                 case BT_PICASSO:
1222                         vga_wseq(regbase, CL_SEQR7, 0x25);
1223                         /* Fast Page-Mode writes */
1224                         vga_wseq(regbase, CL_SEQRF, 0xb0);
1225                         /* MCLK select */
1226                         vga_wseq(regbase, CL_SEQR1F, 0x22);
1227                         break;
1228
1229                 case BT_PICASSO4:
1230                         vga_wseq(regbase, CL_SEQR7, 0x25);
1231 /*                      vga_wseq(regbase, CL_SEQR1F, 0x1c);  */
1232                         break;
1233
1234                 case BT_ALPINE:
1235                         vga_wseq(regbase, CL_SEQR7, 0xa9);
1236                         break;
1237
1238                 case BT_GD5480:
1239                         vga_wseq(regbase, CL_SEQR7, 0x19);
1240                         /* We already set SRF and SR1F */
1241                         break;
1242
1243                 case BT_LAGUNA:
1244                         vga_wseq(regbase, CL_SEQR7,
1245                                 vga_rseq(regbase, CL_SEQR7) & ~0x01);
1246                         control |= 0x6000;
1247                         format |= 0x3400;
1248                         threshold |= 0x20;
1249                         break;
1250
1251                 default:
1252                         dev_warn(info->device, "unknown Board\n");
1253                         break;
1254                 }
1255
1256                 /* mode register: 256 color mode */
1257                 vga_wgfx(regbase, VGA_GFX_MODE, 64);
1258                 /* pixel mask: pass-through all planes */
1259                 WGen(cinfo, VGA_PEL_MSK, 0xff);
1260                 /* hidden dac reg: 8-8-8 mode (24 or 32) */
1261                 WHDR(cinfo, 0xc5);
1262                 /* memory mode: chain4, ext. memory */
1263                 vga_wseq(regbase, VGA_SEQ_MEMORY_MODE, 0x0a);
1264                 /* plane mask: enable writing to all 4 planes */
1265                 vga_wseq(regbase, VGA_SEQ_PLANE_WRITE, 0xff);
1266                 offset = var->xres_virtual / 4;
1267         }
1268
1269         /******************************************************
1270          *
1271          * unknown/unsupported bpp
1272          *
1273          */
1274
1275         else
1276                 dev_err(info->device,
1277                         "What's this? requested color depth == %d.\n",
1278                         var->bits_per_pixel);
1279
1280         vga_wcrt(regbase, VGA_CRTC_OFFSET, offset & 0xff);
1281         tmp = 0x22;
1282         if (offset & 0x100)
1283                 tmp |= 0x10;    /* offset overflow bit */
1284
1285         /* screen start addr #16-18, fastpagemode cycles */
1286         vga_wcrt(regbase, CL_CRT1B, tmp);
1287
1288         /* screen start address bit 19 */
1289         if (cirrusfb_board_info[cinfo->btype].scrn_start_bit19)
1290                 vga_wcrt(regbase, CL_CRT1D, 0x00);
1291
1292         if (cinfo->btype == BT_LAGUNA ||
1293             cinfo->btype == BT_GD5480) {
1294
1295                 tmp = 0;
1296                 if ((htotal + 5) & 256)
1297                         tmp |= 128;
1298                 if (hdispend & 256)
1299                         tmp |= 64;
1300                 if (hsyncstart & 256)
1301                         tmp |= 48;
1302                 if (vtotal & 1024)
1303                         tmp |= 8;
1304                 if (vdispend & 1024)
1305                         tmp |= 4;
1306                 if (vsyncstart & 1024)
1307                         tmp |= 3;
1308
1309                 vga_wcrt(regbase, CL_CRT1E, tmp);
1310                 dev_dbg(info->device, "CRT1e: %d\n", tmp);
1311         }
1312
1313
1314         /* text cursor location high */
1315         vga_wcrt(regbase, VGA_CRTC_CURSOR_HI, 0);
1316         /* text cursor location low */
1317         vga_wcrt(regbase, VGA_CRTC_CURSOR_LO, 0);
1318         /* underline row scanline = at very bottom */
1319         vga_wcrt(regbase, VGA_CRTC_UNDERLINE, 0);
1320
1321         /* controller mode */
1322         vga_wattr(regbase, VGA_ATC_MODE, 1);
1323         /* overscan (border) color */
1324         vga_wattr(regbase, VGA_ATC_OVERSCAN, 0);
1325         /* color plane enable */
1326         vga_wattr(regbase, VGA_ATC_PLANE_ENABLE, 15);
1327         /* pixel panning */
1328         vga_wattr(regbase, CL_AR33, 0);
1329         /* color select */
1330         vga_wattr(regbase, VGA_ATC_COLOR_PAGE, 0);
1331
1332         /* [ EGS: SetOffset(); ] */
1333         /* From SetOffset(): Turn on VideoEnable bit in Attribute controller */
1334         AttrOn(cinfo);
1335
1336         /* set/reset register */
1337         vga_wgfx(regbase, VGA_GFX_SR_VALUE, 0);
1338         /* set/reset enable */
1339         vga_wgfx(regbase, VGA_GFX_SR_ENABLE, 0);
1340         /* color compare */
1341         vga_wgfx(regbase, VGA_GFX_COMPARE_VALUE, 0);
1342         /* data rotate */
1343         vga_wgfx(regbase, VGA_GFX_DATA_ROTATE, 0);
1344         /* read map select */
1345         vga_wgfx(regbase, VGA_GFX_PLANE_READ, 0);
1346         /* miscellaneous register */
1347         vga_wgfx(regbase, VGA_GFX_MISC, 1);
1348         /* color don't care */
1349         vga_wgfx(regbase, VGA_GFX_COMPARE_MASK, 15);
1350         /* bit mask */
1351         vga_wgfx(regbase, VGA_GFX_BIT_MASK, 255);
1352
1353         /* graphics cursor attributes: nothing special */
1354         vga_wseq(regbase, CL_SEQR12, 0x0);
1355
1356         if (cinfo->btype == BT_LAGUNA) {
1357                 /* no tiles */
1358                 fb_writew(control | 0x1000, cinfo->laguna_mmio + 0x402);
1359                 fb_writew(format, cinfo->laguna_mmio + 0xc0);
1360                 fb_writew(threshold, cinfo->laguna_mmio + 0xea);
1361         }
1362         /* finally, turn on everything - turn off "FullBandwidth" bit */
1363         /* also, set "DotClock%2" bit where requested */
1364         tmp = 0x01;
1365
1366 /*** FB_VMODE_CLOCK_HALVE in linux/fb.h not defined anymore ?
1367     if (var->vmode & FB_VMODE_CLOCK_HALVE)
1368         tmp |= 0x08;
1369 */
1370
1371         vga_wseq(regbase, VGA_SEQ_CLOCK_MODE, tmp);
1372         dev_dbg(info->device, "CL_SEQR1: %d\n", tmp);
1373
1374         cinfo->currentmode = regs;
1375
1376         /* pan to requested offset */
1377         cirrusfb_pan_display(var, info);
1378
1379 #ifdef CIRRUSFB_DEBUG
1380         cirrusfb_dbg_reg_dump(info, NULL);
1381 #endif
1382
1383         return 0;
1384 }
1385
1386 /* for some reason incomprehensible to me, cirrusfb requires that you write
1387  * the registers twice for the settings to take..grr. -dte */
1388 static int cirrusfb_set_par(struct fb_info *info)
1389 {
1390         cirrusfb_set_par_foo(info);
1391         return cirrusfb_set_par_foo(info);
1392 }
1393
1394 static int cirrusfb_setcolreg(unsigned regno, unsigned red, unsigned green,
1395                               unsigned blue, unsigned transp,
1396                               struct fb_info *info)
1397 {
1398         struct cirrusfb_info *cinfo = info->par;
1399
1400         if (regno > 255)
1401                 return -EINVAL;
1402
1403         if (info->fix.visual == FB_VISUAL_TRUECOLOR) {
1404                 u32 v;
1405                 red >>= (16 - info->var.red.length);
1406                 green >>= (16 - info->var.green.length);
1407                 blue >>= (16 - info->var.blue.length);
1408
1409                 if (regno >= 16)
1410                         return 1;
1411                 v = (red << info->var.red.offset) |
1412                     (green << info->var.green.offset) |
1413                     (blue << info->var.blue.offset);
1414
1415                 cinfo->pseudo_palette[regno] = v;
1416                 return 0;
1417         }
1418
1419         if (info->var.bits_per_pixel == 8)
1420                 WClut(cinfo, regno, red >> 10, green >> 10, blue >> 10);
1421
1422         return 0;
1423
1424 }
1425
1426 /*************************************************************************
1427         cirrusfb_pan_display()
1428
1429         performs display panning - provided hardware permits this
1430 **************************************************************************/
1431 static int cirrusfb_pan_display(struct fb_var_screeninfo *var,
1432                                 struct fb_info *info)
1433 {
1434         int xoffset = 0;
1435         int yoffset = 0;
1436         unsigned long base;
1437         unsigned char tmp, xpix;
1438         struct cirrusfb_info *cinfo = info->par;
1439
1440         dev_dbg(info->device,
1441                 "virtual offset: (%d,%d)\n", var->xoffset, var->yoffset);
1442
1443         /* no range checks for xoffset and yoffset,   */
1444         /* as fb_pan_display has already done this */
1445         if (var->vmode & FB_VMODE_YWRAP)
1446                 return -EINVAL;
1447
1448         info->var.xoffset = var->xoffset;
1449         info->var.yoffset = var->yoffset;
1450
1451         xoffset = var->xoffset * info->var.bits_per_pixel / 8;
1452         yoffset = var->yoffset;
1453
1454         base = yoffset * info->fix.line_length + xoffset;
1455
1456         if (info->var.bits_per_pixel == 1) {
1457                 /* base is already correct */
1458                 xpix = (unsigned char) (var->xoffset % 8);
1459         } else {
1460                 base /= 4;
1461                 xpix = (unsigned char) ((xoffset % 4) * 2);
1462         }
1463
1464         cirrusfb_WaitBLT(cinfo->regbase); /* make sure all the BLT's are done */
1465
1466         /* lower 8 + 8 bits of screen start address */
1467         vga_wcrt(cinfo->regbase, VGA_CRTC_START_LO,
1468                  (unsigned char) (base & 0xff));
1469         vga_wcrt(cinfo->regbase, VGA_CRTC_START_HI,
1470                  (unsigned char) (base >> 8));
1471
1472         /* 0xf2 is %11110010, exclude tmp bits */
1473         tmp = vga_rcrt(cinfo->regbase, CL_CRT1B) & 0xf2;
1474         /* construct bits 16, 17 and 18 of screen start address */
1475         if (base & 0x10000)
1476                 tmp |= 0x01;
1477         if (base & 0x20000)
1478                 tmp |= 0x04;
1479         if (base & 0x40000)
1480                 tmp |= 0x08;
1481
1482         vga_wcrt(cinfo->regbase, CL_CRT1B, tmp);
1483
1484         /* construct bit 19 of screen start address */
1485         if (cirrusfb_board_info[cinfo->btype].scrn_start_bit19)
1486                 vga_wcrt(cinfo->regbase, CL_CRT1D, (base >> 12) & 0x80);
1487
1488         /* write pixel panning value to AR33; this does not quite work in 8bpp
1489          *
1490          * ### Piccolo..? Will this work?
1491          */
1492         if (info->var.bits_per_pixel == 1)
1493                 vga_wattr(cinfo->regbase, CL_AR33, xpix);
1494
1495         cirrusfb_WaitBLT(cinfo->regbase);
1496
1497         return 0;
1498 }
1499
1500 static int cirrusfb_blank(int blank_mode, struct fb_info *info)
1501 {
1502         /*
1503          * Blank the screen if blank_mode != 0, else unblank. If blank == NULL
1504          * then the caller blanks by setting the CLUT (Color Look Up Table)
1505          * to all black. Return 0 if blanking succeeded, != 0 if un-/blanking
1506          * failed due to e.g. a video mode which doesn't support it.
1507          * Implements VESA suspend and powerdown modes on hardware that
1508          * supports disabling hsync/vsync:
1509          *   blank_mode == 2: suspend vsync
1510          *   blank_mode == 3: suspend hsync
1511          *   blank_mode == 4: powerdown
1512          */
1513         unsigned char val;
1514         struct cirrusfb_info *cinfo = info->par;
1515         int current_mode = cinfo->blank_mode;
1516
1517         dev_dbg(info->device, "ENTER, blank mode = %d\n", blank_mode);
1518
1519         if (info->state != FBINFO_STATE_RUNNING ||
1520             current_mode == blank_mode) {
1521                 dev_dbg(info->device, "EXIT, returning 0\n");
1522                 return 0;
1523         }
1524
1525         /* Undo current */
1526         if (current_mode == FB_BLANK_NORMAL ||
1527             current_mode == FB_BLANK_UNBLANK)
1528                 /* clear "FullBandwidth" bit */
1529                 val = 0;
1530         else
1531                 /* set "FullBandwidth" bit */
1532                 val = 0x20;
1533
1534         val |= vga_rseq(cinfo->regbase, VGA_SEQ_CLOCK_MODE) & 0xdf;
1535         vga_wseq(cinfo->regbase, VGA_SEQ_CLOCK_MODE, val);
1536
1537         switch (blank_mode) {
1538         case FB_BLANK_UNBLANK:
1539         case FB_BLANK_NORMAL:
1540                 val = 0x00;
1541                 break;
1542         case FB_BLANK_VSYNC_SUSPEND:
1543                 val = 0x04;
1544                 break;
1545         case FB_BLANK_HSYNC_SUSPEND:
1546                 val = 0x02;
1547                 break;
1548         case FB_BLANK_POWERDOWN:
1549                 val = 0x06;
1550                 break;
1551         default:
1552                 dev_dbg(info->device, "EXIT, returning 1\n");
1553                 return 1;
1554         }
1555
1556         vga_wgfx(cinfo->regbase, CL_GRE, val);
1557
1558         cinfo->blank_mode = blank_mode;
1559         dev_dbg(info->device, "EXIT, returning 0\n");
1560
1561         /* Let fbcon do a soft blank for us */
1562         return (blank_mode == FB_BLANK_NORMAL) ? 1 : 0;
1563 }
1564
1565 /**** END   Hardware specific Routines **************************************/
1566 /****************************************************************************/
1567 /**** BEGIN Internal Routines ***********************************************/
1568
1569 static void init_vgachip(struct fb_info *info)
1570 {
1571         struct cirrusfb_info *cinfo = info->par;
1572         const struct cirrusfb_board_info_rec *bi;
1573
1574         assert(cinfo != NULL);
1575
1576         bi = &cirrusfb_board_info[cinfo->btype];
1577
1578         /* reset board globally */
1579         switch (cinfo->btype) {
1580         case BT_PICCOLO:
1581                 WSFR(cinfo, 0x01);
1582                 udelay(500);
1583                 WSFR(cinfo, 0x51);
1584                 udelay(500);
1585                 break;
1586         case BT_PICASSO:
1587                 WSFR2(cinfo, 0xff);
1588                 udelay(500);
1589                 break;
1590         case BT_SD64:
1591         case BT_SPECTRUM:
1592                 WSFR(cinfo, 0x1f);
1593                 udelay(500);
1594                 WSFR(cinfo, 0x4f);
1595                 udelay(500);
1596                 break;
1597         case BT_PICASSO4:
1598                 /* disable flickerfixer */
1599                 vga_wcrt(cinfo->regbase, CL_CRT51, 0x00);
1600                 mdelay(100);
1601                 /* from Klaus' NetBSD driver: */
1602                 vga_wgfx(cinfo->regbase, CL_GR2F, 0x00);
1603                 /* put blitter into 542x compat */
1604                 vga_wgfx(cinfo->regbase, CL_GR33, 0x00);
1605                 /* mode */
1606                 vga_wgfx(cinfo->regbase, CL_GR31, 0x00);
1607                 break;
1608
1609         case BT_GD5480:
1610                 /* from Klaus' NetBSD driver: */
1611                 vga_wgfx(cinfo->regbase, CL_GR2F, 0x00);
1612                 break;
1613
1614         case BT_ALPINE:
1615                 /* Nothing to do to reset the board. */
1616                 break;
1617
1618         default:
1619                 dev_err(info->device, "Warning: Unknown board type\n");
1620                 break;
1621         }
1622
1623         /* make sure RAM size set by this point */
1624         assert(info->screen_size > 0);
1625
1626         /* the P4 is not fully initialized here; I rely on it having been */
1627         /* inited under AmigaOS already, which seems to work just fine    */
1628         /* (Klaus advised to do it this way)                          */
1629
1630         if (cinfo->btype != BT_PICASSO4) {
1631                 WGen(cinfo, CL_VSSM, 0x10);     /* EGS: 0x16 */
1632                 WGen(cinfo, CL_POS102, 0x01);
1633                 WGen(cinfo, CL_VSSM, 0x08);     /* EGS: 0x0e */
1634
1635                 if (cinfo->btype != BT_SD64)
1636                         WGen(cinfo, CL_VSSM2, 0x01);
1637
1638                 /* reset sequencer logic */
1639                 vga_wseq(cinfo->regbase, CL_SEQR0, 0x03);
1640
1641                 /* FullBandwidth (video off) and 8/9 dot clock */
1642                 vga_wseq(cinfo->regbase, VGA_SEQ_CLOCK_MODE, 0x21);
1643                 /* polarity (-/-), disable access to display memory,
1644                  * VGA_CRTC_START_HI base address: color
1645                  */
1646                 WGen(cinfo, VGA_MIS_W, 0xc1);
1647
1648                 /* "magic cookie" - doesn't make any sense to me.. */
1649 /*      vga_wgfx(cinfo->regbase, CL_GRA, 0xce);   */
1650                 /* unlock all extension registers */
1651                 vga_wseq(cinfo->regbase, CL_SEQR6, 0x12);
1652
1653                 /* reset blitter */
1654                 vga_wgfx(cinfo->regbase, CL_GR31, 0x04);
1655
1656                 switch (cinfo->btype) {
1657                 case BT_GD5480:
1658                         vga_wseq(cinfo->regbase, CL_SEQRF, 0x98);
1659                         break;
1660                 case BT_ALPINE:
1661                         break;
1662                 case BT_SD64:
1663                         vga_wseq(cinfo->regbase, CL_SEQRF, 0xb8);
1664                         break;
1665                 default:
1666                         vga_wseq(cinfo->regbase, CL_SEQR16, 0x0f);
1667                         vga_wseq(cinfo->regbase, CL_SEQRF, 0xb0);
1668                         break;
1669                 }
1670         }
1671         /* plane mask: nothing */
1672         vga_wseq(cinfo->regbase, VGA_SEQ_PLANE_WRITE, 0xff);
1673         /* character map select: doesn't even matter in gx mode */
1674         vga_wseq(cinfo->regbase, VGA_SEQ_CHARACTER_MAP, 0x00);
1675         /* memory mode: chain-4, no odd/even, ext. memory */
1676         vga_wseq(cinfo->regbase, VGA_SEQ_MEMORY_MODE, 0x0e);
1677
1678         /* controller-internal base address of video memory */
1679         if (bi->init_sr07)
1680                 vga_wseq(cinfo->regbase, CL_SEQR7, bi->sr07);
1681
1682         /*  vga_wseq(cinfo->regbase, CL_SEQR8, 0x00); */
1683         /* EEPROM control: shouldn't be necessary to write to this at all.. */
1684
1685         /* graphics cursor X position (incomplete; position gives rem. 3 bits */
1686         vga_wseq(cinfo->regbase, CL_SEQR10, 0x00);
1687         /* graphics cursor Y position (..."... ) */
1688         vga_wseq(cinfo->regbase, CL_SEQR11, 0x00);
1689         /* graphics cursor attributes */
1690         vga_wseq(cinfo->regbase, CL_SEQR12, 0x00);
1691         /* graphics cursor pattern address */
1692         vga_wseq(cinfo->regbase, CL_SEQR13, 0x00);
1693
1694         /* writing these on a P4 might give problems..  */
1695         if (cinfo->btype != BT_PICASSO4) {
1696                 /* configuration readback and ext. color */
1697                 vga_wseq(cinfo->regbase, CL_SEQR17, 0x00);
1698                 /* signature generator */
1699                 vga_wseq(cinfo->regbase, CL_SEQR18, 0x02);
1700         }
1701
1702         /* MCLK select etc. */
1703         if (bi->init_sr1f)
1704                 vga_wseq(cinfo->regbase, CL_SEQR1F, bi->sr1f);
1705
1706         /* Screen A preset row scan: none */
1707         vga_wcrt(cinfo->regbase, VGA_CRTC_PRESET_ROW, 0x00);
1708         /* Text cursor start: disable text cursor */
1709         vga_wcrt(cinfo->regbase, VGA_CRTC_CURSOR_START, 0x20);
1710         /* Text cursor end: - */
1711         vga_wcrt(cinfo->regbase, VGA_CRTC_CURSOR_END, 0x00);
1712         /* Screen start address high: 0 */
1713         vga_wcrt(cinfo->regbase, VGA_CRTC_START_HI, 0x00);
1714         /* Screen start address low: 0 */
1715         vga_wcrt(cinfo->regbase, VGA_CRTC_START_LO, 0x00);
1716         /* text cursor location high: 0 */
1717         vga_wcrt(cinfo->regbase, VGA_CRTC_CURSOR_HI, 0x00);
1718         /* text cursor location low: 0 */
1719         vga_wcrt(cinfo->regbase, VGA_CRTC_CURSOR_LO, 0x00);
1720
1721         /* Underline Row scanline: - */
1722         vga_wcrt(cinfo->regbase, VGA_CRTC_UNDERLINE, 0x00);
1723         /* mode control: timing enable, byte mode, no compat modes */
1724         vga_wcrt(cinfo->regbase, VGA_CRTC_MODE, 0xc3);
1725         /* Line Compare: not needed */
1726         vga_wcrt(cinfo->regbase, VGA_CRTC_LINE_COMPARE, 0x00);
1727         /* ### add 0x40 for text modes with > 30 MHz pixclock */
1728         /* ext. display controls: ext.adr. wrap */
1729         vga_wcrt(cinfo->regbase, CL_CRT1B, 0x02);
1730
1731         /* Set/Reset registes: - */
1732         vga_wgfx(cinfo->regbase, VGA_GFX_SR_VALUE, 0x00);
1733         /* Set/Reset enable: - */
1734         vga_wgfx(cinfo->regbase, VGA_GFX_SR_ENABLE, 0x00);
1735         /* Color Compare: - */
1736         vga_wgfx(cinfo->regbase, VGA_GFX_COMPARE_VALUE, 0x00);
1737         /* Data Rotate: - */
1738         vga_wgfx(cinfo->regbase, VGA_GFX_DATA_ROTATE, 0x00);
1739         /* Read Map Select: - */
1740         vga_wgfx(cinfo->regbase, VGA_GFX_PLANE_READ, 0x00);
1741         /* Mode: conf. for 16/4/2 color mode, no odd/even, read/write mode 0 */
1742         vga_wgfx(cinfo->regbase, VGA_GFX_MODE, 0x00);
1743         /* Miscellaneous: memory map base address, graphics mode */
1744         vga_wgfx(cinfo->regbase, VGA_GFX_MISC, 0x01);
1745         /* Color Don't care: involve all planes */
1746         vga_wgfx(cinfo->regbase, VGA_GFX_COMPARE_MASK, 0x0f);
1747         /* Bit Mask: no mask at all */
1748         vga_wgfx(cinfo->regbase, VGA_GFX_BIT_MASK, 0xff);
1749         if (cinfo->btype == BT_ALPINE)
1750                 /* (5434 can't have bit 3 set for bitblt) */
1751                 vga_wgfx(cinfo->regbase, CL_GRB, 0x20);
1752         else
1753         /* Graphics controller mode extensions: finer granularity,
1754          * 8byte data latches
1755          */
1756                 vga_wgfx(cinfo->regbase, CL_GRB, 0x28);
1757
1758         vga_wgfx(cinfo->regbase, CL_GRC, 0xff); /* Color Key compare: - */
1759         vga_wgfx(cinfo->regbase, CL_GRD, 0x00); /* Color Key compare mask: - */
1760         vga_wgfx(cinfo->regbase, CL_GRE, 0x00); /* Miscellaneous control: - */
1761         /* Background color byte 1: - */
1762         /*  vga_wgfx (cinfo->regbase, CL_GR10, 0x00); */
1763         /*  vga_wgfx (cinfo->regbase, CL_GR11, 0x00); */
1764
1765         /* Attribute Controller palette registers: "identity mapping" */
1766         vga_wattr(cinfo->regbase, VGA_ATC_PALETTE0, 0x00);
1767         vga_wattr(cinfo->regbase, VGA_ATC_PALETTE1, 0x01);
1768         vga_wattr(cinfo->regbase, VGA_ATC_PALETTE2, 0x02);
1769         vga_wattr(cinfo->regbase, VGA_ATC_PALETTE3, 0x03);
1770         vga_wattr(cinfo->regbase, VGA_ATC_PALETTE4, 0x04);
1771         vga_wattr(cinfo->regbase, VGA_ATC_PALETTE5, 0x05);
1772         vga_wattr(cinfo->regbase, VGA_ATC_PALETTE6, 0x06);
1773         vga_wattr(cinfo->regbase, VGA_ATC_PALETTE7, 0x07);
1774         vga_wattr(cinfo->regbase, VGA_ATC_PALETTE8, 0x08);
1775         vga_wattr(cinfo->regbase, VGA_ATC_PALETTE9, 0x09);
1776         vga_wattr(cinfo->regbase, VGA_ATC_PALETTEA, 0x0a);
1777         vga_wattr(cinfo->regbase, VGA_ATC_PALETTEB, 0x0b);
1778         vga_wattr(cinfo->regbase, VGA_ATC_PALETTEC, 0x0c);
1779         vga_wattr(cinfo->regbase, VGA_ATC_PALETTED, 0x0d);
1780         vga_wattr(cinfo->regbase, VGA_ATC_PALETTEE, 0x0e);
1781         vga_wattr(cinfo->regbase, VGA_ATC_PALETTEF, 0x0f);
1782
1783         /* Attribute Controller mode: graphics mode */
1784         vga_wattr(cinfo->regbase, VGA_ATC_MODE, 0x01);
1785         /* Overscan color reg.: reg. 0 */
1786         vga_wattr(cinfo->regbase, VGA_ATC_OVERSCAN, 0x00);
1787         /* Color Plane enable: Enable all 4 planes */
1788         vga_wattr(cinfo->regbase, VGA_ATC_PLANE_ENABLE, 0x0f);
1789 /* ###  vga_wattr(cinfo->regbase, CL_AR33, 0x00); * Pixel Panning: - */
1790         /* Color Select: - */
1791         vga_wattr(cinfo->regbase, VGA_ATC_COLOR_PAGE, 0x00);
1792
1793         WGen(cinfo, VGA_PEL_MSK, 0xff); /* Pixel mask: no mask */
1794
1795         if (cinfo->btype != BT_ALPINE && cinfo->btype != BT_GD5480)
1796         /* polarity (-/-), enable display mem,
1797          * VGA_CRTC_START_HI i/o base = color
1798          */
1799                 WGen(cinfo, VGA_MIS_W, 0xc3);
1800
1801         /* BLT Start/status: Blitter reset */
1802         vga_wgfx(cinfo->regbase, CL_GR31, 0x04);
1803         /* - " -           : "end-of-reset" */
1804         vga_wgfx(cinfo->regbase, CL_GR31, 0x00);
1805
1806         /* misc... */
1807         WHDR(cinfo, 0); /* Hidden DAC register: - */
1808         return;
1809 }
1810
1811 static void switch_monitor(struct cirrusfb_info *cinfo, int on)
1812 {
1813 #ifdef CONFIG_ZORRO /* only works on Zorro boards */
1814         static int IsOn = 0;    /* XXX not ok for multiple boards */
1815
1816         if (cinfo->btype == BT_PICASSO4)
1817                 return;         /* nothing to switch */
1818         if (cinfo->btype == BT_ALPINE)
1819                 return;         /* nothing to switch */
1820         if (cinfo->btype == BT_GD5480)
1821                 return;         /* nothing to switch */
1822         if (cinfo->btype == BT_PICASSO) {
1823                 if ((on && !IsOn) || (!on && IsOn))
1824                         WSFR(cinfo, 0xff);
1825                 return;
1826         }
1827         if (on) {
1828                 switch (cinfo->btype) {
1829                 case BT_SD64:
1830                         WSFR(cinfo, cinfo->SFR | 0x21);
1831                         break;
1832                 case BT_PICCOLO:
1833                         WSFR(cinfo, cinfo->SFR | 0x28);
1834                         break;
1835                 case BT_SPECTRUM:
1836                         WSFR(cinfo, 0x6f);
1837                         break;
1838                 default: /* do nothing */ break;
1839                 }
1840         } else {
1841                 switch (cinfo->btype) {
1842                 case BT_SD64:
1843                         WSFR(cinfo, cinfo->SFR & 0xde);
1844                         break;
1845                 case BT_PICCOLO:
1846                         WSFR(cinfo, cinfo->SFR & 0xd7);
1847                         break;
1848                 case BT_SPECTRUM:
1849                         WSFR(cinfo, 0x4f);
1850                         break;
1851                 default: /* do nothing */
1852                         break;
1853                 }
1854         }
1855 #endif /* CONFIG_ZORRO */
1856 }
1857
1858 /******************************************/
1859 /* Linux 2.6-style  accelerated functions */
1860 /******************************************/
1861
1862 static void cirrusfb_fillrect(struct fb_info *info,
1863                               const struct fb_fillrect *region)
1864 {
1865         struct fb_fillrect modded;
1866         int vxres, vyres;
1867         struct cirrusfb_info *cinfo = info->par;
1868         int m = info->var.bits_per_pixel;
1869         u32 color = (info->fix.visual == FB_VISUAL_TRUECOLOR) ?
1870                 cinfo->pseudo_palette[region->color] : region->color;
1871
1872         if (info->state != FBINFO_STATE_RUNNING)
1873                 return;
1874         if (info->flags & FBINFO_HWACCEL_DISABLED) {
1875                 cfb_fillrect(info, region);
1876                 return;
1877         }
1878
1879         vxres = info->var.xres_virtual;
1880         vyres = info->var.yres_virtual;
1881
1882         memcpy(&modded, region, sizeof(struct fb_fillrect));
1883
1884         if (!modded.width || !modded.height ||
1885            modded.dx >= vxres || modded.dy >= vyres)
1886                 return;
1887
1888         if (modded.dx + modded.width  > vxres)
1889                 modded.width  = vxres - modded.dx;
1890         if (modded.dy + modded.height > vyres)
1891                 modded.height = vyres - modded.dy;
1892
1893         cirrusfb_RectFill(cinfo->regbase,
1894                           info->var.bits_per_pixel,
1895                           (region->dx * m) / 8, region->dy,
1896                           (region->width * m) / 8, region->height,
1897                           color,
1898                           info->fix.line_length);
1899 }
1900
1901 static void cirrusfb_copyarea(struct fb_info *info,
1902                               const struct fb_copyarea *area)
1903 {
1904         struct fb_copyarea modded;
1905         u32 vxres, vyres;
1906         struct cirrusfb_info *cinfo = info->par;
1907         int m = info->var.bits_per_pixel;
1908
1909         if (info->state != FBINFO_STATE_RUNNING)
1910                 return;
1911         if (info->flags & FBINFO_HWACCEL_DISABLED) {
1912                 cfb_copyarea(info, area);
1913                 return;
1914         }
1915
1916         vxres = info->var.xres_virtual;
1917         vyres = info->var.yres_virtual;
1918         memcpy(&modded, area, sizeof(struct fb_copyarea));
1919
1920         if (!modded.width || !modded.height ||
1921            modded.sx >= vxres || modded.sy >= vyres ||
1922            modded.dx >= vxres || modded.dy >= vyres)
1923                 return;
1924
1925         if (modded.sx + modded.width > vxres)
1926                 modded.width = vxres - modded.sx;
1927         if (modded.dx + modded.width > vxres)
1928                 modded.width = vxres - modded.dx;
1929         if (modded.sy + modded.height > vyres)
1930                 modded.height = vyres - modded.sy;
1931         if (modded.dy + modded.height > vyres)
1932                 modded.height = vyres - modded.dy;
1933
1934         cirrusfb_BitBLT(cinfo->regbase, info->var.bits_per_pixel,
1935                         (area->sx * m) / 8, area->sy,
1936                         (area->dx * m) / 8, area->dy,
1937                         (area->width * m) / 8, area->height,
1938                         info->fix.line_length);
1939
1940 }
1941
1942 static void cirrusfb_imageblit(struct fb_info *info,
1943                                const struct fb_image *image)
1944 {
1945         struct cirrusfb_info *cinfo = info->par;
1946
1947         cirrusfb_WaitBLT(cinfo->regbase);
1948         cfb_imageblit(info, image);
1949 }
1950
1951 #ifdef CONFIG_PPC_PREP
1952 #define PREP_VIDEO_BASE ((volatile unsigned long) 0xC0000000)
1953 #define PREP_IO_BASE    ((volatile unsigned char *) 0x80000000)
1954 static void get_prep_addrs(unsigned long *display, unsigned long *registers)
1955 {
1956         *display = PREP_VIDEO_BASE;
1957         *registers = (unsigned long) PREP_IO_BASE;
1958 }
1959
1960 #endif                          /* CONFIG_PPC_PREP */
1961
1962 #ifdef CONFIG_PCI
1963 static int release_io_ports;
1964
1965 /* Pulled the logic from XFree86 Cirrus driver to get the memory size,
1966  * based on the DRAM bandwidth bit and DRAM bank switching bit.  This
1967  * works with 1MB, 2MB and 4MB configurations (which the Motorola boards
1968  * seem to have. */
1969 static unsigned int __devinit cirrusfb_get_memsize(struct fb_info *info,
1970                                                    u8 __iomem *regbase)
1971 {
1972         unsigned long mem;
1973         struct cirrusfb_info *cinfo = info->par;
1974
1975         if (cinfo->btype == BT_LAGUNA) {
1976                 unsigned char SR14 = vga_rseq(regbase, CL_SEQR14);
1977
1978                 mem = ((SR14 & 7) + 1) << 20;
1979         } else {
1980                 unsigned char SRF = vga_rseq(regbase, CL_SEQRF);
1981                 switch ((SRF & 0x18)) {
1982                 case 0x08:
1983                         mem = 512 * 1024;
1984                         break;
1985                 case 0x10:
1986                         mem = 1024 * 1024;
1987                         break;
1988                 /* 64-bit DRAM data bus width; assume 2MB.
1989                  * Also indicates 2MB memory on the 5430.
1990                  */
1991                 case 0x18:
1992                         mem = 2048 * 1024;
1993                         break;
1994                 default:
1995                         dev_warn(info->device, "Unknown memory size!\n");
1996                         mem = 1024 * 1024;
1997                 }
1998                 /* If DRAM bank switching is enabled, there must be
1999                  * twice as much memory installed. (4MB on the 5434)
2000                  */
2001                 if (SRF & 0x80)
2002                         mem *= 2;
2003         }
2004
2005         /* TODO: Handling of GD5446/5480 (see XF86 sources ...) */
2006         return mem;
2007 }
2008
2009 static void get_pci_addrs(const struct pci_dev *pdev,
2010                           unsigned long *display, unsigned long *registers)
2011 {
2012         assert(pdev != NULL);
2013         assert(display != NULL);
2014         assert(registers != NULL);
2015
2016         *display = 0;
2017         *registers = 0;
2018
2019         /* This is a best-guess for now */
2020
2021         if (pci_resource_flags(pdev, 0) & IORESOURCE_IO) {
2022                 *display = pci_resource_start(pdev, 1);
2023                 *registers = pci_resource_start(pdev, 0);
2024         } else {
2025                 *display = pci_resource_start(pdev, 0);
2026                 *registers = pci_resource_start(pdev, 1);
2027         }
2028
2029         assert(*display != 0);
2030 }
2031
2032 static void cirrusfb_pci_unmap(struct fb_info *info)
2033 {
2034         struct pci_dev *pdev = to_pci_dev(info->device);
2035         struct cirrusfb_info *cinfo = info->par;
2036
2037         if (cinfo->laguna_mmio == NULL)
2038                 iounmap(cinfo->laguna_mmio);
2039         iounmap(info->screen_base);
2040 #if 0 /* if system didn't claim this region, we would... */
2041         release_mem_region(0xA0000, 65535);
2042 #endif
2043         if (release_io_ports)
2044                 release_region(0x3C0, 32);
2045         pci_release_regions(pdev);
2046 }
2047 #endif /* CONFIG_PCI */
2048
2049 #ifdef CONFIG_ZORRO
2050 static void cirrusfb_zorro_unmap(struct fb_info *info)
2051 {
2052         struct cirrusfb_info *cinfo = info->par;
2053         struct zorro_dev *zdev = to_zorro_dev(info->device);
2054
2055         zorro_release_device(zdev);
2056
2057         if (cinfo->btype == BT_PICASSO4) {
2058                 cinfo->regbase -= 0x600000;
2059                 iounmap((void *)cinfo->regbase);
2060                 iounmap(info->screen_base);
2061         } else {
2062                 if (zorro_resource_start(zdev) > 0x01000000)
2063                         iounmap(info->screen_base);
2064         }
2065 }
2066 #endif /* CONFIG_ZORRO */
2067
2068 static int __devinit cirrusfb_set_fbinfo(struct fb_info *info)
2069 {
2070         struct cirrusfb_info *cinfo = info->par;
2071         struct fb_var_screeninfo *var = &info->var;
2072
2073         info->pseudo_palette = cinfo->pseudo_palette;
2074         info->flags = FBINFO_DEFAULT
2075                     | FBINFO_HWACCEL_XPAN
2076                     | FBINFO_HWACCEL_YPAN
2077                     | FBINFO_HWACCEL_FILLRECT
2078                     | FBINFO_HWACCEL_COPYAREA;
2079         if (noaccel)
2080                 info->flags |= FBINFO_HWACCEL_DISABLED;
2081         info->fbops = &cirrusfb_ops;
2082         if (cinfo->btype == BT_GD5480) {
2083                 if (var->bits_per_pixel == 16)
2084                         info->screen_base += 1 * MB_;
2085                 if (var->bits_per_pixel == 32)
2086                         info->screen_base += 2 * MB_;
2087         }
2088
2089         /* Fill fix common fields */
2090         strlcpy(info->fix.id, cirrusfb_board_info[cinfo->btype].name,
2091                 sizeof(info->fix.id));
2092
2093         /* monochrome: only 1 memory plane */
2094         /* 8 bit and above: Use whole memory area */
2095         info->fix.smem_len   = info->screen_size;
2096         if (var->bits_per_pixel == 1)
2097                 info->fix.smem_len /= 4;
2098         info->fix.type_aux   = 0;
2099         info->fix.xpanstep   = 1;
2100         info->fix.ypanstep   = 1;
2101         info->fix.ywrapstep  = 0;
2102
2103         /* FIXME: map region at 0xB8000 if available, fill in here */
2104         info->fix.mmio_len   = 0;
2105         info->fix.accel = FB_ACCEL_NONE;
2106
2107         fb_alloc_cmap(&info->cmap, 256, 0);
2108
2109         return 0;
2110 }
2111
2112 static int __devinit cirrusfb_register(struct fb_info *info)
2113 {
2114         struct cirrusfb_info *cinfo = info->par;
2115         int err;
2116         enum cirrus_board btype;
2117
2118         btype = cinfo->btype;
2119
2120         /* sanity checks */
2121         assert(btype != BT_NONE);
2122
2123         /* set all the vital stuff */
2124         cirrusfb_set_fbinfo(info);
2125
2126         dev_dbg(info->device, "(RAM start set to: 0x%p)\n", info->screen_base);
2127
2128         err = fb_find_mode(&info->var, info, mode_option, NULL, 0, NULL, 8);
2129         if (!err) {
2130                 dev_dbg(info->device, "wrong initial video mode\n");
2131                 err = -EINVAL;
2132                 goto err_dealloc_cmap;
2133         }
2134
2135         info->var.activate = FB_ACTIVATE_NOW;
2136
2137         err = cirrusfb_decode_var(&info->var, &cinfo->currentmode, info);
2138         if (err < 0) {
2139                 /* should never happen */
2140                 dev_dbg(info->device,
2141                         "choking on default var... umm, no good.\n");
2142                 goto err_dealloc_cmap;
2143         }
2144
2145         err = register_framebuffer(info);
2146         if (err < 0) {
2147                 dev_err(info->device,
2148                         "could not register fb device; err = %d!\n", err);
2149                 goto err_dealloc_cmap;
2150         }
2151
2152         return 0;
2153
2154 err_dealloc_cmap:
2155         fb_dealloc_cmap(&info->cmap);
2156         cinfo->unmap(info);
2157         framebuffer_release(info);
2158         return err;
2159 }
2160
2161 static void __devexit cirrusfb_cleanup(struct fb_info *info)
2162 {
2163         struct cirrusfb_info *cinfo = info->par;
2164
2165         switch_monitor(cinfo, 0);
2166         unregister_framebuffer(info);
2167         fb_dealloc_cmap(&info->cmap);
2168         dev_dbg(info->device, "Framebuffer unregistered\n");
2169         cinfo->unmap(info);
2170         framebuffer_release(info);
2171 }
2172
2173 #ifdef CONFIG_PCI
2174 static int __devinit cirrusfb_pci_register(struct pci_dev *pdev,
2175                                            const struct pci_device_id *ent)
2176 {
2177         struct cirrusfb_info *cinfo;
2178         struct fb_info *info;
2179         enum cirrus_board btype;
2180         unsigned long board_addr, board_size;
2181         int ret;
2182
2183         ret = pci_enable_device(pdev);
2184         if (ret < 0) {
2185                 printk(KERN_ERR "cirrusfb: Cannot enable PCI device\n");
2186                 goto err_out;
2187         }
2188
2189         info = framebuffer_alloc(sizeof(struct cirrusfb_info), &pdev->dev);
2190         if (!info) {
2191                 printk(KERN_ERR "cirrusfb: could not allocate memory\n");
2192                 ret = -ENOMEM;
2193                 goto err_disable;
2194         }
2195
2196         cinfo = info->par;
2197         cinfo->btype = btype = (enum cirrus_board) ent->driver_data;
2198
2199         dev_dbg(info->device,
2200                 " Found PCI device, base address 0 is 0x%Lx, btype set to %d\n",
2201                 (unsigned long long)pdev->resource[0].start, btype);
2202         dev_dbg(info->device, " base address 1 is 0x%Lx\n",
2203                 (unsigned long long)pdev->resource[1].start);
2204
2205         if (isPReP) {
2206                 pci_write_config_dword(pdev, PCI_BASE_ADDRESS_0, 0x00000000);
2207 #ifdef CONFIG_PPC_PREP
2208                 get_prep_addrs(&board_addr, &info->fix.mmio_start);
2209 #endif
2210         /* PReP dies if we ioremap the IO registers, but it works w/out... */
2211                 cinfo->regbase = (char __iomem *) info->fix.mmio_start;
2212         } else {
2213                 dev_dbg(info->device,
2214                         "Attempt to get PCI info for Cirrus Graphics Card\n");
2215                 get_pci_addrs(pdev, &board_addr, &info->fix.mmio_start);
2216                 /* FIXME: this forces VGA.  alternatives? */
2217                 cinfo->regbase = NULL;
2218                 cinfo->laguna_mmio = ioremap(info->fix.mmio_start, 0x1000);
2219         }
2220
2221         dev_dbg(info->device, "Board address: 0x%lx, register address: 0x%lx\n",
2222                 board_addr, info->fix.mmio_start);
2223
2224         board_size = (btype == BT_GD5480) ?
2225                 32 * MB_ : cirrusfb_get_memsize(info, cinfo->regbase);
2226
2227         ret = pci_request_regions(pdev, "cirrusfb");
2228         if (ret < 0) {
2229                 dev_err(info->device, "cannot reserve region 0x%lx, abort\n",
2230                         board_addr);
2231                 goto err_release_fb;
2232         }
2233 #if 0 /* if the system didn't claim this region, we would... */
2234         if (!request_mem_region(0xA0000, 65535, "cirrusfb")) {
2235                 dev_err(info->device, "cannot reserve region 0x%lx, abort\n",
2236                         0xA0000L);
2237                 ret = -EBUSY;
2238                 goto err_release_regions;
2239         }
2240 #endif
2241         if (request_region(0x3C0, 32, "cirrusfb"))
2242                 release_io_ports = 1;
2243
2244         info->screen_base = ioremap(board_addr, board_size);
2245         if (!info->screen_base) {
2246                 ret = -EIO;
2247                 goto err_release_legacy;
2248         }
2249
2250         info->fix.smem_start = board_addr;
2251         info->screen_size = board_size;
2252         cinfo->unmap = cirrusfb_pci_unmap;
2253
2254         dev_info(info->device,
2255                  "Cirrus Logic chipset on PCI bus, RAM (%lu kB) at 0x%lx\n",
2256                  info->screen_size >> 10, board_addr);
2257         pci_set_drvdata(pdev, info);
2258
2259         ret = cirrusfb_register(info);
2260         if (ret)
2261                 iounmap(info->screen_base);
2262         return ret;
2263
2264 err_release_legacy:
2265         if (release_io_ports)
2266                 release_region(0x3C0, 32);
2267 #if 0
2268         release_mem_region(0xA0000, 65535);
2269 err_release_regions:
2270 #endif
2271         pci_release_regions(pdev);
2272 err_release_fb:
2273         if (cinfo->laguna_mmio == NULL)
2274                 iounmap(cinfo->laguna_mmio);
2275         framebuffer_release(info);
2276 err_disable:
2277 err_out:
2278         return ret;
2279 }
2280
2281 static void __devexit cirrusfb_pci_unregister(struct pci_dev *pdev)
2282 {
2283         struct fb_info *info = pci_get_drvdata(pdev);
2284
2285         cirrusfb_cleanup(info);
2286 }
2287
2288 static struct pci_driver cirrusfb_pci_driver = {
2289         .name           = "cirrusfb",
2290         .id_table       = cirrusfb_pci_table,
2291         .probe          = cirrusfb_pci_register,
2292         .remove         = __devexit_p(cirrusfb_pci_unregister),
2293 #ifdef CONFIG_PM
2294 #if 0
2295         .suspend        = cirrusfb_pci_suspend,
2296         .resume         = cirrusfb_pci_resume,
2297 #endif
2298 #endif
2299 };
2300 #endif /* CONFIG_PCI */
2301
2302 #ifdef CONFIG_ZORRO
2303 static int __devinit cirrusfb_zorro_register(struct zorro_dev *z,
2304                                              const struct zorro_device_id *ent)
2305 {
2306         struct cirrusfb_info *cinfo;
2307         struct fb_info *info;
2308         enum cirrus_board btype;
2309         struct zorro_dev *z2 = NULL;
2310         unsigned long board_addr, board_size, size;
2311         int ret;
2312
2313         btype = ent->driver_data;
2314         if (cirrusfb_zorro_table2[btype].id2)
2315                 z2 = zorro_find_device(cirrusfb_zorro_table2[btype].id2, NULL);
2316         size = cirrusfb_zorro_table2[btype].size;
2317
2318         info = framebuffer_alloc(sizeof(struct cirrusfb_info), &z->dev);
2319         if (!info) {
2320                 printk(KERN_ERR "cirrusfb: could not allocate memory\n");
2321                 ret = -ENOMEM;
2322                 goto err_out;
2323         }
2324
2325         dev_info(info->device, "%s board detected\n",
2326                  cirrusfb_board_info[btype].name);
2327
2328         cinfo = info->par;
2329         cinfo->btype = btype;
2330
2331         assert(z);
2332         assert(btype != BT_NONE);
2333
2334         board_addr = zorro_resource_start(z);
2335         board_size = zorro_resource_len(z);
2336         info->screen_size = size;
2337
2338         if (!zorro_request_device(z, "cirrusfb")) {
2339                 dev_err(info->device, "cannot reserve region 0x%lx, abort\n",
2340                         board_addr);
2341                 ret = -EBUSY;
2342                 goto err_release_fb;
2343         }
2344
2345         ret = -EIO;
2346
2347         if (btype == BT_PICASSO4) {
2348                 dev_info(info->device, " REG at $%lx\n", board_addr + 0x600000);
2349
2350                 /* To be precise, for the P4 this is not the */
2351                 /* begin of the board, but the begin of RAM. */
2352                 /* for P4, map in its address space in 2 chunks (### TEST! ) */
2353                 /* (note the ugly hardcoded 16M number) */
2354                 cinfo->regbase = ioremap(board_addr, 16777216);
2355                 if (!cinfo->regbase)
2356                         goto err_release_region;
2357
2358                 dev_dbg(info->device, "Virtual address for board set to: $%p\n",
2359                         cinfo->regbase);
2360                 cinfo->regbase += 0x600000;
2361                 info->fix.mmio_start = board_addr + 0x600000;
2362
2363                 info->fix.smem_start = board_addr + 16777216;
2364                 info->screen_base = ioremap(info->fix.smem_start, 16777216);
2365                 if (!info->screen_base)
2366                         goto err_unmap_regbase;
2367         } else {
2368                 dev_info(info->device, " REG at $%lx\n",
2369                          (unsigned long) z2->resource.start);
2370
2371                 info->fix.smem_start = board_addr;
2372                 if (board_addr > 0x01000000)
2373                         info->screen_base = ioremap(board_addr, board_size);
2374                 else
2375                         info->screen_base = (caddr_t) ZTWO_VADDR(board_addr);
2376                 if (!info->screen_base)
2377                         goto err_release_region;
2378
2379                 /* set address for REG area of board */
2380                 cinfo->regbase = (caddr_t) ZTWO_VADDR(z2->resource.start);
2381                 info->fix.mmio_start = z2->resource.start;
2382
2383                 dev_dbg(info->device, "Virtual address for board set to: $%p\n",
2384                         cinfo->regbase);
2385         }
2386         cinfo->unmap = cirrusfb_zorro_unmap;
2387
2388         dev_info(info->device,
2389                  "Cirrus Logic chipset on Zorro bus, RAM (%lu MB) at $%lx\n",
2390                  board_size / MB_, board_addr);
2391
2392         zorro_set_drvdata(z, info);
2393
2394         ret = cirrusfb_register(info);
2395         if (ret) {
2396                 if (btype == BT_PICASSO4) {
2397                         iounmap(info->screen_base);
2398                         iounmap(cinfo->regbase - 0x600000);
2399                 } else if (board_addr > 0x01000000)
2400                         iounmap(info->screen_base);
2401         }
2402         return ret;
2403
2404 err_unmap_regbase:
2405         /* Parental advisory: explicit hack */
2406         iounmap(cinfo->regbase - 0x600000);
2407 err_release_region:
2408         release_region(board_addr, board_size);
2409 err_release_fb:
2410         framebuffer_release(info);
2411 err_out:
2412         return ret;
2413 }
2414
2415 void __devexit cirrusfb_zorro_unregister(struct zorro_dev *z)
2416 {
2417         struct fb_info *info = zorro_get_drvdata(z);
2418
2419         cirrusfb_cleanup(info);
2420 }
2421
2422 static struct zorro_driver cirrusfb_zorro_driver = {
2423         .name           = "cirrusfb",
2424         .id_table       = cirrusfb_zorro_table,
2425         .probe          = cirrusfb_zorro_register,
2426         .remove         = __devexit_p(cirrusfb_zorro_unregister),
2427 };
2428 #endif /* CONFIG_ZORRO */
2429
2430 static int __init cirrusfb_init(void)
2431 {
2432         int error = 0;
2433
2434 #ifndef MODULE
2435         char *option = NULL;
2436
2437         if (fb_get_options("cirrusfb", &option))
2438                 return -ENODEV;
2439         cirrusfb_setup(option);
2440 #endif
2441
2442 #ifdef CONFIG_ZORRO
2443         error |= zorro_register_driver(&cirrusfb_zorro_driver);
2444 #endif
2445 #ifdef CONFIG_PCI
2446         error |= pci_register_driver(&cirrusfb_pci_driver);
2447 #endif
2448         return error;
2449 }
2450
2451 #ifndef MODULE
2452 static int __init cirrusfb_setup(char *options)
2453 {
2454         char *this_opt;
2455
2456         if (!options || !*options)
2457                 return 0;
2458
2459         while ((this_opt = strsep(&options, ",")) != NULL) {
2460                 if (!*this_opt)
2461                         continue;
2462
2463                 if (!strcmp(this_opt, "noaccel"))
2464                         noaccel = 1;
2465                 else if (!strncmp(this_opt, "mode:", 5))
2466                         mode_option = this_opt + 5;
2467                 else
2468                         mode_option = this_opt;
2469         }
2470         return 0;
2471 }
2472 #endif
2473
2474     /*
2475      *  Modularization
2476      */
2477
2478 MODULE_AUTHOR("Copyright 1999,2000 Jeff Garzik <jgarzik@pobox.com>");
2479 MODULE_DESCRIPTION("Accelerated FBDev driver for Cirrus Logic chips");
2480 MODULE_LICENSE("GPL");
2481
2482 static void __exit cirrusfb_exit(void)
2483 {
2484 #ifdef CONFIG_PCI
2485         pci_unregister_driver(&cirrusfb_pci_driver);
2486 #endif
2487 #ifdef CONFIG_ZORRO
2488         zorro_unregister_driver(&cirrusfb_zorro_driver);
2489 #endif
2490 }
2491
2492 module_init(cirrusfb_init);
2493
2494 module_param(mode_option, charp, 0);
2495 MODULE_PARM_DESC(mode_option, "Initial video mode e.g. '648x480-8@60'");
2496 module_param(noaccel, bool, 0);
2497 MODULE_PARM_DESC(noaccel, "Disable acceleration");
2498
2499 #ifdef MODULE
2500 module_exit(cirrusfb_exit);
2501 #endif
2502
2503 /**********************************************************************/
2504 /* about the following functions - I have used the same names for the */
2505 /* functions as Markus Wild did in his Retina driver for NetBSD as    */
2506 /* they just made sense for this purpose. Apart from that, I wrote    */
2507 /* these functions myself.                                          */
2508 /**********************************************************************/
2509
2510 /*** WGen() - write into one of the external/general registers ***/
2511 static void WGen(const struct cirrusfb_info *cinfo,
2512                   int regnum, unsigned char val)
2513 {
2514         unsigned long regofs = 0;
2515
2516         if (cinfo->btype == BT_PICASSO) {
2517                 /* Picasso II specific hack */
2518 /*            if (regnum == VGA_PEL_IR || regnum == VGA_PEL_D ||
2519                   regnum == CL_VSSM2) */
2520                 if (regnum == VGA_PEL_IR || regnum == VGA_PEL_D)
2521                         regofs = 0xfff;
2522         }
2523
2524         vga_w(cinfo->regbase, regofs + regnum, val);
2525 }
2526
2527 /*** RGen() - read out one of the external/general registers ***/
2528 static unsigned char RGen(const struct cirrusfb_info *cinfo, int regnum)
2529 {
2530         unsigned long regofs = 0;
2531
2532         if (cinfo->btype == BT_PICASSO) {
2533                 /* Picasso II specific hack */
2534 /*            if (regnum == VGA_PEL_IR || regnum == VGA_PEL_D ||
2535                   regnum == CL_VSSM2) */
2536                 if (regnum == VGA_PEL_IR || regnum == VGA_PEL_D)
2537                         regofs = 0xfff;
2538         }
2539
2540         return vga_r(cinfo->regbase, regofs + regnum);
2541 }
2542
2543 /*** AttrOn() - turn on VideoEnable for Attribute controller ***/
2544 static void AttrOn(const struct cirrusfb_info *cinfo)
2545 {
2546         assert(cinfo != NULL);
2547
2548         if (vga_rcrt(cinfo->regbase, CL_CRT24) & 0x80) {
2549                 /* if we're just in "write value" mode, write back the */
2550                 /* same value as before to not modify anything */
2551                 vga_w(cinfo->regbase, VGA_ATT_IW,
2552                       vga_r(cinfo->regbase, VGA_ATT_R));
2553         }
2554         /* turn on video bit */
2555 /*      vga_w(cinfo->regbase, VGA_ATT_IW, 0x20); */
2556         vga_w(cinfo->regbase, VGA_ATT_IW, 0x33);
2557
2558         /* dummy write on Reg0 to be on "write index" mode next time */
2559         vga_w(cinfo->regbase, VGA_ATT_IW, 0x00);
2560 }
2561
2562 /*** WHDR() - write into the Hidden DAC register ***/
2563 /* as the HDR is the only extension register that requires special treatment
2564  * (the other extension registers are accessible just like the "ordinary"
2565  * registers of their functional group) here is a specialized routine for
2566  * accessing the HDR
2567  */
2568 static void WHDR(const struct cirrusfb_info *cinfo, unsigned char val)
2569 {
2570         unsigned char dummy;
2571
2572         if (cinfo->btype == BT_PICASSO) {
2573                 /* Klaus' hint for correct access to HDR on some boards */
2574                 /* first write 0 to pixel mask (3c6) */
2575                 WGen(cinfo, VGA_PEL_MSK, 0x00);
2576                 udelay(200);
2577                 /* next read dummy from pixel address (3c8) */
2578                 dummy = RGen(cinfo, VGA_PEL_IW);
2579                 udelay(200);
2580         }
2581         /* now do the usual stuff to access the HDR */
2582
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         dummy = RGen(cinfo, VGA_PEL_MSK);
2590         udelay(200);
2591
2592         WGen(cinfo, VGA_PEL_MSK, val);
2593         udelay(200);
2594
2595         if (cinfo->btype == BT_PICASSO) {
2596                 /* now first reset HDR access counter */
2597                 dummy = RGen(cinfo, VGA_PEL_IW);
2598                 udelay(200);
2599
2600                 /* and at the end, restore the mask value */
2601                 /* ## is this mask always 0xff? */
2602                 WGen(cinfo, VGA_PEL_MSK, 0xff);
2603                 udelay(200);
2604         }
2605 }
2606
2607 /*** WSFR() - write to the "special function register" (SFR) ***/
2608 static void WSFR(struct cirrusfb_info *cinfo, unsigned char val)
2609 {
2610 #ifdef CONFIG_ZORRO
2611         assert(cinfo->regbase != NULL);
2612         cinfo->SFR = val;
2613         z_writeb(val, cinfo->regbase + 0x8000);
2614 #endif
2615 }
2616
2617 /* The Picasso has a second register for switching the monitor bit */
2618 static void WSFR2(struct cirrusfb_info *cinfo, unsigned char val)
2619 {
2620 #ifdef CONFIG_ZORRO
2621         /* writing an arbitrary value to this one causes the monitor switcher */
2622         /* to flip to Amiga display */
2623         assert(cinfo->regbase != NULL);
2624         cinfo->SFR = val;
2625         z_writeb(val, cinfo->regbase + 0x9000);
2626 #endif
2627 }
2628
2629 /*** WClut - set CLUT entry (range: 0..63) ***/
2630 static void WClut(struct cirrusfb_info *cinfo, unsigned char regnum, unsigned char red,
2631             unsigned char green, unsigned char blue)
2632 {
2633         unsigned int data = VGA_PEL_D;
2634
2635         /* address write mode register is not translated.. */
2636         vga_w(cinfo->regbase, VGA_PEL_IW, regnum);
2637
2638         if (cinfo->btype == BT_PICASSO || cinfo->btype == BT_PICASSO4 ||
2639             cinfo->btype == BT_ALPINE || cinfo->btype == BT_GD5480) {
2640                 /* but DAC data register IS, at least for Picasso II */
2641                 if (cinfo->btype == BT_PICASSO)
2642                         data += 0xfff;
2643                 vga_w(cinfo->regbase, data, red);
2644                 vga_w(cinfo->regbase, data, green);
2645                 vga_w(cinfo->regbase, data, blue);
2646         } else {
2647                 vga_w(cinfo->regbase, data, blue);
2648                 vga_w(cinfo->regbase, data, green);
2649                 vga_w(cinfo->regbase, data, red);
2650         }
2651 }
2652
2653 #if 0
2654 /*** RClut - read CLUT entry (range 0..63) ***/
2655 static void RClut(struct cirrusfb_info *cinfo, unsigned char regnum, unsigned char *red,
2656             unsigned char *green, unsigned char *blue)
2657 {
2658         unsigned int data = VGA_PEL_D;
2659
2660         vga_w(cinfo->regbase, VGA_PEL_IR, regnum);
2661
2662         if (cinfo->btype == BT_PICASSO || cinfo->btype == BT_PICASSO4 ||
2663             cinfo->btype == BT_ALPINE || cinfo->btype == BT_GD5480) {
2664                 if (cinfo->btype == BT_PICASSO)
2665                         data += 0xfff;
2666                 *red = vga_r(cinfo->regbase, data);
2667                 *green = vga_r(cinfo->regbase, data);
2668                 *blue = vga_r(cinfo->regbase, data);
2669         } else {
2670                 *blue = vga_r(cinfo->regbase, data);
2671                 *green = vga_r(cinfo->regbase, data);
2672                 *red = vga_r(cinfo->regbase, data);
2673         }
2674 }
2675 #endif
2676
2677 /*******************************************************************
2678         cirrusfb_WaitBLT()
2679
2680         Wait for the BitBLT engine to complete a possible earlier job
2681 *********************************************************************/
2682
2683 /* FIXME: use interrupts instead */
2684 static void cirrusfb_WaitBLT(u8 __iomem *regbase)
2685 {
2686         /* now busy-wait until we're done */
2687         while (vga_rgfx(regbase, CL_GR31) & 0x08)
2688                 /* do nothing */ ;
2689 }
2690
2691 /*******************************************************************
2692         cirrusfb_BitBLT()
2693
2694         perform accelerated "scrolling"
2695 ********************************************************************/
2696
2697 static void cirrusfb_BitBLT(u8 __iomem *regbase, int bits_per_pixel,
2698                             u_short curx, u_short cury,
2699                             u_short destx, u_short desty,
2700                             u_short width, u_short height,
2701                             u_short line_length)
2702 {
2703         u_short nwidth, nheight;
2704         u_long nsrc, ndest;
2705         u_char bltmode;
2706
2707         nwidth = width - 1;
2708         nheight = height - 1;
2709
2710         bltmode = 0x00;
2711         /* if source adr < dest addr, do the Blt backwards */
2712         if (cury <= desty) {
2713                 if (cury == desty) {
2714                         /* if src and dest are on the same line, check x */
2715                         if (curx < destx)
2716                                 bltmode |= 0x01;
2717                 } else
2718                         bltmode |= 0x01;
2719         }
2720         if (!bltmode) {
2721                 /* standard case: forward blitting */
2722                 nsrc = (cury * line_length) + curx;
2723                 ndest = (desty * line_length) + destx;
2724         } else {
2725                 /* this means start addresses are at the end,
2726                  * counting backwards
2727                  */
2728                 nsrc = cury * line_length + curx +
2729                         nheight * line_length + nwidth;
2730                 ndest = desty * line_length + destx +
2731                         nheight * line_length + nwidth;
2732         }
2733
2734         /*
2735            run-down of registers to be programmed:
2736            destination pitch
2737            source pitch
2738            BLT width/height
2739            source start
2740            destination start
2741            BLT mode
2742            BLT ROP
2743            VGA_GFX_SR_VALUE / VGA_GFX_SR_ENABLE: "fill color"
2744            start/stop
2745          */
2746
2747         cirrusfb_WaitBLT(regbase);
2748
2749         /* pitch: set to line_length */
2750         /* dest pitch low */
2751         vga_wgfx(regbase, CL_GR24, line_length & 0xff);
2752         /* dest pitch hi */
2753         vga_wgfx(regbase, CL_GR25, line_length >> 8);
2754         /* source pitch low */
2755         vga_wgfx(regbase, CL_GR26, line_length & 0xff);
2756         /* source pitch hi */
2757         vga_wgfx(regbase, CL_GR27, line_length >> 8);
2758
2759         /* BLT width: actual number of pixels - 1 */
2760         /* BLT width low */
2761         vga_wgfx(regbase, CL_GR20, nwidth & 0xff);
2762         /* BLT width hi */
2763         vga_wgfx(regbase, CL_GR21, nwidth >> 8);
2764
2765         /* BLT height: actual number of lines -1 */
2766         /* BLT height low */
2767         vga_wgfx(regbase, CL_GR22, nheight & 0xff);
2768         /* BLT width hi */
2769         vga_wgfx(regbase, CL_GR23, nheight >> 8);
2770
2771         /* BLT destination */
2772         /* BLT dest low */
2773         vga_wgfx(regbase, CL_GR28, (u_char) (ndest & 0xff));
2774         /* BLT dest mid */
2775         vga_wgfx(regbase, CL_GR29, (u_char) (ndest >> 8));
2776         /* BLT dest hi */
2777         vga_wgfx(regbase, CL_GR2A, (u_char) (ndest >> 16));
2778
2779         /* BLT source */
2780         /* BLT src low */
2781         vga_wgfx(regbase, CL_GR2C, (u_char) (nsrc & 0xff));
2782         /* BLT src mid */
2783         vga_wgfx(regbase, CL_GR2D, (u_char) (nsrc >> 8));
2784         /* BLT src hi */
2785         vga_wgfx(regbase, CL_GR2E, (u_char) (nsrc >> 16));
2786
2787         /* BLT mode */
2788         vga_wgfx(regbase, CL_GR30, bltmode);    /* BLT mode */
2789
2790         /* BLT ROP: SrcCopy */
2791         vga_wgfx(regbase, CL_GR32, 0x0d);       /* BLT ROP */
2792
2793         /* and finally: GO! */
2794         vga_wgfx(regbase, CL_GR31, 0x02);       /* BLT Start/status */
2795 }
2796
2797 /*******************************************************************
2798         cirrusfb_RectFill()
2799
2800         perform accelerated rectangle fill
2801 ********************************************************************/
2802
2803 static void cirrusfb_RectFill(u8 __iomem *regbase, int bits_per_pixel,
2804                      u_short x, u_short y, u_short width, u_short height,
2805                      u_char color, u_short line_length)
2806 {
2807         u_short nwidth, nheight;
2808         u_long ndest;
2809         u_char op;
2810
2811         nwidth = width - 1;
2812         nheight = height - 1;
2813
2814         ndest = (y * line_length) + x;
2815
2816         cirrusfb_WaitBLT(regbase);
2817
2818         /* pitch: set to line_length */
2819         vga_wgfx(regbase, CL_GR24, line_length & 0xff); /* dest pitch low */
2820         vga_wgfx(regbase, CL_GR25, line_length >> 8);   /* dest pitch hi */
2821         vga_wgfx(regbase, CL_GR26, line_length & 0xff); /* source pitch low */
2822         vga_wgfx(regbase, CL_GR27, line_length >> 8);   /* source pitch hi */
2823
2824         /* BLT width: actual number of pixels - 1 */
2825         vga_wgfx(regbase, CL_GR20, nwidth & 0xff);      /* BLT width low */
2826         vga_wgfx(regbase, CL_GR21, nwidth >> 8);        /* BLT width hi */
2827
2828         /* BLT height: actual number of lines -1 */
2829         vga_wgfx(regbase, CL_GR22, nheight & 0xff);     /* BLT height low */
2830         vga_wgfx(regbase, CL_GR23, nheight >> 8);       /* BLT width hi */
2831
2832         /* BLT destination */
2833         /* BLT dest low */
2834         vga_wgfx(regbase, CL_GR28, (u_char) (ndest & 0xff));
2835         /* BLT dest mid */
2836         vga_wgfx(regbase, CL_GR29, (u_char) (ndest >> 8));
2837         /* BLT dest hi */
2838         vga_wgfx(regbase, CL_GR2A, (u_char) (ndest >> 16));
2839
2840         /* BLT source: set to 0 (is a dummy here anyway) */
2841         vga_wgfx(regbase, CL_GR2C, 0x00);       /* BLT src low */
2842         vga_wgfx(regbase, CL_GR2D, 0x00);       /* BLT src mid */
2843         vga_wgfx(regbase, CL_GR2E, 0x00);       /* BLT src hi */
2844
2845         /* This is a ColorExpand Blt, using the */
2846         /* same color for foreground and background */
2847         vga_wgfx(regbase, VGA_GFX_SR_VALUE, color);     /* foreground color */
2848         vga_wgfx(regbase, VGA_GFX_SR_ENABLE, color);    /* background color */
2849
2850         op = 0xc0;
2851         if (bits_per_pixel == 16) {
2852                 vga_wgfx(regbase, CL_GR10, color);      /* foreground color */
2853                 vga_wgfx(regbase, CL_GR11, color);      /* background color */
2854                 op = 0x50;
2855                 op = 0xd0;
2856         } else if (bits_per_pixel == 32) {
2857                 vga_wgfx(regbase, CL_GR10, color);      /* foreground color */
2858                 vga_wgfx(regbase, CL_GR11, color);      /* background color */
2859                 vga_wgfx(regbase, CL_GR12, color);      /* foreground color */
2860                 vga_wgfx(regbase, CL_GR13, color);      /* background color */
2861                 vga_wgfx(regbase, CL_GR14, 0);  /* foreground color */
2862                 vga_wgfx(regbase, CL_GR15, 0);  /* background color */
2863                 op = 0x50;
2864                 op = 0xf0;
2865         }
2866         /* BLT mode: color expand, Enable 8x8 copy (faster?) */
2867         vga_wgfx(regbase, CL_GR30, op); /* BLT mode */
2868
2869         /* BLT ROP: SrcCopy */
2870         vga_wgfx(regbase, CL_GR32, 0x0d);       /* BLT ROP */
2871
2872         /* and finally: GO! */
2873         vga_wgfx(regbase, CL_GR31, 0x02);       /* BLT Start/status */
2874 }
2875
2876 /**************************************************************************
2877  * bestclock() - determine closest possible clock lower(?) than the
2878  * desired pixel clock
2879  **************************************************************************/
2880 static void bestclock(long freq, int *nom, int *den, int *div)
2881 {
2882         int n, d;
2883         long h, diff;
2884
2885         assert(nom != NULL);
2886         assert(den != NULL);
2887         assert(div != NULL);
2888
2889         *nom = 0;
2890         *den = 0;
2891         *div = 0;
2892
2893         if (freq < 8000)
2894                 freq = 8000;
2895
2896         diff = freq;
2897
2898         for (n = 32; n < 128; n++) {
2899                 int s = 0;
2900
2901                 d = (14318 * n) / freq;
2902                 if ((d >= 7) && (d <= 63)) {
2903                         int temp = d;
2904
2905                         if (temp > 31) {
2906                                 s = 1;
2907                                 temp >>= 1;
2908                         }
2909                         h = ((14318 * n) / temp) >> s;
2910                         h = h > freq ? h - freq : freq - h;
2911                         if (h < diff) {
2912                                 diff = h;
2913                                 *nom = n;
2914                                 *den = temp;
2915                                 *div = s;
2916                         }
2917                 }
2918                 d++;
2919                 if ((d >= 7) && (d <= 63)) {
2920                         if (d > 31) {
2921                                 s = 1;
2922                                 d >>= 1;
2923                         }
2924                         h = ((14318 * n) / d) >> s;
2925                         h = h > freq ? h - freq : freq - h;
2926                         if (h < diff) {
2927                                 diff = h;
2928                                 *nom = n;
2929                                 *den = d;
2930                                 *div = s;
2931                         }
2932                 }
2933         }
2934 }
2935
2936 /* -------------------------------------------------------------------------
2937  *
2938  * debugging functions
2939  *
2940  * -------------------------------------------------------------------------
2941  */
2942
2943 #ifdef CIRRUSFB_DEBUG
2944
2945 /**
2946  * cirrusfb_dbg_print_regs
2947  * @base: If using newmmio, the newmmio base address, otherwise %NULL
2948  * @reg_class: type of registers to read: %CRT, or %SEQ
2949  *
2950  * DESCRIPTION:
2951  * Dumps the given list of VGA CRTC registers.  If @base is %NULL,
2952  * old-style I/O ports are queried for information, otherwise MMIO is
2953  * used at the given @base address to query the information.
2954  */
2955
2956 static void cirrusfb_dbg_print_regs(struct fb_info *info,
2957                                     caddr_t regbase,
2958                                     enum cirrusfb_dbg_reg_class reg_class, ...)
2959 {
2960         va_list list;
2961         unsigned char val = 0;
2962         unsigned reg;
2963         char *name;
2964
2965         va_start(list, reg_class);
2966
2967         name = va_arg(list, char *);
2968         while (name != NULL) {
2969                 reg = va_arg(list, int);
2970
2971                 switch (reg_class) {
2972                 case CRT:
2973                         val = vga_rcrt(regbase, (unsigned char) reg);
2974                         break;
2975                 case SEQ:
2976                         val = vga_rseq(regbase, (unsigned char) reg);
2977                         break;
2978                 default:
2979                         /* should never occur */
2980                         assert(false);
2981                         break;
2982                 }
2983
2984                 dev_dbg(info->device, "%8s = 0x%02X\n", name, val);
2985
2986                 name = va_arg(list, char *);
2987         }
2988
2989         va_end(list);
2990 }
2991
2992 /**
2993  * cirrusfb_dbg_reg_dump
2994  * @base: If using newmmio, the newmmio base address, otherwise %NULL
2995  *
2996  * DESCRIPTION:
2997  * Dumps a list of interesting VGA and CIRRUSFB registers.  If @base is %NULL,
2998  * old-style I/O ports are queried for information, otherwise MMIO is
2999  * used at the given @base address to query the information.
3000  */
3001
3002 static void cirrusfb_dbg_reg_dump(struct fb_info *info, caddr_t regbase)
3003 {
3004         dev_dbg(info->device, "VGA CRTC register dump:\n");
3005
3006         cirrusfb_dbg_print_regs(info, regbase, CRT,
3007                            "CR00", 0x00,
3008                            "CR01", 0x01,
3009                            "CR02", 0x02,
3010                            "CR03", 0x03,
3011                            "CR04", 0x04,
3012                            "CR05", 0x05,
3013                            "CR06", 0x06,
3014                            "CR07", 0x07,
3015                            "CR08", 0x08,
3016                            "CR09", 0x09,
3017                            "CR0A", 0x0A,
3018                            "CR0B", 0x0B,
3019                            "CR0C", 0x0C,
3020                            "CR0D", 0x0D,
3021                            "CR0E", 0x0E,
3022                            "CR0F", 0x0F,
3023                            "CR10", 0x10,
3024                            "CR11", 0x11,
3025                            "CR12", 0x12,
3026                            "CR13", 0x13,
3027                            "CR14", 0x14,
3028                            "CR15", 0x15,
3029                            "CR16", 0x16,
3030                            "CR17", 0x17,
3031                            "CR18", 0x18,
3032                            "CR22", 0x22,
3033                            "CR24", 0x24,
3034                            "CR26", 0x26,
3035                            "CR2D", 0x2D,
3036                            "CR2E", 0x2E,
3037                            "CR2F", 0x2F,
3038                            "CR30", 0x30,
3039                            "CR31", 0x31,
3040                            "CR32", 0x32,
3041                            "CR33", 0x33,
3042                            "CR34", 0x34,
3043                            "CR35", 0x35,
3044                            "CR36", 0x36,
3045                            "CR37", 0x37,
3046                            "CR38", 0x38,
3047                            "CR39", 0x39,
3048                            "CR3A", 0x3A,
3049                            "CR3B", 0x3B,
3050                            "CR3C", 0x3C,
3051                            "CR3D", 0x3D,
3052                            "CR3E", 0x3E,
3053                            "CR3F", 0x3F,
3054                            NULL);
3055
3056         dev_dbg(info->device, "\n");
3057
3058         dev_dbg(info->device, "VGA SEQ register dump:\n");
3059
3060         cirrusfb_dbg_print_regs(info, regbase, SEQ,
3061                            "SR00", 0x00,
3062                            "SR01", 0x01,
3063                            "SR02", 0x02,
3064                            "SR03", 0x03,
3065                            "SR04", 0x04,
3066                            "SR08", 0x08,
3067                            "SR09", 0x09,
3068                            "SR0A", 0x0A,
3069                            "SR0B", 0x0B,
3070                            "SR0D", 0x0D,
3071                            "SR10", 0x10,
3072                            "SR11", 0x11,
3073                            "SR12", 0x12,
3074                            "SR13", 0x13,
3075                            "SR14", 0x14,
3076                            "SR15", 0x15,
3077                            "SR16", 0x16,
3078                            "SR17", 0x17,
3079                            "SR18", 0x18,
3080                            "SR19", 0x19,
3081                            "SR1A", 0x1A,
3082                            "SR1B", 0x1B,
3083                            "SR1C", 0x1C,
3084                            "SR1D", 0x1D,
3085                            "SR1E", 0x1E,
3086                            "SR1F", 0x1F,
3087                            NULL);
3088
3089         dev_dbg(info->device, "\n");
3090 }
3091
3092 #endif                          /* CIRRUSFB_DEBUG */
3093