cirrusfb: various Laguna fixes
[pandora-kernel.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                               u_char 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                 /* reset blitter */
1554                 vga_wgfx(cinfo->regbase, CL_GR31, 0x04);
1555
1556                 switch (cinfo->btype) {
1557                 case BT_GD5480:
1558                         vga_wseq(cinfo->regbase, CL_SEQRF, 0x98);
1559                         break;
1560                 case BT_ALPINE:
1561                 case BT_LAGUNA:
1562                 case BT_LAGUNAB:
1563                         break;
1564                 case BT_SD64:
1565                         vga_wseq(cinfo->regbase, CL_SEQRF, 0xb8);
1566                         break;
1567                 default:
1568                         vga_wseq(cinfo->regbase, CL_SEQR16, 0x0f);
1569                         vga_wseq(cinfo->regbase, CL_SEQRF, 0xb0);
1570                         break;
1571                 }
1572         }
1573         /* plane mask: nothing */
1574         vga_wseq(cinfo->regbase, VGA_SEQ_PLANE_WRITE, 0xff);
1575         /* character map select: doesn't even matter in gx mode */
1576         vga_wseq(cinfo->regbase, VGA_SEQ_CHARACTER_MAP, 0x00);
1577         /* memory mode: chain4, ext. memory */
1578         vga_wseq(cinfo->regbase, VGA_SEQ_MEMORY_MODE, 0x0a);
1579
1580         /* controller-internal base address of video memory */
1581         if (bi->init_sr07)
1582                 vga_wseq(cinfo->regbase, CL_SEQR7, bi->sr07);
1583
1584         /*  vga_wseq(cinfo->regbase, CL_SEQR8, 0x00); */
1585         /* EEPROM control: shouldn't be necessary to write to this at all.. */
1586
1587         /* graphics cursor X position (incomplete; position gives rem. 3 bits */
1588         vga_wseq(cinfo->regbase, CL_SEQR10, 0x00);
1589         /* graphics cursor Y position (..."... ) */
1590         vga_wseq(cinfo->regbase, CL_SEQR11, 0x00);
1591         /* graphics cursor attributes */
1592         vga_wseq(cinfo->regbase, CL_SEQR12, 0x00);
1593         /* graphics cursor pattern address */
1594         vga_wseq(cinfo->regbase, CL_SEQR13, 0x00);
1595
1596         /* writing these on a P4 might give problems..  */
1597         if (cinfo->btype != BT_PICASSO4) {
1598                 /* configuration readback and ext. color */
1599                 vga_wseq(cinfo->regbase, CL_SEQR17, 0x00);
1600                 /* signature generator */
1601                 vga_wseq(cinfo->regbase, CL_SEQR18, 0x02);
1602         }
1603
1604         /* MCLK select etc. */
1605         if (bi->init_sr1f)
1606                 vga_wseq(cinfo->regbase, CL_SEQR1F, bi->sr1f);
1607
1608         /* Screen A preset row scan: none */
1609         vga_wcrt(cinfo->regbase, VGA_CRTC_PRESET_ROW, 0x00);
1610         /* Text cursor start: disable text cursor */
1611         vga_wcrt(cinfo->regbase, VGA_CRTC_CURSOR_START, 0x20);
1612         /* Text cursor end: - */
1613         vga_wcrt(cinfo->regbase, VGA_CRTC_CURSOR_END, 0x00);
1614         /* text cursor location high: 0 */
1615         vga_wcrt(cinfo->regbase, VGA_CRTC_CURSOR_HI, 0x00);
1616         /* text cursor location low: 0 */
1617         vga_wcrt(cinfo->regbase, VGA_CRTC_CURSOR_LO, 0x00);
1618
1619         /* Underline Row scanline: - */
1620         vga_wcrt(cinfo->regbase, VGA_CRTC_UNDERLINE, 0x00);
1621         /* ### add 0x40 for text modes with > 30 MHz pixclock */
1622         /* ext. display controls: ext.adr. wrap */
1623         vga_wcrt(cinfo->regbase, CL_CRT1B, 0x02);
1624
1625         /* Set/Reset registes: - */
1626         vga_wgfx(cinfo->regbase, VGA_GFX_SR_VALUE, 0x00);
1627         /* Set/Reset enable: - */
1628         vga_wgfx(cinfo->regbase, VGA_GFX_SR_ENABLE, 0x00);
1629         /* Color Compare: - */
1630         vga_wgfx(cinfo->regbase, VGA_GFX_COMPARE_VALUE, 0x00);
1631         /* Data Rotate: - */
1632         vga_wgfx(cinfo->regbase, VGA_GFX_DATA_ROTATE, 0x00);
1633         /* Read Map Select: - */
1634         vga_wgfx(cinfo->regbase, VGA_GFX_PLANE_READ, 0x00);
1635         /* Mode: conf. for 16/4/2 color mode, no odd/even, read/write mode 0 */
1636         vga_wgfx(cinfo->regbase, VGA_GFX_MODE, 0x00);
1637         /* Miscellaneous: memory map base address, graphics mode */
1638         vga_wgfx(cinfo->regbase, VGA_GFX_MISC, 0x01);
1639         /* Color Don't care: involve all planes */
1640         vga_wgfx(cinfo->regbase, VGA_GFX_COMPARE_MASK, 0x0f);
1641         /* Bit Mask: no mask at all */
1642         vga_wgfx(cinfo->regbase, VGA_GFX_BIT_MASK, 0xff);
1643
1644         if (cinfo->btype == BT_ALPINE || is_laguna(cinfo))
1645                 /* (5434 can't have bit 3 set for bitblt) */
1646                 vga_wgfx(cinfo->regbase, CL_GRB, 0x20);
1647         else
1648         /* Graphics controller mode extensions: finer granularity,
1649          * 8byte data latches
1650          */
1651                 vga_wgfx(cinfo->regbase, CL_GRB, 0x28);
1652
1653         vga_wgfx(cinfo->regbase, CL_GRC, 0xff); /* Color Key compare: - */
1654         vga_wgfx(cinfo->regbase, CL_GRD, 0x00); /* Color Key compare mask: - */
1655         vga_wgfx(cinfo->regbase, CL_GRE, 0x00); /* Miscellaneous control: - */
1656         /* Background color byte 1: - */
1657         /*  vga_wgfx (cinfo->regbase, CL_GR10, 0x00); */
1658         /*  vga_wgfx (cinfo->regbase, CL_GR11, 0x00); */
1659
1660         /* Attribute Controller palette registers: "identity mapping" */
1661         vga_wattr(cinfo->regbase, VGA_ATC_PALETTE0, 0x00);
1662         vga_wattr(cinfo->regbase, VGA_ATC_PALETTE1, 0x01);
1663         vga_wattr(cinfo->regbase, VGA_ATC_PALETTE2, 0x02);
1664         vga_wattr(cinfo->regbase, VGA_ATC_PALETTE3, 0x03);
1665         vga_wattr(cinfo->regbase, VGA_ATC_PALETTE4, 0x04);
1666         vga_wattr(cinfo->regbase, VGA_ATC_PALETTE5, 0x05);
1667         vga_wattr(cinfo->regbase, VGA_ATC_PALETTE6, 0x06);
1668         vga_wattr(cinfo->regbase, VGA_ATC_PALETTE7, 0x07);
1669         vga_wattr(cinfo->regbase, VGA_ATC_PALETTE8, 0x08);
1670         vga_wattr(cinfo->regbase, VGA_ATC_PALETTE9, 0x09);
1671         vga_wattr(cinfo->regbase, VGA_ATC_PALETTEA, 0x0a);
1672         vga_wattr(cinfo->regbase, VGA_ATC_PALETTEB, 0x0b);
1673         vga_wattr(cinfo->regbase, VGA_ATC_PALETTEC, 0x0c);
1674         vga_wattr(cinfo->regbase, VGA_ATC_PALETTED, 0x0d);
1675         vga_wattr(cinfo->regbase, VGA_ATC_PALETTEE, 0x0e);
1676         vga_wattr(cinfo->regbase, VGA_ATC_PALETTEF, 0x0f);
1677
1678         /* Attribute Controller mode: graphics mode */
1679         vga_wattr(cinfo->regbase, VGA_ATC_MODE, 0x01);
1680         /* Overscan color reg.: reg. 0 */
1681         vga_wattr(cinfo->regbase, VGA_ATC_OVERSCAN, 0x00);
1682         /* Color Plane enable: Enable all 4 planes */
1683         vga_wattr(cinfo->regbase, VGA_ATC_PLANE_ENABLE, 0x0f);
1684         /* Color Select: - */
1685         vga_wattr(cinfo->regbase, VGA_ATC_COLOR_PAGE, 0x00);
1686
1687         WGen(cinfo, VGA_PEL_MSK, 0xff); /* Pixel mask: no mask */
1688
1689         /* BLT Start/status: Blitter reset */
1690         vga_wgfx(cinfo->regbase, CL_GR31, 0x04);
1691         /* - " -           : "end-of-reset" */
1692         vga_wgfx(cinfo->regbase, CL_GR31, 0x00);
1693
1694         /* misc... */
1695         WHDR(cinfo, 0); /* Hidden DAC register: - */
1696         return;
1697 }
1698
1699 static void switch_monitor(struct cirrusfb_info *cinfo, int on)
1700 {
1701 #ifdef CONFIG_ZORRO /* only works on Zorro boards */
1702         static int IsOn = 0;    /* XXX not ok for multiple boards */
1703
1704         if (cinfo->btype == BT_PICASSO4)
1705                 return;         /* nothing to switch */
1706         if (cinfo->btype == BT_ALPINE)
1707                 return;         /* nothing to switch */
1708         if (cinfo->btype == BT_GD5480)
1709                 return;         /* nothing to switch */
1710         if (cinfo->btype == BT_PICASSO) {
1711                 if ((on && !IsOn) || (!on && IsOn))
1712                         WSFR(cinfo, 0xff);
1713                 return;
1714         }
1715         if (on) {
1716                 switch (cinfo->btype) {
1717                 case BT_SD64:
1718                         WSFR(cinfo, cinfo->SFR | 0x21);
1719                         break;
1720                 case BT_PICCOLO:
1721                         WSFR(cinfo, cinfo->SFR | 0x28);
1722                         break;
1723                 case BT_SPECTRUM:
1724                         WSFR(cinfo, 0x6f);
1725                         break;
1726                 default: /* do nothing */ break;
1727                 }
1728         } else {
1729                 switch (cinfo->btype) {
1730                 case BT_SD64:
1731                         WSFR(cinfo, cinfo->SFR & 0xde);
1732                         break;
1733                 case BT_PICCOLO:
1734                         WSFR(cinfo, cinfo->SFR & 0xd7);
1735                         break;
1736                 case BT_SPECTRUM:
1737                         WSFR(cinfo, 0x4f);
1738                         break;
1739                 default: /* do nothing */
1740                         break;
1741                 }
1742         }
1743 #endif /* CONFIG_ZORRO */
1744 }
1745
1746 /******************************************/
1747 /* Linux 2.6-style  accelerated functions */
1748 /******************************************/
1749
1750 static void cirrusfb_fillrect(struct fb_info *info,
1751                               const struct fb_fillrect *region)
1752 {
1753         struct fb_fillrect modded;
1754         int vxres, vyres;
1755         struct cirrusfb_info *cinfo = info->par;
1756         int m = info->var.bits_per_pixel;
1757         u32 color = (info->fix.visual == FB_VISUAL_TRUECOLOR) ?
1758                 cinfo->pseudo_palette[region->color] : region->color;
1759
1760         if (info->state != FBINFO_STATE_RUNNING)
1761                 return;
1762         if (info->flags & FBINFO_HWACCEL_DISABLED) {
1763                 cfb_fillrect(info, region);
1764                 return;
1765         }
1766
1767         vxres = info->var.xres_virtual;
1768         vyres = info->var.yres_virtual;
1769
1770         memcpy(&modded, region, sizeof(struct fb_fillrect));
1771
1772         if (!modded.width || !modded.height ||
1773            modded.dx >= vxres || modded.dy >= vyres)
1774                 return;
1775
1776         if (modded.dx + modded.width  > vxres)
1777                 modded.width  = vxres - modded.dx;
1778         if (modded.dy + modded.height > vyres)
1779                 modded.height = vyres - modded.dy;
1780
1781         cirrusfb_RectFill(cinfo->regbase,
1782                           info->var.bits_per_pixel,
1783                           (region->dx * m) / 8, region->dy,
1784                           (region->width * m) / 8, region->height,
1785                           color,
1786                           info->fix.line_length);
1787 }
1788
1789 static void cirrusfb_copyarea(struct fb_info *info,
1790                               const struct fb_copyarea *area)
1791 {
1792         struct fb_copyarea modded;
1793         u32 vxres, vyres;
1794         struct cirrusfb_info *cinfo = info->par;
1795         int m = info->var.bits_per_pixel;
1796
1797         if (info->state != FBINFO_STATE_RUNNING)
1798                 return;
1799         if (info->flags & FBINFO_HWACCEL_DISABLED) {
1800                 cfb_copyarea(info, area);
1801                 return;
1802         }
1803
1804         vxres = info->var.xres_virtual;
1805         vyres = info->var.yres_virtual;
1806         memcpy(&modded, area, sizeof(struct fb_copyarea));
1807
1808         if (!modded.width || !modded.height ||
1809            modded.sx >= vxres || modded.sy >= vyres ||
1810            modded.dx >= vxres || modded.dy >= vyres)
1811                 return;
1812
1813         if (modded.sx + modded.width > vxres)
1814                 modded.width = vxres - modded.sx;
1815         if (modded.dx + modded.width > vxres)
1816                 modded.width = vxres - modded.dx;
1817         if (modded.sy + modded.height > vyres)
1818                 modded.height = vyres - modded.sy;
1819         if (modded.dy + modded.height > vyres)
1820                 modded.height = vyres - modded.dy;
1821
1822         cirrusfb_BitBLT(cinfo->regbase, info->var.bits_per_pixel,
1823                         (area->sx * m) / 8, area->sy,
1824                         (area->dx * m) / 8, area->dy,
1825                         (area->width * m) / 8, area->height,
1826                         info->fix.line_length);
1827
1828 }
1829
1830 static void cirrusfb_imageblit(struct fb_info *info,
1831                                const struct fb_image *image)
1832 {
1833         struct cirrusfb_info *cinfo = info->par;
1834
1835         if (!is_laguna(cinfo))
1836                 cirrusfb_WaitBLT(cinfo->regbase);
1837         cfb_imageblit(info, image);
1838 }
1839
1840 #ifdef CONFIG_PPC_PREP
1841 #define PREP_VIDEO_BASE ((volatile unsigned long) 0xC0000000)
1842 #define PREP_IO_BASE    ((volatile unsigned char *) 0x80000000)
1843 static void get_prep_addrs(unsigned long *display, unsigned long *registers)
1844 {
1845         *display = PREP_VIDEO_BASE;
1846         *registers = (unsigned long) PREP_IO_BASE;
1847 }
1848
1849 #endif                          /* CONFIG_PPC_PREP */
1850
1851 #ifdef CONFIG_PCI
1852 static int release_io_ports;
1853
1854 /* Pulled the logic from XFree86 Cirrus driver to get the memory size,
1855  * based on the DRAM bandwidth bit and DRAM bank switching bit.  This
1856  * works with 1MB, 2MB and 4MB configurations (which the Motorola boards
1857  * seem to have. */
1858 static unsigned int __devinit cirrusfb_get_memsize(struct fb_info *info,
1859                                                    u8 __iomem *regbase)
1860 {
1861         unsigned long mem;
1862         struct cirrusfb_info *cinfo = info->par;
1863
1864         if (is_laguna(cinfo)) {
1865                 unsigned char SR14 = vga_rseq(regbase, CL_SEQR14);
1866
1867                 mem = ((SR14 & 7) + 1) << 20;
1868         } else {
1869                 unsigned char SRF = vga_rseq(regbase, CL_SEQRF);
1870                 switch ((SRF & 0x18)) {
1871                 case 0x08:
1872                         mem = 512 * 1024;
1873                         break;
1874                 case 0x10:
1875                         mem = 1024 * 1024;
1876                         break;
1877                 /* 64-bit DRAM data bus width; assume 2MB.
1878                  * Also indicates 2MB memory on the 5430.
1879                  */
1880                 case 0x18:
1881                         mem = 2048 * 1024;
1882                         break;
1883                 default:
1884                         dev_warn(info->device, "Unknown memory size!\n");
1885                         mem = 1024 * 1024;
1886                 }
1887                 /* If DRAM bank switching is enabled, there must be
1888                  * twice as much memory installed. (4MB on the 5434)
1889                  */
1890                 if (SRF & 0x80)
1891                         mem *= 2;
1892         }
1893
1894         /* TODO: Handling of GD5446/5480 (see XF86 sources ...) */
1895         return mem;
1896 }
1897
1898 static void get_pci_addrs(const struct pci_dev *pdev,
1899                           unsigned long *display, unsigned long *registers)
1900 {
1901         assert(pdev != NULL);
1902         assert(display != NULL);
1903         assert(registers != NULL);
1904
1905         *display = 0;
1906         *registers = 0;
1907
1908         /* This is a best-guess for now */
1909
1910         if (pci_resource_flags(pdev, 0) & IORESOURCE_IO) {
1911                 *display = pci_resource_start(pdev, 1);
1912                 *registers = pci_resource_start(pdev, 0);
1913         } else {
1914                 *display = pci_resource_start(pdev, 0);
1915                 *registers = pci_resource_start(pdev, 1);
1916         }
1917
1918         assert(*display != 0);
1919 }
1920
1921 static void cirrusfb_pci_unmap(struct fb_info *info)
1922 {
1923         struct pci_dev *pdev = to_pci_dev(info->device);
1924         struct cirrusfb_info *cinfo = info->par;
1925
1926         if (cinfo->laguna_mmio == NULL)
1927                 iounmap(cinfo->laguna_mmio);
1928         iounmap(info->screen_base);
1929 #if 0 /* if system didn't claim this region, we would... */
1930         release_mem_region(0xA0000, 65535);
1931 #endif
1932         if (release_io_ports)
1933                 release_region(0x3C0, 32);
1934         pci_release_regions(pdev);
1935 }
1936 #endif /* CONFIG_PCI */
1937
1938 #ifdef CONFIG_ZORRO
1939 static void cirrusfb_zorro_unmap(struct fb_info *info)
1940 {
1941         struct cirrusfb_info *cinfo = info->par;
1942         struct zorro_dev *zdev = to_zorro_dev(info->device);
1943
1944         zorro_release_device(zdev);
1945
1946         if (cinfo->btype == BT_PICASSO4) {
1947                 cinfo->regbase -= 0x600000;
1948                 iounmap((void *)cinfo->regbase);
1949                 iounmap(info->screen_base);
1950         } else {
1951                 if (zorro_resource_start(zdev) > 0x01000000)
1952                         iounmap(info->screen_base);
1953         }
1954 }
1955 #endif /* CONFIG_ZORRO */
1956
1957 /* function table of the above functions */
1958 static struct fb_ops cirrusfb_ops = {
1959         .owner          = THIS_MODULE,
1960         .fb_open        = cirrusfb_open,
1961         .fb_release     = cirrusfb_release,
1962         .fb_setcolreg   = cirrusfb_setcolreg,
1963         .fb_check_var   = cirrusfb_check_var,
1964         .fb_set_par     = cirrusfb_set_par,
1965         .fb_pan_display = cirrusfb_pan_display,
1966         .fb_blank       = cirrusfb_blank,
1967         .fb_fillrect    = cirrusfb_fillrect,
1968         .fb_copyarea    = cirrusfb_copyarea,
1969         .fb_imageblit   = cirrusfb_imageblit,
1970 };
1971
1972 static int __devinit cirrusfb_set_fbinfo(struct fb_info *info)
1973 {
1974         struct cirrusfb_info *cinfo = info->par;
1975         struct fb_var_screeninfo *var = &info->var;
1976
1977         info->pseudo_palette = cinfo->pseudo_palette;
1978         info->flags = FBINFO_DEFAULT
1979                     | FBINFO_HWACCEL_XPAN
1980                     | FBINFO_HWACCEL_YPAN
1981                     | FBINFO_HWACCEL_FILLRECT
1982                     | FBINFO_HWACCEL_COPYAREA;
1983         if (noaccel || is_laguna(cinfo))
1984                 info->flags |= FBINFO_HWACCEL_DISABLED;
1985         info->fbops = &cirrusfb_ops;
1986         if (cinfo->btype == BT_GD5480) {
1987                 if (var->bits_per_pixel == 16)
1988                         info->screen_base += 1 * MB_;
1989                 if (var->bits_per_pixel == 32)
1990                         info->screen_base += 2 * MB_;
1991         }
1992
1993         /* Fill fix common fields */
1994         strlcpy(info->fix.id, cirrusfb_board_info[cinfo->btype].name,
1995                 sizeof(info->fix.id));
1996
1997         /* monochrome: only 1 memory plane */
1998         /* 8 bit and above: Use whole memory area */
1999         info->fix.smem_len   = info->screen_size;
2000         if (var->bits_per_pixel == 1)
2001                 info->fix.smem_len /= 4;
2002         info->fix.type_aux   = 0;
2003         info->fix.xpanstep   = 1;
2004         info->fix.ypanstep   = 1;
2005         info->fix.ywrapstep  = 0;
2006
2007         /* FIXME: map region at 0xB8000 if available, fill in here */
2008         info->fix.mmio_len   = 0;
2009         info->fix.accel = FB_ACCEL_NONE;
2010
2011         fb_alloc_cmap(&info->cmap, 256, 0);
2012
2013         return 0;
2014 }
2015
2016 static int __devinit cirrusfb_register(struct fb_info *info)
2017 {
2018         struct cirrusfb_info *cinfo = info->par;
2019         int err;
2020
2021         /* sanity checks */
2022         assert(cinfo->btype != BT_NONE);
2023
2024         /* set all the vital stuff */
2025         cirrusfb_set_fbinfo(info);
2026
2027         dev_dbg(info->device, "(RAM start set to: 0x%p)\n", info->screen_base);
2028
2029         err = fb_find_mode(&info->var, info, mode_option, NULL, 0, NULL, 8);
2030         if (!err) {
2031                 dev_dbg(info->device, "wrong initial video mode\n");
2032                 err = -EINVAL;
2033                 goto err_dealloc_cmap;
2034         }
2035
2036         info->var.activate = FB_ACTIVATE_NOW;
2037
2038         err = cirrusfb_check_var(&info->var, info);
2039         if (err < 0) {
2040                 /* should never happen */
2041                 dev_dbg(info->device,
2042                         "choking on default var... umm, no good.\n");
2043                 goto err_dealloc_cmap;
2044         }
2045
2046         err = register_framebuffer(info);
2047         if (err < 0) {
2048                 dev_err(info->device,
2049                         "could not register fb device; err = %d!\n", err);
2050                 goto err_dealloc_cmap;
2051         }
2052
2053         return 0;
2054
2055 err_dealloc_cmap:
2056         fb_dealloc_cmap(&info->cmap);
2057         cinfo->unmap(info);
2058         framebuffer_release(info);
2059         return err;
2060 }
2061
2062 static void __devexit cirrusfb_cleanup(struct fb_info *info)
2063 {
2064         struct cirrusfb_info *cinfo = info->par;
2065
2066         switch_monitor(cinfo, 0);
2067         unregister_framebuffer(info);
2068         fb_dealloc_cmap(&info->cmap);
2069         dev_dbg(info->device, "Framebuffer unregistered\n");
2070         cinfo->unmap(info);
2071         framebuffer_release(info);
2072 }
2073
2074 #ifdef CONFIG_PCI
2075 static int __devinit cirrusfb_pci_register(struct pci_dev *pdev,
2076                                            const struct pci_device_id *ent)
2077 {
2078         struct cirrusfb_info *cinfo;
2079         struct fb_info *info;
2080         unsigned long board_addr, board_size;
2081         int ret;
2082
2083         ret = pci_enable_device(pdev);
2084         if (ret < 0) {
2085                 printk(KERN_ERR "cirrusfb: Cannot enable PCI device\n");
2086                 goto err_out;
2087         }
2088
2089         info = framebuffer_alloc(sizeof(struct cirrusfb_info), &pdev->dev);
2090         if (!info) {
2091                 printk(KERN_ERR "cirrusfb: could not allocate memory\n");
2092                 ret = -ENOMEM;
2093                 goto err_out;
2094         }
2095
2096         cinfo = info->par;
2097         cinfo->btype = (enum cirrus_board) ent->driver_data;
2098
2099         dev_dbg(info->device,
2100                 " Found PCI device, base address 0 is 0x%Lx, btype set to %d\n",
2101                 (unsigned long long)pdev->resource[0].start,  cinfo->btype);
2102         dev_dbg(info->device, " base address 1 is 0x%Lx\n",
2103                 (unsigned long long)pdev->resource[1].start);
2104
2105         if (isPReP) {
2106                 pci_write_config_dword(pdev, PCI_BASE_ADDRESS_0, 0x00000000);
2107 #ifdef CONFIG_PPC_PREP
2108                 get_prep_addrs(&board_addr, &info->fix.mmio_start);
2109 #endif
2110         /* PReP dies if we ioremap the IO registers, but it works w/out... */
2111                 cinfo->regbase = (char __iomem *) info->fix.mmio_start;
2112         } else {
2113                 dev_dbg(info->device,
2114                         "Attempt to get PCI info for Cirrus Graphics Card\n");
2115                 get_pci_addrs(pdev, &board_addr, &info->fix.mmio_start);
2116                 /* FIXME: this forces VGA.  alternatives? */
2117                 cinfo->regbase = NULL;
2118                 cinfo->laguna_mmio = ioremap(info->fix.mmio_start, 0x1000);
2119         }
2120
2121         dev_dbg(info->device, "Board address: 0x%lx, register address: 0x%lx\n",
2122                 board_addr, info->fix.mmio_start);
2123
2124         board_size = (cinfo->btype == BT_GD5480) ?
2125                 32 * MB_ : cirrusfb_get_memsize(info, cinfo->regbase);
2126
2127         ret = pci_request_regions(pdev, "cirrusfb");
2128         if (ret < 0) {
2129                 dev_err(info->device, "cannot reserve region 0x%lx, abort\n",
2130                         board_addr);
2131                 goto err_release_fb;
2132         }
2133 #if 0 /* if the system didn't claim this region, we would... */
2134         if (!request_mem_region(0xA0000, 65535, "cirrusfb")) {
2135                 dev_err(info->device, "cannot reserve region 0x%lx, abort\n",
2136                         0xA0000L);
2137                 ret = -EBUSY;
2138                 goto err_release_regions;
2139         }
2140 #endif
2141         if (request_region(0x3C0, 32, "cirrusfb"))
2142                 release_io_ports = 1;
2143
2144         info->screen_base = ioremap(board_addr, board_size);
2145         if (!info->screen_base) {
2146                 ret = -EIO;
2147                 goto err_release_legacy;
2148         }
2149
2150         info->fix.smem_start = board_addr;
2151         info->screen_size = board_size;
2152         cinfo->unmap = cirrusfb_pci_unmap;
2153
2154         dev_info(info->device,
2155                  "Cirrus Logic chipset on PCI bus, RAM (%lu kB) at 0x%lx\n",
2156                  info->screen_size >> 10, board_addr);
2157         pci_set_drvdata(pdev, info);
2158
2159         ret = cirrusfb_register(info);
2160         if (!ret)
2161                 return 0;
2162
2163         pci_set_drvdata(pdev, NULL);
2164         iounmap(info->screen_base);
2165 err_release_legacy:
2166         if (release_io_ports)
2167                 release_region(0x3C0, 32);
2168 #if 0
2169         release_mem_region(0xA0000, 65535);
2170 err_release_regions:
2171 #endif
2172         pci_release_regions(pdev);
2173 err_release_fb:
2174         if (cinfo->laguna_mmio != NULL)
2175                 iounmap(cinfo->laguna_mmio);
2176         framebuffer_release(info);
2177 err_out:
2178         return ret;
2179 }
2180
2181 static void __devexit cirrusfb_pci_unregister(struct pci_dev *pdev)
2182 {
2183         struct fb_info *info = pci_get_drvdata(pdev);
2184
2185         cirrusfb_cleanup(info);
2186 }
2187
2188 static struct pci_driver cirrusfb_pci_driver = {
2189         .name           = "cirrusfb",
2190         .id_table       = cirrusfb_pci_table,
2191         .probe          = cirrusfb_pci_register,
2192         .remove         = __devexit_p(cirrusfb_pci_unregister),
2193 #ifdef CONFIG_PM
2194 #if 0
2195         .suspend        = cirrusfb_pci_suspend,
2196         .resume         = cirrusfb_pci_resume,
2197 #endif
2198 #endif
2199 };
2200 #endif /* CONFIG_PCI */
2201
2202 #ifdef CONFIG_ZORRO
2203 static int __devinit cirrusfb_zorro_register(struct zorro_dev *z,
2204                                              const struct zorro_device_id *ent)
2205 {
2206         struct cirrusfb_info *cinfo;
2207         struct fb_info *info;
2208         enum cirrus_board btype;
2209         struct zorro_dev *z2 = NULL;
2210         unsigned long board_addr, board_size, size;
2211         int ret;
2212
2213         btype = ent->driver_data;
2214         if (cirrusfb_zorro_table2[btype].id2)
2215                 z2 = zorro_find_device(cirrusfb_zorro_table2[btype].id2, NULL);
2216         size = cirrusfb_zorro_table2[btype].size;
2217
2218         info = framebuffer_alloc(sizeof(struct cirrusfb_info), &z->dev);
2219         if (!info) {
2220                 printk(KERN_ERR "cirrusfb: could not allocate memory\n");
2221                 ret = -ENOMEM;
2222                 goto err_out;
2223         }
2224
2225         dev_info(info->device, "%s board detected\n",
2226                  cirrusfb_board_info[btype].name);
2227
2228         cinfo = info->par;
2229         cinfo->btype = btype;
2230
2231         assert(z);
2232         assert(btype != BT_NONE);
2233
2234         board_addr = zorro_resource_start(z);
2235         board_size = zorro_resource_len(z);
2236         info->screen_size = size;
2237
2238         if (!zorro_request_device(z, "cirrusfb")) {
2239                 dev_err(info->device, "cannot reserve region 0x%lx, abort\n",
2240                         board_addr);
2241                 ret = -EBUSY;
2242                 goto err_release_fb;
2243         }
2244
2245         ret = -EIO;
2246
2247         if (btype == BT_PICASSO4) {
2248                 dev_info(info->device, " REG at $%lx\n", board_addr + 0x600000);
2249
2250                 /* To be precise, for the P4 this is not the */
2251                 /* begin of the board, but the begin of RAM. */
2252                 /* for P4, map in its address space in 2 chunks (### TEST! ) */
2253                 /* (note the ugly hardcoded 16M number) */
2254                 cinfo->regbase = ioremap(board_addr, 16777216);
2255                 if (!cinfo->regbase)
2256                         goto err_release_region;
2257
2258                 dev_dbg(info->device, "Virtual address for board set to: $%p\n",
2259                         cinfo->regbase);
2260                 cinfo->regbase += 0x600000;
2261                 info->fix.mmio_start = board_addr + 0x600000;
2262
2263                 info->fix.smem_start = board_addr + 16777216;
2264                 info->screen_base = ioremap(info->fix.smem_start, 16777216);
2265                 if (!info->screen_base)
2266                         goto err_unmap_regbase;
2267         } else {
2268                 dev_info(info->device, " REG at $%lx\n",
2269                          (unsigned long) z2->resource.start);
2270
2271                 info->fix.smem_start = board_addr;
2272                 if (board_addr > 0x01000000)
2273                         info->screen_base = ioremap(board_addr, board_size);
2274                 else
2275                         info->screen_base = (caddr_t) ZTWO_VADDR(board_addr);
2276                 if (!info->screen_base)
2277                         goto err_release_region;
2278
2279                 /* set address for REG area of board */
2280                 cinfo->regbase = (caddr_t) ZTWO_VADDR(z2->resource.start);
2281                 info->fix.mmio_start = z2->resource.start;
2282
2283                 dev_dbg(info->device, "Virtual address for board set to: $%p\n",
2284                         cinfo->regbase);
2285         }
2286         cinfo->unmap = cirrusfb_zorro_unmap;
2287
2288         dev_info(info->device,
2289                  "Cirrus Logic chipset on Zorro bus, RAM (%lu MB) at $%lx\n",
2290                  board_size / MB_, board_addr);
2291
2292         zorro_set_drvdata(z, info);
2293
2294         ret = cirrusfb_register(info);
2295         if (ret) {
2296                 if (btype == BT_PICASSO4) {
2297                         iounmap(info->screen_base);
2298                         iounmap(cinfo->regbase - 0x600000);
2299                 } else if (board_addr > 0x01000000)
2300                         iounmap(info->screen_base);
2301         }
2302         return ret;
2303
2304 err_unmap_regbase:
2305         /* Parental advisory: explicit hack */
2306         iounmap(cinfo->regbase - 0x600000);
2307 err_release_region:
2308         release_region(board_addr, board_size);
2309 err_release_fb:
2310         framebuffer_release(info);
2311 err_out:
2312         return ret;
2313 }
2314
2315 void __devexit cirrusfb_zorro_unregister(struct zorro_dev *z)
2316 {
2317         struct fb_info *info = zorro_get_drvdata(z);
2318
2319         cirrusfb_cleanup(info);
2320 }
2321
2322 static struct zorro_driver cirrusfb_zorro_driver = {
2323         .name           = "cirrusfb",
2324         .id_table       = cirrusfb_zorro_table,
2325         .probe          = cirrusfb_zorro_register,
2326         .remove         = __devexit_p(cirrusfb_zorro_unregister),
2327 };
2328 #endif /* CONFIG_ZORRO */
2329
2330 #ifndef MODULE
2331 static int __init cirrusfb_setup(char *options)
2332 {
2333         char *this_opt;
2334
2335         if (!options || !*options)
2336                 return 0;
2337
2338         while ((this_opt = strsep(&options, ",")) != NULL) {
2339                 if (!*this_opt)
2340                         continue;
2341
2342                 if (!strcmp(this_opt, "noaccel"))
2343                         noaccel = 1;
2344                 else if (!strncmp(this_opt, "mode:", 5))
2345                         mode_option = this_opt + 5;
2346                 else
2347                         mode_option = this_opt;
2348         }
2349         return 0;
2350 }
2351 #endif
2352
2353     /*
2354      *  Modularization
2355      */
2356
2357 MODULE_AUTHOR("Copyright 1999,2000 Jeff Garzik <jgarzik@pobox.com>");
2358 MODULE_DESCRIPTION("Accelerated FBDev driver for Cirrus Logic chips");
2359 MODULE_LICENSE("GPL");
2360
2361 static int __init cirrusfb_init(void)
2362 {
2363         int error = 0;
2364
2365 #ifndef MODULE
2366         char *option = NULL;
2367
2368         if (fb_get_options("cirrusfb", &option))
2369                 return -ENODEV;
2370         cirrusfb_setup(option);
2371 #endif
2372
2373 #ifdef CONFIG_ZORRO
2374         error |= zorro_register_driver(&cirrusfb_zorro_driver);
2375 #endif
2376 #ifdef CONFIG_PCI
2377         error |= pci_register_driver(&cirrusfb_pci_driver);
2378 #endif
2379         return error;
2380 }
2381
2382 static void __exit cirrusfb_exit(void)
2383 {
2384 #ifdef CONFIG_PCI
2385         pci_unregister_driver(&cirrusfb_pci_driver);
2386 #endif
2387 #ifdef CONFIG_ZORRO
2388         zorro_unregister_driver(&cirrusfb_zorro_driver);
2389 #endif
2390 }
2391
2392 module_init(cirrusfb_init);
2393
2394 module_param(mode_option, charp, 0);
2395 MODULE_PARM_DESC(mode_option, "Initial video mode e.g. '648x480-8@60'");
2396 module_param(noaccel, bool, 0);
2397 MODULE_PARM_DESC(noaccel, "Disable acceleration");
2398
2399 #ifdef MODULE
2400 module_exit(cirrusfb_exit);
2401 #endif
2402
2403 /**********************************************************************/
2404 /* about the following functions - I have used the same names for the */
2405 /* functions as Markus Wild did in his Retina driver for NetBSD as    */
2406 /* they just made sense for this purpose. Apart from that, I wrote    */
2407 /* these functions myself.                                          */
2408 /**********************************************************************/
2409
2410 /*** WGen() - write into one of the external/general registers ***/
2411 static void WGen(const struct cirrusfb_info *cinfo,
2412                   int regnum, unsigned char val)
2413 {
2414         unsigned long regofs = 0;
2415
2416         if (cinfo->btype == BT_PICASSO) {
2417                 /* Picasso II specific hack */
2418 /*            if (regnum == VGA_PEL_IR || regnum == VGA_PEL_D ||
2419                   regnum == CL_VSSM2) */
2420                 if (regnum == VGA_PEL_IR || regnum == VGA_PEL_D)
2421                         regofs = 0xfff;
2422         }
2423
2424         vga_w(cinfo->regbase, regofs + regnum, val);
2425 }
2426
2427 /*** RGen() - read out one of the external/general registers ***/
2428 static unsigned char RGen(const struct cirrusfb_info *cinfo, int regnum)
2429 {
2430         unsigned long regofs = 0;
2431
2432         if (cinfo->btype == BT_PICASSO) {
2433                 /* Picasso II specific hack */
2434 /*            if (regnum == VGA_PEL_IR || regnum == VGA_PEL_D ||
2435                   regnum == CL_VSSM2) */
2436                 if (regnum == VGA_PEL_IR || regnum == VGA_PEL_D)
2437                         regofs = 0xfff;
2438         }
2439
2440         return vga_r(cinfo->regbase, regofs + regnum);
2441 }
2442
2443 /*** AttrOn() - turn on VideoEnable for Attribute controller ***/
2444 static void AttrOn(const struct cirrusfb_info *cinfo)
2445 {
2446         assert(cinfo != NULL);
2447
2448         if (vga_rcrt(cinfo->regbase, CL_CRT24) & 0x80) {
2449                 /* if we're just in "write value" mode, write back the */
2450                 /* same value as before to not modify anything */
2451                 vga_w(cinfo->regbase, VGA_ATT_IW,
2452                       vga_r(cinfo->regbase, VGA_ATT_R));
2453         }
2454         /* turn on video bit */
2455 /*      vga_w(cinfo->regbase, VGA_ATT_IW, 0x20); */
2456         vga_w(cinfo->regbase, VGA_ATT_IW, 0x33);
2457
2458         /* dummy write on Reg0 to be on "write index" mode next time */
2459         vga_w(cinfo->regbase, VGA_ATT_IW, 0x00);
2460 }
2461
2462 /*** WHDR() - write into the Hidden DAC register ***/
2463 /* as the HDR is the only extension register that requires special treatment
2464  * (the other extension registers are accessible just like the "ordinary"
2465  * registers of their functional group) here is a specialized routine for
2466  * accessing the HDR
2467  */
2468 static void WHDR(const struct cirrusfb_info *cinfo, unsigned char val)
2469 {
2470         unsigned char dummy;
2471
2472         if (is_laguna(cinfo))
2473                 return;
2474         if (cinfo->btype == BT_PICASSO) {
2475                 /* Klaus' hint for correct access to HDR on some boards */
2476                 /* first write 0 to pixel mask (3c6) */
2477                 WGen(cinfo, VGA_PEL_MSK, 0x00);
2478                 udelay(200);
2479                 /* next read dummy from pixel address (3c8) */
2480                 dummy = RGen(cinfo, VGA_PEL_IW);
2481                 udelay(200);
2482         }
2483         /* now do the usual stuff to access the HDR */
2484
2485         dummy = RGen(cinfo, VGA_PEL_MSK);
2486         udelay(200);
2487         dummy = RGen(cinfo, VGA_PEL_MSK);
2488         udelay(200);
2489         dummy = RGen(cinfo, VGA_PEL_MSK);
2490         udelay(200);
2491         dummy = RGen(cinfo, VGA_PEL_MSK);
2492         udelay(200);
2493
2494         WGen(cinfo, VGA_PEL_MSK, val);
2495         udelay(200);
2496
2497         if (cinfo->btype == BT_PICASSO) {
2498                 /* now first reset HDR access counter */
2499                 dummy = RGen(cinfo, VGA_PEL_IW);
2500                 udelay(200);
2501
2502                 /* and at the end, restore the mask value */
2503                 /* ## is this mask always 0xff? */
2504                 WGen(cinfo, VGA_PEL_MSK, 0xff);
2505                 udelay(200);
2506         }
2507 }
2508
2509 /*** WSFR() - write to the "special function register" (SFR) ***/
2510 static void WSFR(struct cirrusfb_info *cinfo, unsigned char val)
2511 {
2512 #ifdef CONFIG_ZORRO
2513         assert(cinfo->regbase != NULL);
2514         cinfo->SFR = val;
2515         z_writeb(val, cinfo->regbase + 0x8000);
2516 #endif
2517 }
2518
2519 /* The Picasso has a second register for switching the monitor bit */
2520 static void WSFR2(struct cirrusfb_info *cinfo, unsigned char val)
2521 {
2522 #ifdef CONFIG_ZORRO
2523         /* writing an arbitrary value to this one causes the monitor switcher */
2524         /* to flip to Amiga display */
2525         assert(cinfo->regbase != NULL);
2526         cinfo->SFR = val;
2527         z_writeb(val, cinfo->regbase + 0x9000);
2528 #endif
2529 }
2530
2531 /*** WClut - set CLUT entry (range: 0..63) ***/
2532 static void WClut(struct cirrusfb_info *cinfo, unsigned char regnum, unsigned char red,
2533             unsigned char green, unsigned char blue)
2534 {
2535         unsigned int data = VGA_PEL_D;
2536
2537         /* address write mode register is not translated.. */
2538         vga_w(cinfo->regbase, VGA_PEL_IW, regnum);
2539
2540         if (cinfo->btype == BT_PICASSO || cinfo->btype == BT_PICASSO4 ||
2541             cinfo->btype == BT_ALPINE || cinfo->btype == BT_GD5480 ||
2542             is_laguna(cinfo)) {
2543                 /* but DAC data register IS, at least for Picasso II */
2544                 if (cinfo->btype == BT_PICASSO)
2545                         data += 0xfff;
2546                 vga_w(cinfo->regbase, data, red);
2547                 vga_w(cinfo->regbase, data, green);
2548                 vga_w(cinfo->regbase, data, blue);
2549         } else {
2550                 vga_w(cinfo->regbase, data, blue);
2551                 vga_w(cinfo->regbase, data, green);
2552                 vga_w(cinfo->regbase, data, red);
2553         }
2554 }
2555
2556 #if 0
2557 /*** RClut - read CLUT entry (range 0..63) ***/
2558 static void RClut(struct cirrusfb_info *cinfo, unsigned char regnum, unsigned char *red,
2559             unsigned char *green, unsigned char *blue)
2560 {
2561         unsigned int data = VGA_PEL_D;
2562
2563         vga_w(cinfo->regbase, VGA_PEL_IR, regnum);
2564
2565         if (cinfo->btype == BT_PICASSO || cinfo->btype == BT_PICASSO4 ||
2566             cinfo->btype == BT_ALPINE || cinfo->btype == BT_GD5480) {
2567                 if (cinfo->btype == BT_PICASSO)
2568                         data += 0xfff;
2569                 *red = vga_r(cinfo->regbase, data);
2570                 *green = vga_r(cinfo->regbase, data);
2571                 *blue = vga_r(cinfo->regbase, data);
2572         } else {
2573                 *blue = vga_r(cinfo->regbase, data);
2574                 *green = vga_r(cinfo->regbase, data);
2575                 *red = vga_r(cinfo->regbase, data);
2576         }
2577 }
2578 #endif
2579
2580 /*******************************************************************
2581         cirrusfb_WaitBLT()
2582
2583         Wait for the BitBLT engine to complete a possible earlier job
2584 *********************************************************************/
2585
2586 /* FIXME: use interrupts instead */
2587 static void cirrusfb_WaitBLT(u8 __iomem *regbase)
2588 {
2589         /* now busy-wait until we're done */
2590         while (vga_rgfx(regbase, CL_GR31) & 0x08)
2591                 cpu_relax();
2592 }
2593
2594 /*******************************************************************
2595         cirrusfb_BitBLT()
2596
2597         perform accelerated "scrolling"
2598 ********************************************************************/
2599
2600 static void cirrusfb_BitBLT(u8 __iomem *regbase, int bits_per_pixel,
2601                             u_short curx, u_short cury,
2602                             u_short destx, u_short desty,
2603                             u_short width, u_short height,
2604                             u_short line_length)
2605 {
2606         u_short nwidth, nheight;
2607         u_long nsrc, ndest;
2608         u_char bltmode;
2609
2610         nwidth = width - 1;
2611         nheight = height - 1;
2612
2613         bltmode = 0x00;
2614         /* if source adr < dest addr, do the Blt backwards */
2615         if (cury <= desty) {
2616                 if (cury == desty) {
2617                         /* if src and dest are on the same line, check x */
2618                         if (curx < destx)
2619                                 bltmode |= 0x01;
2620                 } else
2621                         bltmode |= 0x01;
2622         }
2623         if (!bltmode) {
2624                 /* standard case: forward blitting */
2625                 nsrc = (cury * line_length) + curx;
2626                 ndest = (desty * line_length) + destx;
2627         } else {
2628                 /* this means start addresses are at the end,
2629                  * counting backwards
2630                  */
2631                 nsrc = cury * line_length + curx +
2632                         nheight * line_length + nwidth;
2633                 ndest = desty * line_length + destx +
2634                         nheight * line_length + nwidth;
2635         }
2636
2637         /*
2638            run-down of registers to be programmed:
2639            destination pitch
2640            source pitch
2641            BLT width/height
2642            source start
2643            destination start
2644            BLT mode
2645            BLT ROP
2646            VGA_GFX_SR_VALUE / VGA_GFX_SR_ENABLE: "fill color"
2647            start/stop
2648          */
2649
2650         cirrusfb_WaitBLT(regbase);
2651
2652         /* pitch: set to line_length */
2653         /* dest pitch low */
2654         vga_wgfx(regbase, CL_GR24, line_length & 0xff);
2655         /* dest pitch hi */
2656         vga_wgfx(regbase, CL_GR25, line_length >> 8);
2657         /* source pitch low */
2658         vga_wgfx(regbase, CL_GR26, line_length & 0xff);
2659         /* source pitch hi */
2660         vga_wgfx(regbase, CL_GR27, line_length >> 8);
2661
2662         /* BLT width: actual number of pixels - 1 */
2663         /* BLT width low */
2664         vga_wgfx(regbase, CL_GR20, nwidth & 0xff);
2665         /* BLT width hi */
2666         vga_wgfx(regbase, CL_GR21, nwidth >> 8);
2667
2668         /* BLT height: actual number of lines -1 */
2669         /* BLT height low */
2670         vga_wgfx(regbase, CL_GR22, nheight & 0xff);
2671         /* BLT width hi */
2672         vga_wgfx(regbase, CL_GR23, nheight >> 8);
2673
2674         /* BLT destination */
2675         /* BLT dest low */
2676         vga_wgfx(regbase, CL_GR28, (u_char) (ndest & 0xff));
2677         /* BLT dest mid */
2678         vga_wgfx(regbase, CL_GR29, (u_char) (ndest >> 8));
2679         /* BLT dest hi */
2680         vga_wgfx(regbase, CL_GR2A, (u_char) (ndest >> 16));
2681
2682         /* BLT source */
2683         /* BLT src low */
2684         vga_wgfx(regbase, CL_GR2C, (u_char) (nsrc & 0xff));
2685         /* BLT src mid */
2686         vga_wgfx(regbase, CL_GR2D, (u_char) (nsrc >> 8));
2687         /* BLT src hi */
2688         vga_wgfx(regbase, CL_GR2E, (u_char) (nsrc >> 16));
2689
2690         /* BLT mode */
2691         vga_wgfx(regbase, CL_GR30, bltmode);    /* BLT mode */
2692
2693         /* BLT ROP: SrcCopy */
2694         vga_wgfx(regbase, CL_GR32, 0x0d);       /* BLT ROP */
2695
2696         /* and finally: GO! */
2697         vga_wgfx(regbase, CL_GR31, 0x02);       /* BLT Start/status */
2698 }
2699
2700 /*******************************************************************
2701         cirrusfb_RectFill()
2702
2703         perform accelerated rectangle fill
2704 ********************************************************************/
2705
2706 static void cirrusfb_RectFill(u8 __iomem *regbase, int bits_per_pixel,
2707                      u_short x, u_short y, u_short width, u_short height,
2708                      u_char color, u_short line_length)
2709 {
2710         u_short nwidth, nheight;
2711         u_long ndest;
2712         u_char op;
2713
2714         nwidth = width - 1;
2715         nheight = height - 1;
2716
2717         ndest = (y * line_length) + x;
2718
2719         cirrusfb_WaitBLT(regbase);
2720
2721         /* pitch: set to line_length */
2722         vga_wgfx(regbase, CL_GR24, line_length & 0xff); /* dest pitch low */
2723         vga_wgfx(regbase, CL_GR25, line_length >> 8);   /* dest pitch hi */
2724         vga_wgfx(regbase, CL_GR26, line_length & 0xff); /* source pitch low */
2725         vga_wgfx(regbase, CL_GR27, line_length >> 8);   /* source pitch hi */
2726
2727         /* BLT width: actual number of pixels - 1 */
2728         vga_wgfx(regbase, CL_GR20, nwidth & 0xff);      /* BLT width low */
2729         vga_wgfx(regbase, CL_GR21, nwidth >> 8);        /* BLT width hi */
2730
2731         /* BLT height: actual number of lines -1 */
2732         vga_wgfx(regbase, CL_GR22, nheight & 0xff);     /* BLT height low */
2733         vga_wgfx(regbase, CL_GR23, nheight >> 8);       /* BLT width hi */
2734
2735         /* BLT destination */
2736         /* BLT dest low */
2737         vga_wgfx(regbase, CL_GR28, (u_char) (ndest & 0xff));
2738         /* BLT dest mid */
2739         vga_wgfx(regbase, CL_GR29, (u_char) (ndest >> 8));
2740         /* BLT dest hi */
2741         vga_wgfx(regbase, CL_GR2A, (u_char) (ndest >> 16));
2742
2743         /* BLT source: set to 0 (is a dummy here anyway) */
2744         vga_wgfx(regbase, CL_GR2C, 0x00);       /* BLT src low */
2745         vga_wgfx(regbase, CL_GR2D, 0x00);       /* BLT src mid */
2746         vga_wgfx(regbase, CL_GR2E, 0x00);       /* BLT src hi */
2747
2748         /* This is a ColorExpand Blt, using the */
2749         /* same color for foreground and background */
2750         vga_wgfx(regbase, VGA_GFX_SR_VALUE, color);     /* foreground color */
2751         vga_wgfx(regbase, VGA_GFX_SR_ENABLE, color);    /* background color */
2752
2753         op = 0xc0;
2754         if (bits_per_pixel == 16) {
2755                 vga_wgfx(regbase, CL_GR10, color);      /* foreground color */
2756                 vga_wgfx(regbase, CL_GR11, color);      /* background color */
2757                 op = 0x50;
2758                 op = 0xd0;
2759         } else if (bits_per_pixel == 32) {
2760                 vga_wgfx(regbase, CL_GR10, color);      /* foreground color */
2761                 vga_wgfx(regbase, CL_GR11, color);      /* background color */
2762                 vga_wgfx(regbase, CL_GR12, color);      /* foreground color */
2763                 vga_wgfx(regbase, CL_GR13, color);      /* background color */
2764                 vga_wgfx(regbase, CL_GR14, 0);  /* foreground color */
2765                 vga_wgfx(regbase, CL_GR15, 0);  /* background color */
2766                 op = 0x50;
2767                 op = 0xf0;
2768         }
2769         /* BLT mode: color expand, Enable 8x8 copy (faster?) */
2770         vga_wgfx(regbase, CL_GR30, op); /* BLT mode */
2771
2772         /* BLT ROP: SrcCopy */
2773         vga_wgfx(regbase, CL_GR32, 0x0d);       /* BLT ROP */
2774
2775         /* and finally: GO! */
2776         vga_wgfx(regbase, CL_GR31, 0x02);       /* BLT Start/status */
2777 }
2778
2779 /**************************************************************************
2780  * bestclock() - determine closest possible clock lower(?) than the
2781  * desired pixel clock
2782  **************************************************************************/
2783 static void bestclock(long freq, int *nom, int *den, int *div)
2784 {
2785         int n, d;
2786         long h, diff;
2787
2788         assert(nom != NULL);
2789         assert(den != NULL);
2790         assert(div != NULL);
2791
2792         *nom = 0;
2793         *den = 0;
2794         *div = 0;
2795
2796         if (freq < 8000)
2797                 freq = 8000;
2798
2799         diff = freq;
2800
2801         for (n = 32; n < 128; n++) {
2802                 int s = 0;
2803
2804                 d = (14318 * n) / freq;
2805                 if ((d >= 7) && (d <= 63)) {
2806                         int temp = d;
2807
2808                         if (temp > 31) {
2809                                 s = 1;
2810                                 temp >>= 1;
2811                         }
2812                         h = ((14318 * n) / temp) >> s;
2813                         h = h > freq ? h - freq : freq - h;
2814                         if (h < diff) {
2815                                 diff = h;
2816                                 *nom = n;
2817                                 *den = temp;
2818                                 *div = s;
2819                         }
2820                 }
2821                 d++;
2822                 if ((d >= 7) && (d <= 63)) {
2823                         if (d > 31) {
2824                                 s = 1;
2825                                 d >>= 1;
2826                         }
2827                         h = ((14318 * n) / d) >> s;
2828                         h = h > freq ? h - freq : freq - h;
2829                         if (h < diff) {
2830                                 diff = h;
2831                                 *nom = n;
2832                                 *den = d;
2833                                 *div = s;
2834                         }
2835                 }
2836         }
2837 }
2838
2839 /* -------------------------------------------------------------------------
2840  *
2841  * debugging functions
2842  *
2843  * -------------------------------------------------------------------------
2844  */
2845
2846 #ifdef CIRRUSFB_DEBUG
2847
2848 /**
2849  * cirrusfb_dbg_print_regs
2850  * @base: If using newmmio, the newmmio base address, otherwise %NULL
2851  * @reg_class: type of registers to read: %CRT, or %SEQ
2852  *
2853  * DESCRIPTION:
2854  * Dumps the given list of VGA CRTC registers.  If @base is %NULL,
2855  * old-style I/O ports are queried for information, otherwise MMIO is
2856  * used at the given @base address to query the information.
2857  */
2858
2859 static void cirrusfb_dbg_print_regs(struct fb_info *info,
2860                                     caddr_t regbase,
2861                                     enum cirrusfb_dbg_reg_class reg_class, ...)
2862 {
2863         va_list list;
2864         unsigned char val = 0;
2865         unsigned reg;
2866         char *name;
2867
2868         va_start(list, reg_class);
2869
2870         name = va_arg(list, char *);
2871         while (name != NULL) {
2872                 reg = va_arg(list, int);
2873
2874                 switch (reg_class) {
2875                 case CRT:
2876                         val = vga_rcrt(regbase, (unsigned char) reg);
2877                         break;
2878                 case SEQ:
2879                         val = vga_rseq(regbase, (unsigned char) reg);
2880                         break;
2881                 default:
2882                         /* should never occur */
2883                         assert(false);
2884                         break;
2885                 }
2886
2887                 dev_dbg(info->device, "%8s = 0x%02X\n", name, val);
2888
2889                 name = va_arg(list, char *);
2890         }
2891
2892         va_end(list);
2893 }
2894
2895 /**
2896  * cirrusfb_dbg_reg_dump
2897  * @base: If using newmmio, the newmmio base address, otherwise %NULL
2898  *
2899  * DESCRIPTION:
2900  * Dumps a list of interesting VGA and CIRRUSFB registers.  If @base is %NULL,
2901  * old-style I/O ports are queried for information, otherwise MMIO is
2902  * used at the given @base address to query the information.
2903  */
2904
2905 static void cirrusfb_dbg_reg_dump(struct fb_info *info, caddr_t regbase)
2906 {
2907         dev_dbg(info->device, "VGA CRTC register dump:\n");
2908
2909         cirrusfb_dbg_print_regs(info, regbase, CRT,
2910                            "CR00", 0x00,
2911                            "CR01", 0x01,
2912                            "CR02", 0x02,
2913                            "CR03", 0x03,
2914                            "CR04", 0x04,
2915                            "CR05", 0x05,
2916                            "CR06", 0x06,
2917                            "CR07", 0x07,
2918                            "CR08", 0x08,
2919                            "CR09", 0x09,
2920                            "CR0A", 0x0A,
2921                            "CR0B", 0x0B,
2922                            "CR0C", 0x0C,
2923                            "CR0D", 0x0D,
2924                            "CR0E", 0x0E,
2925                            "CR0F", 0x0F,
2926                            "CR10", 0x10,
2927                            "CR11", 0x11,
2928                            "CR12", 0x12,
2929                            "CR13", 0x13,
2930                            "CR14", 0x14,
2931                            "CR15", 0x15,
2932                            "CR16", 0x16,
2933                            "CR17", 0x17,
2934                            "CR18", 0x18,
2935                            "CR22", 0x22,
2936                            "CR24", 0x24,
2937                            "CR26", 0x26,
2938                            "CR2D", 0x2D,
2939                            "CR2E", 0x2E,
2940                            "CR2F", 0x2F,
2941                            "CR30", 0x30,
2942                            "CR31", 0x31,
2943                            "CR32", 0x32,
2944                            "CR33", 0x33,
2945                            "CR34", 0x34,
2946                            "CR35", 0x35,
2947                            "CR36", 0x36,
2948                            "CR37", 0x37,
2949                            "CR38", 0x38,
2950                            "CR39", 0x39,
2951                            "CR3A", 0x3A,
2952                            "CR3B", 0x3B,
2953                            "CR3C", 0x3C,
2954                            "CR3D", 0x3D,
2955                            "CR3E", 0x3E,
2956                            "CR3F", 0x3F,
2957                            NULL);
2958
2959         dev_dbg(info->device, "\n");
2960
2961         dev_dbg(info->device, "VGA SEQ register dump:\n");
2962
2963         cirrusfb_dbg_print_regs(info, regbase, SEQ,
2964                            "SR00", 0x00,
2965                            "SR01", 0x01,
2966                            "SR02", 0x02,
2967                            "SR03", 0x03,
2968                            "SR04", 0x04,
2969                            "SR08", 0x08,
2970                            "SR09", 0x09,
2971                            "SR0A", 0x0A,
2972                            "SR0B", 0x0B,
2973                            "SR0D", 0x0D,
2974                            "SR10", 0x10,
2975                            "SR11", 0x11,
2976                            "SR12", 0x12,
2977                            "SR13", 0x13,
2978                            "SR14", 0x14,
2979                            "SR15", 0x15,
2980                            "SR16", 0x16,
2981                            "SR17", 0x17,
2982                            "SR18", 0x18,
2983                            "SR19", 0x19,
2984                            "SR1A", 0x1A,
2985                            "SR1B", 0x1B,
2986                            "SR1C", 0x1C,
2987                            "SR1D", 0x1D,
2988                            "SR1E", 0x1E,
2989                            "SR1F", 0x1F,
2990                            NULL);
2991
2992         dev_dbg(info->device, "\n");
2993 }
2994
2995 #endif                          /* CIRRUSFB_DEBUG */
2996