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