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