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