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