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