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