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