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