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