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