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