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