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