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