]> git.kernelconcepts.de Git - karo-tx-linux.git/blob - drivers/video/cirrusfb.c
Merge remote-tracking branch 'idle/next'
[karo-tx-linux.git] / drivers / video / cirrusfb.c
1 /*
2  * drivers/video/cirrusfb.c - driver for Cirrus Logic chipsets
3  *
4  * Copyright 1999-2001 Jeff Garzik <jgarzik@pobox.com>
5  *
6  * Contributors (thanks, all!)
7  *
8  *      David Eger:
9  *      Overhaul for Linux 2.6
10  *
11  *      Jeff Rugen:
12  *      Major contributions;  Motorola PowerStack (PPC and PCI) support,
13  *      GD54xx, 1280x1024 mode support, change MCLK based on VCLK.
14  *
15  *      Geert Uytterhoeven:
16  *      Excellent code review.
17  *
18  *      Lars Hecking:
19  *      Amiga updates and testing.
20  *
21  * Original cirrusfb author:  Frank Neumann
22  *
23  * Based on retz3fb.c and cirrusfb.c:
24  *      Copyright (C) 1997 Jes Sorensen
25  *      Copyright (C) 1996 Frank Neumann
26  *
27  ***************************************************************
28  *
29  * Format this code with GNU indent '-kr -i8 -pcs' options.
30  *
31  * This file is subject to the terms and conditions of the GNU General Public
32  * License.  See the file COPYING in the main directory of this archive
33  * for more details.
34  *
35  */
36
37 #include <linux/module.h>
38 #include <linux/kernel.h>
39 #include <linux/errno.h>
40 #include <linux/string.h>
41 #include <linux/mm.h>
42 #include <linux/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         pci_set_drvdata(pdev, NULL);
2163         iounmap(info->screen_base);
2164 err_release_legacy:
2165         if (release_io_ports)
2166                 release_region(0x3C0, 32);
2167 #if 0
2168         release_mem_region(0xA0000, 65535);
2169 err_release_regions:
2170 #endif
2171         pci_release_regions(pdev);
2172 err_release_fb:
2173         if (cinfo->laguna_mmio != NULL)
2174                 iounmap(cinfo->laguna_mmio);
2175         framebuffer_release(info);
2176 err_out:
2177         return ret;
2178 }
2179
2180 static void cirrusfb_pci_unregister(struct pci_dev *pdev)
2181 {
2182         struct fb_info *info = pci_get_drvdata(pdev);
2183
2184         cirrusfb_cleanup(info);
2185 }
2186
2187 static struct pci_driver cirrusfb_pci_driver = {
2188         .name           = "cirrusfb",
2189         .id_table       = cirrusfb_pci_table,
2190         .probe          = cirrusfb_pci_register,
2191         .remove         = cirrusfb_pci_unregister,
2192 #ifdef CONFIG_PM
2193 #if 0
2194         .suspend        = cirrusfb_pci_suspend,
2195         .resume         = cirrusfb_pci_resume,
2196 #endif
2197 #endif
2198 };
2199 #endif /* CONFIG_PCI */
2200
2201 #ifdef CONFIG_ZORRO
2202 static int cirrusfb_zorro_register(struct zorro_dev *z,
2203                                    const struct zorro_device_id *ent)
2204 {
2205         struct fb_info *info;
2206         int error;
2207         const struct zorrocl *zcl;
2208         enum cirrus_board btype;
2209         unsigned long regbase, ramsize, rambase;
2210         struct cirrusfb_info *cinfo;
2211
2212         info = framebuffer_alloc(sizeof(struct cirrusfb_info), &z->dev);
2213         if (!info) {
2214                 printk(KERN_ERR "cirrusfb: could not allocate memory\n");
2215                 return -ENOMEM;
2216         }
2217
2218         zcl = (const struct zorrocl *)ent->driver_data;
2219         btype = zcl->type;
2220         regbase = zorro_resource_start(z) + zcl->regoffset;
2221         ramsize = zcl->ramsize;
2222         if (ramsize) {
2223                 rambase = zorro_resource_start(z) + zcl->ramoffset;
2224                 if (zorro_resource_len(z) == 64 * MB_) {
2225                         /* Quirk for 64 MiB Picasso IV */
2226                         rambase += zcl->ramoffset;
2227                 }
2228         } else {
2229                 struct zorro_dev *ram = zorro_find_device(zcl->ramid, NULL);
2230                 if (!ram || !zorro_resource_len(ram)) {
2231                         dev_err(info->device, "No video RAM found\n");
2232                         error = -ENODEV;
2233                         goto err_release_fb;
2234                 }
2235                 rambase = zorro_resource_start(ram);
2236                 ramsize = zorro_resource_len(ram);
2237                 if (zcl->ramid2 &&
2238                     (ram = zorro_find_device(zcl->ramid2, NULL))) {
2239                         if (zorro_resource_start(ram) != rambase + ramsize) {
2240                                 dev_warn(info->device,
2241                                          "Skipping non-contiguous RAM at %pR\n",
2242                                          &ram->resource);
2243                         } else {
2244                                 ramsize += zorro_resource_len(ram);
2245                         }
2246                 }
2247         }
2248
2249         dev_info(info->device,
2250                  "%s board detected, REG at 0x%lx, %lu MiB RAM at 0x%lx\n",
2251                  cirrusfb_board_info[btype].name, regbase, ramsize / MB_,
2252                  rambase);
2253
2254         if (!zorro_request_device(z, "cirrusfb")) {
2255                 dev_err(info->device, "Cannot reserve %pR\n", &z->resource);
2256                 error = -EBUSY;
2257                 goto err_release_fb;
2258         }
2259
2260         cinfo = info->par;
2261         cinfo->btype = btype;
2262
2263         info->fix.mmio_start = regbase;
2264         cinfo->regbase = regbase > 16 * MB_ ? ioremap(regbase, 64 * 1024)
2265                                             : (caddr_t)ZTWO_VADDR(regbase);
2266         if (!cinfo->regbase) {
2267                 dev_err(info->device, "Cannot map registers\n");
2268                 error = -EIO;
2269                 goto err_release_dev;
2270         }
2271
2272         info->fix.smem_start = rambase;
2273         info->screen_size = ramsize;
2274         info->screen_base = rambase > 16 * MB_ ? ioremap(rambase, ramsize)
2275                                                : (caddr_t)ZTWO_VADDR(rambase);
2276         if (!info->screen_base) {
2277                 dev_err(info->device, "Cannot map video RAM\n");
2278                 error = -EIO;
2279                 goto err_unmap_reg;
2280         }
2281
2282         cinfo->unmap = cirrusfb_zorro_unmap;
2283
2284         dev_info(info->device,
2285                  "Cirrus Logic chipset on Zorro bus, RAM (%lu MiB) at 0x%lx\n",
2286                  ramsize / MB_, rambase);
2287
2288         /* MCLK select etc. */
2289         if (cirrusfb_board_info[btype].init_sr1f)
2290                 vga_wseq(cinfo->regbase, CL_SEQR1F,
2291                          cirrusfb_board_info[btype].sr1f);
2292
2293         error = cirrusfb_register(info);
2294         if (error) {
2295                 dev_err(info->device, "Failed to register device, error %d\n",
2296                         error);
2297                 goto err_unmap_ram;
2298         }
2299
2300         zorro_set_drvdata(z, info);
2301         return 0;
2302
2303 err_unmap_ram:
2304         if (rambase > 16 * MB_)
2305                 iounmap(info->screen_base);
2306
2307 err_unmap_reg:
2308         if (regbase > 16 * MB_)
2309                 iounmap(cinfo->regbase);
2310 err_release_dev:
2311         zorro_release_device(z);
2312 err_release_fb:
2313         framebuffer_release(info);
2314         return error;
2315 }
2316
2317 void cirrusfb_zorro_unregister(struct zorro_dev *z)
2318 {
2319         struct fb_info *info = zorro_get_drvdata(z);
2320
2321         cirrusfb_cleanup(info);
2322         zorro_set_drvdata(z, NULL);
2323 }
2324
2325 static struct zorro_driver cirrusfb_zorro_driver = {
2326         .name           = "cirrusfb",
2327         .id_table       = cirrusfb_zorro_table,
2328         .probe          = cirrusfb_zorro_register,
2329         .remove         = cirrusfb_zorro_unregister,
2330 };
2331 #endif /* CONFIG_ZORRO */
2332
2333 #ifndef MODULE
2334 static int __init cirrusfb_setup(char *options)
2335 {
2336         char *this_opt;
2337
2338         if (!options || !*options)
2339                 return 0;
2340
2341         while ((this_opt = strsep(&options, ",")) != NULL) {
2342                 if (!*this_opt)
2343                         continue;
2344
2345                 if (!strcmp(this_opt, "noaccel"))
2346                         noaccel = 1;
2347                 else if (!strncmp(this_opt, "mode:", 5))
2348                         mode_option = this_opt + 5;
2349                 else
2350                         mode_option = this_opt;
2351         }
2352         return 0;
2353 }
2354 #endif
2355
2356     /*
2357      *  Modularization
2358      */
2359
2360 MODULE_AUTHOR("Copyright 1999,2000 Jeff Garzik <jgarzik@pobox.com>");
2361 MODULE_DESCRIPTION("Accelerated FBDev driver for Cirrus Logic chips");
2362 MODULE_LICENSE("GPL");
2363
2364 static int __init cirrusfb_init(void)
2365 {
2366         int error = 0;
2367
2368 #ifndef MODULE
2369         char *option = NULL;
2370
2371         if (fb_get_options("cirrusfb", &option))
2372                 return -ENODEV;
2373         cirrusfb_setup(option);
2374 #endif
2375
2376 #ifdef CONFIG_ZORRO
2377         error |= zorro_register_driver(&cirrusfb_zorro_driver);
2378 #endif
2379 #ifdef CONFIG_PCI
2380         error |= pci_register_driver(&cirrusfb_pci_driver);
2381 #endif
2382         return error;
2383 }
2384
2385 static void __exit cirrusfb_exit(void)
2386 {
2387 #ifdef CONFIG_PCI
2388         pci_unregister_driver(&cirrusfb_pci_driver);
2389 #endif
2390 #ifdef CONFIG_ZORRO
2391         zorro_unregister_driver(&cirrusfb_zorro_driver);
2392 #endif
2393 }
2394
2395 module_init(cirrusfb_init);
2396
2397 module_param(mode_option, charp, 0);
2398 MODULE_PARM_DESC(mode_option, "Initial video mode e.g. '648x480-8@60'");
2399 module_param(noaccel, bool, 0);
2400 MODULE_PARM_DESC(noaccel, "Disable acceleration");
2401
2402 #ifdef MODULE
2403 module_exit(cirrusfb_exit);
2404 #endif
2405
2406 /**********************************************************************/
2407 /* about the following functions - I have used the same names for the */
2408 /* functions as Markus Wild did in his Retina driver for NetBSD as    */
2409 /* they just made sense for this purpose. Apart from that, I wrote    */
2410 /* these functions myself.                                          */
2411 /**********************************************************************/
2412
2413 /*** WGen() - write into one of the external/general registers ***/
2414 static void WGen(const struct cirrusfb_info *cinfo,
2415                   int regnum, unsigned char val)
2416 {
2417         unsigned long regofs = 0;
2418
2419         if (cinfo->btype == BT_PICASSO) {
2420                 /* Picasso II specific hack */
2421 /*            if (regnum == VGA_PEL_IR || regnum == VGA_PEL_D ||
2422                   regnum == CL_VSSM2) */
2423                 if (regnum == VGA_PEL_IR || regnum == VGA_PEL_D)
2424                         regofs = 0xfff;
2425         }
2426
2427         vga_w(cinfo->regbase, regofs + regnum, val);
2428 }
2429
2430 /*** RGen() - read out one of the external/general registers ***/
2431 static unsigned char RGen(const struct cirrusfb_info *cinfo, int regnum)
2432 {
2433         unsigned long regofs = 0;
2434
2435         if (cinfo->btype == BT_PICASSO) {
2436                 /* Picasso II specific hack */
2437 /*            if (regnum == VGA_PEL_IR || regnum == VGA_PEL_D ||
2438                   regnum == CL_VSSM2) */
2439                 if (regnum == VGA_PEL_IR || regnum == VGA_PEL_D)
2440                         regofs = 0xfff;
2441         }
2442
2443         return vga_r(cinfo->regbase, regofs + regnum);
2444 }
2445
2446 /*** AttrOn() - turn on VideoEnable for Attribute controller ***/
2447 static void AttrOn(const struct cirrusfb_info *cinfo)
2448 {
2449         assert(cinfo != NULL);
2450
2451         if (vga_rcrt(cinfo->regbase, CL_CRT24) & 0x80) {
2452                 /* if we're just in "write value" mode, write back the */
2453                 /* same value as before to not modify anything */
2454                 vga_w(cinfo->regbase, VGA_ATT_IW,
2455                       vga_r(cinfo->regbase, VGA_ATT_R));
2456         }
2457         /* turn on video bit */
2458 /*      vga_w(cinfo->regbase, VGA_ATT_IW, 0x20); */
2459         vga_w(cinfo->regbase, VGA_ATT_IW, 0x33);
2460
2461         /* dummy write on Reg0 to be on "write index" mode next time */
2462         vga_w(cinfo->regbase, VGA_ATT_IW, 0x00);
2463 }
2464
2465 /*** WHDR() - write into the Hidden DAC register ***/
2466 /* as the HDR is the only extension register that requires special treatment
2467  * (the other extension registers are accessible just like the "ordinary"
2468  * registers of their functional group) here is a specialized routine for
2469  * accessing the HDR
2470  */
2471 static void WHDR(const struct cirrusfb_info *cinfo, unsigned char val)
2472 {
2473         unsigned char dummy;
2474
2475         if (is_laguna(cinfo))
2476                 return;
2477         if (cinfo->btype == BT_PICASSO) {
2478                 /* Klaus' hint for correct access to HDR on some boards */
2479                 /* first write 0 to pixel mask (3c6) */
2480                 WGen(cinfo, VGA_PEL_MSK, 0x00);
2481                 udelay(200);
2482                 /* next read dummy from pixel address (3c8) */
2483                 dummy = RGen(cinfo, VGA_PEL_IW);
2484                 udelay(200);
2485         }
2486         /* now do the usual stuff to access the HDR */
2487
2488         dummy = RGen(cinfo, VGA_PEL_MSK);
2489         udelay(200);
2490         dummy = RGen(cinfo, VGA_PEL_MSK);
2491         udelay(200);
2492         dummy = RGen(cinfo, VGA_PEL_MSK);
2493         udelay(200);
2494         dummy = RGen(cinfo, VGA_PEL_MSK);
2495         udelay(200);
2496
2497         WGen(cinfo, VGA_PEL_MSK, val);
2498         udelay(200);
2499
2500         if (cinfo->btype == BT_PICASSO) {
2501                 /* now first reset HDR access counter */
2502                 dummy = RGen(cinfo, VGA_PEL_IW);
2503                 udelay(200);
2504
2505                 /* and at the end, restore the mask value */
2506                 /* ## is this mask always 0xff? */
2507                 WGen(cinfo, VGA_PEL_MSK, 0xff);
2508                 udelay(200);
2509         }
2510 }
2511
2512 /*** WSFR() - write to the "special function register" (SFR) ***/
2513 static void WSFR(struct cirrusfb_info *cinfo, unsigned char val)
2514 {
2515 #ifdef CONFIG_ZORRO
2516         assert(cinfo->regbase != NULL);
2517         cinfo->SFR = val;
2518         z_writeb(val, cinfo->regbase + 0x8000);
2519 #endif
2520 }
2521
2522 /* The Picasso has a second register for switching the monitor bit */
2523 static void WSFR2(struct cirrusfb_info *cinfo, unsigned char val)
2524 {
2525 #ifdef CONFIG_ZORRO
2526         /* writing an arbitrary value to this one causes the monitor switcher */
2527         /* to flip to Amiga display */
2528         assert(cinfo->regbase != NULL);
2529         cinfo->SFR = val;
2530         z_writeb(val, cinfo->regbase + 0x9000);
2531 #endif
2532 }
2533
2534 /*** WClut - set CLUT entry (range: 0..63) ***/
2535 static void WClut(struct cirrusfb_info *cinfo, unsigned char regnum, unsigned char red,
2536             unsigned char green, unsigned char blue)
2537 {
2538         unsigned int data = VGA_PEL_D;
2539
2540         /* address write mode register is not translated.. */
2541         vga_w(cinfo->regbase, VGA_PEL_IW, regnum);
2542
2543         if (cinfo->btype == BT_PICASSO || cinfo->btype == BT_PICASSO4 ||
2544             cinfo->btype == BT_ALPINE || cinfo->btype == BT_GD5480 ||
2545             cinfo->btype == BT_SD64 || is_laguna(cinfo)) {
2546                 /* but DAC data register IS, at least for Picasso II */
2547                 if (cinfo->btype == BT_PICASSO)
2548                         data += 0xfff;
2549                 vga_w(cinfo->regbase, data, red);
2550                 vga_w(cinfo->regbase, data, green);
2551                 vga_w(cinfo->regbase, data, blue);
2552         } else {
2553                 vga_w(cinfo->regbase, data, blue);
2554                 vga_w(cinfo->regbase, data, green);
2555                 vga_w(cinfo->regbase, data, red);
2556         }
2557 }
2558
2559 #if 0
2560 /*** RClut - read CLUT entry (range 0..63) ***/
2561 static void RClut(struct cirrusfb_info *cinfo, unsigned char regnum, unsigned char *red,
2562             unsigned char *green, unsigned char *blue)
2563 {
2564         unsigned int data = VGA_PEL_D;
2565
2566         vga_w(cinfo->regbase, VGA_PEL_IR, regnum);
2567
2568         if (cinfo->btype == BT_PICASSO || cinfo->btype == BT_PICASSO4 ||
2569             cinfo->btype == BT_ALPINE || cinfo->btype == BT_GD5480) {
2570                 if (cinfo->btype == BT_PICASSO)
2571                         data += 0xfff;
2572                 *red = vga_r(cinfo->regbase, data);
2573                 *green = vga_r(cinfo->regbase, data);
2574                 *blue = vga_r(cinfo->regbase, data);
2575         } else {
2576                 *blue = vga_r(cinfo->regbase, data);
2577                 *green = vga_r(cinfo->regbase, data);
2578                 *red = vga_r(cinfo->regbase, data);
2579         }
2580 }
2581 #endif
2582
2583 /*******************************************************************
2584         cirrusfb_WaitBLT()
2585
2586         Wait for the BitBLT engine to complete a possible earlier job
2587 *********************************************************************/
2588
2589 /* FIXME: use interrupts instead */
2590 static void cirrusfb_WaitBLT(u8 __iomem *regbase)
2591 {
2592         while (vga_rgfx(regbase, CL_GR31) & 0x08)
2593                 cpu_relax();
2594 }
2595
2596 /*******************************************************************
2597         cirrusfb_BitBLT()
2598
2599         perform accelerated "scrolling"
2600 ********************************************************************/
2601
2602 static void cirrusfb_set_blitter(u8 __iomem *regbase,
2603                             u_short nwidth, u_short nheight,
2604                             u_long nsrc, u_long ndest,
2605                             u_short bltmode, u_short line_length)
2606
2607 {
2608         /* pitch: set to line_length */
2609         /* dest pitch low */
2610         vga_wgfx(regbase, CL_GR24, line_length & 0xff);
2611         /* dest pitch hi */
2612         vga_wgfx(regbase, CL_GR25, line_length >> 8);
2613         /* source pitch low */
2614         vga_wgfx(regbase, CL_GR26, line_length & 0xff);
2615         /* source pitch hi */
2616         vga_wgfx(regbase, CL_GR27, line_length >> 8);
2617
2618         /* BLT width: actual number of pixels - 1 */
2619         /* BLT width low */
2620         vga_wgfx(regbase, CL_GR20, nwidth & 0xff);
2621         /* BLT width hi */
2622         vga_wgfx(regbase, CL_GR21, nwidth >> 8);
2623
2624         /* BLT height: actual number of lines -1 */
2625         /* BLT height low */
2626         vga_wgfx(regbase, CL_GR22, nheight & 0xff);
2627         /* BLT width hi */
2628         vga_wgfx(regbase, CL_GR23, nheight >> 8);
2629
2630         /* BLT destination */
2631         /* BLT dest low */
2632         vga_wgfx(regbase, CL_GR28, (u_char) (ndest & 0xff));
2633         /* BLT dest mid */
2634         vga_wgfx(regbase, CL_GR29, (u_char) (ndest >> 8));
2635         /* BLT dest hi */
2636         vga_wgfx(regbase, CL_GR2A, (u_char) (ndest >> 16));
2637
2638         /* BLT source */
2639         /* BLT src low */
2640         vga_wgfx(regbase, CL_GR2C, (u_char) (nsrc & 0xff));
2641         /* BLT src mid */
2642         vga_wgfx(regbase, CL_GR2D, (u_char) (nsrc >> 8));
2643         /* BLT src hi */
2644         vga_wgfx(regbase, CL_GR2E, (u_char) (nsrc >> 16));
2645
2646         /* BLT mode */
2647         vga_wgfx(regbase, CL_GR30, bltmode);    /* BLT mode */
2648
2649         /* BLT ROP: SrcCopy */
2650         vga_wgfx(regbase, CL_GR32, 0x0d);       /* BLT ROP */
2651
2652         /* and finally: GO! */
2653         vga_wgfx(regbase, CL_GR31, 0x02);       /* BLT Start/status */
2654 }
2655
2656 /*******************************************************************
2657         cirrusfb_BitBLT()
2658
2659         perform accelerated "scrolling"
2660 ********************************************************************/
2661
2662 static void cirrusfb_BitBLT(u8 __iomem *regbase, int bits_per_pixel,
2663                             u_short curx, u_short cury,
2664                             u_short destx, u_short desty,
2665                             u_short width, u_short height,
2666                             u_short line_length)
2667 {
2668         u_short nwidth = width - 1;
2669         u_short nheight = height - 1;
2670         u_long nsrc, ndest;
2671         u_char bltmode;
2672
2673         bltmode = 0x00;
2674         /* if source adr < dest addr, do the Blt backwards */
2675         if (cury <= desty) {
2676                 if (cury == desty) {
2677                         /* if src and dest are on the same line, check x */
2678                         if (curx < destx)
2679                                 bltmode |= 0x01;
2680                 } else
2681                         bltmode |= 0x01;
2682         }
2683         /* standard case: forward blitting */
2684         nsrc = (cury * line_length) + curx;
2685         ndest = (desty * line_length) + destx;
2686         if (bltmode) {
2687                 /* this means start addresses are at the end,
2688                  * counting backwards
2689                  */
2690                 nsrc += nheight * line_length + nwidth;
2691                 ndest += nheight * line_length + nwidth;
2692         }
2693
2694         cirrusfb_WaitBLT(regbase);
2695
2696         cirrusfb_set_blitter(regbase, nwidth, nheight,
2697                             nsrc, ndest, bltmode, line_length);
2698 }
2699
2700 /*******************************************************************
2701         cirrusfb_RectFill()
2702
2703         perform accelerated rectangle fill
2704 ********************************************************************/
2705
2706 static void cirrusfb_RectFill(u8 __iomem *regbase, int bits_per_pixel,
2707                      u_short x, u_short y, u_short width, u_short height,
2708                      u32 fg_color, u32 bg_color, u_short line_length,
2709                      u_char blitmode)
2710 {
2711         u_long ndest = (y * line_length) + x;
2712         u_char op;
2713
2714         cirrusfb_WaitBLT(regbase);
2715
2716         /* This is a ColorExpand Blt, using the */
2717         /* same color for foreground and background */
2718         vga_wgfx(regbase, VGA_GFX_SR_VALUE, bg_color);
2719         vga_wgfx(regbase, VGA_GFX_SR_ENABLE, fg_color);
2720
2721         op = 0x80;
2722         if (bits_per_pixel >= 16) {
2723                 vga_wgfx(regbase, CL_GR10, bg_color >> 8);
2724                 vga_wgfx(regbase, CL_GR11, fg_color >> 8);
2725                 op = 0x90;
2726         }
2727         if (bits_per_pixel >= 24) {
2728                 vga_wgfx(regbase, CL_GR12, bg_color >> 16);
2729                 vga_wgfx(regbase, CL_GR13, fg_color >> 16);
2730                 op = 0xa0;
2731         }
2732         if (bits_per_pixel == 32) {
2733                 vga_wgfx(regbase, CL_GR14, bg_color >> 24);
2734                 vga_wgfx(regbase, CL_GR15, fg_color >> 24);
2735                 op = 0xb0;
2736         }
2737         cirrusfb_set_blitter(regbase, width - 1, height - 1,
2738                             0, ndest, op | blitmode, line_length);
2739 }
2740
2741 /**************************************************************************
2742  * bestclock() - determine closest possible clock lower(?) than the
2743  * desired pixel clock
2744  **************************************************************************/
2745 static void bestclock(long freq, int *nom, int *den, int *div)
2746 {
2747         int n, d;
2748         long h, diff;
2749
2750         assert(nom != NULL);
2751         assert(den != NULL);
2752         assert(div != NULL);
2753
2754         *nom = 0;
2755         *den = 0;
2756         *div = 0;
2757
2758         if (freq < 8000)
2759                 freq = 8000;
2760
2761         diff = freq;
2762
2763         for (n = 32; n < 128; n++) {
2764                 int s = 0;
2765
2766                 d = (14318 * n) / freq;
2767                 if ((d >= 7) && (d <= 63)) {
2768                         int temp = d;
2769
2770                         if (temp > 31) {
2771                                 s = 1;
2772                                 temp >>= 1;
2773                         }
2774                         h = ((14318 * n) / temp) >> s;
2775                         h = h > freq ? h - freq : freq - h;
2776                         if (h < diff) {
2777                                 diff = h;
2778                                 *nom = n;
2779                                 *den = temp;
2780                                 *div = s;
2781                         }
2782                 }
2783                 d++;
2784                 if ((d >= 7) && (d <= 63)) {
2785                         if (d > 31) {
2786                                 s = 1;
2787                                 d >>= 1;
2788                         }
2789                         h = ((14318 * n) / d) >> s;
2790                         h = h > freq ? h - freq : freq - h;
2791                         if (h < diff) {
2792                                 diff = h;
2793                                 *nom = n;
2794                                 *den = d;
2795                                 *div = s;
2796                         }
2797                 }
2798         }
2799 }
2800
2801 /* -------------------------------------------------------------------------
2802  *
2803  * debugging functions
2804  *
2805  * -------------------------------------------------------------------------
2806  */
2807
2808 #ifdef CIRRUSFB_DEBUG
2809
2810 /**
2811  * cirrusfb_dbg_print_regs
2812  * @base: If using newmmio, the newmmio base address, otherwise %NULL
2813  * @reg_class: type of registers to read: %CRT, or %SEQ
2814  *
2815  * DESCRIPTION:
2816  * Dumps the given list of VGA CRTC registers.  If @base is %NULL,
2817  * old-style I/O ports are queried for information, otherwise MMIO is
2818  * used at the given @base address to query the information.
2819  */
2820
2821 static void cirrusfb_dbg_print_regs(struct fb_info *info,
2822                                     caddr_t regbase,
2823                                     enum cirrusfb_dbg_reg_class reg_class, ...)
2824 {
2825         va_list list;
2826         unsigned char val = 0;
2827         unsigned reg;
2828         char *name;
2829
2830         va_start(list, reg_class);
2831
2832         name = va_arg(list, char *);
2833         while (name != NULL) {
2834                 reg = va_arg(list, int);
2835
2836                 switch (reg_class) {
2837                 case CRT:
2838                         val = vga_rcrt(regbase, (unsigned char) reg);
2839                         break;
2840                 case SEQ:
2841                         val = vga_rseq(regbase, (unsigned char) reg);
2842                         break;
2843                 default:
2844                         /* should never occur */
2845                         assert(false);
2846                         break;
2847                 }
2848
2849                 dev_dbg(info->device, "%8s = 0x%02X\n", name, val);
2850
2851                 name = va_arg(list, char *);
2852         }
2853
2854         va_end(list);
2855 }
2856
2857 /**
2858  * cirrusfb_dbg_reg_dump
2859  * @base: If using newmmio, the newmmio base address, otherwise %NULL
2860  *
2861  * DESCRIPTION:
2862  * Dumps a list of interesting VGA and CIRRUSFB registers.  If @base is %NULL,
2863  * old-style I/O ports are queried for information, otherwise MMIO is
2864  * used at the given @base address to query the information.
2865  */
2866
2867 static void cirrusfb_dbg_reg_dump(struct fb_info *info, caddr_t regbase)
2868 {
2869         dev_dbg(info->device, "VGA CRTC register dump:\n");
2870
2871         cirrusfb_dbg_print_regs(info, regbase, CRT,
2872                            "CR00", 0x00,
2873                            "CR01", 0x01,
2874                            "CR02", 0x02,
2875                            "CR03", 0x03,
2876                            "CR04", 0x04,
2877                            "CR05", 0x05,
2878                            "CR06", 0x06,
2879                            "CR07", 0x07,
2880                            "CR08", 0x08,
2881                            "CR09", 0x09,
2882                            "CR0A", 0x0A,
2883                            "CR0B", 0x0B,
2884                            "CR0C", 0x0C,
2885                            "CR0D", 0x0D,
2886                            "CR0E", 0x0E,
2887                            "CR0F", 0x0F,
2888                            "CR10", 0x10,
2889                            "CR11", 0x11,
2890                            "CR12", 0x12,
2891                            "CR13", 0x13,
2892                            "CR14", 0x14,
2893                            "CR15", 0x15,
2894                            "CR16", 0x16,
2895                            "CR17", 0x17,
2896                            "CR18", 0x18,
2897                            "CR22", 0x22,
2898                            "CR24", 0x24,
2899                            "CR26", 0x26,
2900                            "CR2D", 0x2D,
2901                            "CR2E", 0x2E,
2902                            "CR2F", 0x2F,
2903                            "CR30", 0x30,
2904                            "CR31", 0x31,
2905                            "CR32", 0x32,
2906                            "CR33", 0x33,
2907                            "CR34", 0x34,
2908                            "CR35", 0x35,
2909                            "CR36", 0x36,
2910                            "CR37", 0x37,
2911                            "CR38", 0x38,
2912                            "CR39", 0x39,
2913                            "CR3A", 0x3A,
2914                            "CR3B", 0x3B,
2915                            "CR3C", 0x3C,
2916                            "CR3D", 0x3D,
2917                            "CR3E", 0x3E,
2918                            "CR3F", 0x3F,
2919                            NULL);
2920
2921         dev_dbg(info->device, "\n");
2922
2923         dev_dbg(info->device, "VGA SEQ register dump:\n");
2924
2925         cirrusfb_dbg_print_regs(info, regbase, SEQ,
2926                            "SR00", 0x00,
2927                            "SR01", 0x01,
2928                            "SR02", 0x02,
2929                            "SR03", 0x03,
2930                            "SR04", 0x04,
2931                            "SR08", 0x08,
2932                            "SR09", 0x09,
2933                            "SR0A", 0x0A,
2934                            "SR0B", 0x0B,
2935                            "SR0D", 0x0D,
2936                            "SR10", 0x10,
2937                            "SR11", 0x11,
2938                            "SR12", 0x12,
2939                            "SR13", 0x13,
2940                            "SR14", 0x14,
2941                            "SR15", 0x15,
2942                            "SR16", 0x16,
2943                            "SR17", 0x17,
2944                            "SR18", 0x18,
2945                            "SR19", 0x19,
2946                            "SR1A", 0x1A,
2947                            "SR1B", 0x1B,
2948                            "SR1C", 0x1C,
2949                            "SR1D", 0x1D,
2950                            "SR1E", 0x1E,
2951                            "SR1F", 0x1F,
2952                            NULL);
2953
2954         dev_dbg(info->device, "\n");
2955 }
2956
2957 #endif                          /* CIRRUSFB_DEBUG */
2958