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