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