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