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