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