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