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