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