1/*
2 *  SGI GBE frame buffer driver
3 *
4 *  Copyright (C) 1999 Silicon Graphics, Inc. - Jeffrey Newquist
5 *  Copyright (C) 2002 Vivien Chappelier <vivien.chappelier@linux-mips.org>
6 *
7 *  This file is subject to the terms and conditions of the GNU General Public
8 *  License. See the file COPYING in the main directory of this archive for
9 *  more details.
10 */
11
12#include <linux/delay.h>
13#include <linux/platform_device.h>
14#include <linux/dma-mapping.h>
15#include <linux/errno.h>
16#include <linux/fb.h>
17#include <linux/init.h>
18#include <linux/interrupt.h>
19#include <linux/kernel.h>
20#include <linux/mm.h>
21#include <linux/module.h>
22
23#ifdef CONFIG_X86
24#include <asm/mtrr.h>
25#endif
26#ifdef CONFIG_MIPS
27#include <asm/addrspace.h>
28#endif
29#include <asm/byteorder.h>
30#include <asm/io.h>
31#include <asm/tlbflush.h>
32
33#include <video/gbe.h>
34
35static struct sgi_gbe *gbe;
36
37struct gbefb_par {
38	struct fb_var_screeninfo var;
39	struct gbe_timing_info timing;
40	int valid;
41};
42
43#ifdef CONFIG_SGI_IP32
44#define GBE_BASE	0x16000000 /* SGI O2 */
45#endif
46
47#ifdef CONFIG_X86_VISWS
48#define GBE_BASE	0xd0000000 /* SGI Visual Workstation */
49#endif
50
51/* macro for fastest write-though access to the framebuffer */
52#ifdef CONFIG_MIPS
53#ifdef CONFIG_CPU_R10000
54#define pgprot_fb(_prot) (((_prot) & (~_CACHE_MASK)) | _CACHE_UNCACHED_ACCELERATED)
55#else
56#define pgprot_fb(_prot) (((_prot) & (~_CACHE_MASK)) | _CACHE_CACHABLE_NO_WA)
57#endif
58#endif
59#ifdef CONFIG_X86
60#define pgprot_fb(_prot) ((_prot) | _PAGE_PCD)
61#endif
62
63/*
64 *  RAM we reserve for the frame buffer. This defines the maximum screen
65 *  size
66 */
67#if CONFIG_FB_GBE_MEM > 8
68#error GBE Framebuffer cannot use more than 8MB of memory
69#endif
70
71#define TILE_SHIFT 16
72#define TILE_SIZE (1 << TILE_SHIFT)
73#define TILE_MASK (TILE_SIZE - 1)
74
75static unsigned int gbe_mem_size = CONFIG_FB_GBE_MEM * 1024*1024;
76static void *gbe_mem;
77static dma_addr_t gbe_dma_addr;
78unsigned long gbe_mem_phys;
79
80static struct {
81	uint16_t *cpu;
82	dma_addr_t dma;
83} gbe_tiles;
84
85static int gbe_revision;
86
87static int ypan, ywrap;
88
89static uint32_t pseudo_palette[256];
90
91static char *mode_option __initdata = NULL;
92
93/* default CRT mode */
94static struct fb_var_screeninfo default_var_CRT __initdata = {
95	/* 640x480, 60 Hz, Non-Interlaced (25.175 MHz dotclock) */
96	.xres		= 640,
97	.yres		= 480,
98	.xres_virtual	= 640,
99	.yres_virtual	= 480,
100	.xoffset	= 0,
101	.yoffset	= 0,
102	.bits_per_pixel	= 8,
103	.grayscale	= 0,
104	.red		= { 0, 8, 0 },
105	.green		= { 0, 8, 0 },
106	.blue		= { 0, 8, 0 },
107	.transp		= { 0, 0, 0 },
108	.nonstd		= 0,
109	.activate	= 0,
110	.height		= -1,
111	.width		= -1,
112	.accel_flags	= 0,
113	.pixclock	= 39722,	/* picoseconds */
114	.left_margin	= 48,
115	.right_margin	= 16,
116	.upper_margin	= 33,
117	.lower_margin	= 10,
118	.hsync_len	= 96,
119	.vsync_len	= 2,
120	.sync		= 0,
121	.vmode		= FB_VMODE_NONINTERLACED,
122};
123
124/* default LCD mode */
125static struct fb_var_screeninfo default_var_LCD __initdata = {
126	/* 1600x1024, 8 bpp */
127	.xres		= 1600,
128	.yres		= 1024,
129	.xres_virtual	= 1600,
130	.yres_virtual	= 1024,
131	.xoffset	= 0,
132	.yoffset	= 0,
133	.bits_per_pixel	= 8,
134	.grayscale	= 0,
135	.red		= { 0, 8, 0 },
136	.green		= { 0, 8, 0 },
137	.blue		= { 0, 8, 0 },
138	.transp		= { 0, 0, 0 },
139	.nonstd		= 0,
140	.activate	= 0,
141	.height		= -1,
142	.width		= -1,
143	.accel_flags	= 0,
144	.pixclock	= 9353,
145	.left_margin	= 20,
146	.right_margin	= 30,
147	.upper_margin	= 37,
148	.lower_margin	= 3,
149	.hsync_len	= 20,
150	.vsync_len	= 3,
151	.sync		= 0,
152	.vmode		= FB_VMODE_NONINTERLACED
153};
154
155/* default modedb mode */
156/* 640x480, 60 Hz, Non-Interlaced (25.172 MHz dotclock) */
157static struct fb_videomode default_mode_CRT __initdata = {
158	.refresh	= 60,
159	.xres		= 640,
160	.yres		= 480,
161	.pixclock	= 39722,
162	.left_margin	= 48,
163	.right_margin	= 16,
164	.upper_margin	= 33,
165	.lower_margin	= 10,
166	.hsync_len	= 96,
167	.vsync_len	= 2,
168	.sync		= 0,
169	.vmode		= FB_VMODE_NONINTERLACED,
170};
171/* 1600x1024 SGI flatpanel 1600sw */
172static struct fb_videomode default_mode_LCD __initdata = {
173	/* 1600x1024, 8 bpp */
174	.xres		= 1600,
175	.yres		= 1024,
176	.pixclock	= 9353,
177	.left_margin	= 20,
178	.right_margin	= 30,
179	.upper_margin	= 37,
180	.lower_margin	= 3,
181	.hsync_len	= 20,
182	.vsync_len	= 3,
183	.vmode		= FB_VMODE_NONINTERLACED,
184};
185
186struct fb_videomode *default_mode = &default_mode_CRT;
187struct fb_var_screeninfo *default_var = &default_var_CRT;
188
189static int flat_panel_enabled = 0;
190
191static void gbe_reset(void)
192{
193	/* Turn on dotclock PLL */
194	gbe->ctrlstat = 0x300aa000;
195}
196
197
198/*
199 * Function:	gbe_turn_off
200 * Parameters:	(None)
201 * Description:	This should turn off the monitor and gbe.  This is used
202 *              when switching between the serial console and the graphics
203 *              console.
204 */
205
206void gbe_turn_off(void)
207{
208	int i;
209	unsigned int val, x, y, vpixen_off;
210
211	/* check if pixel counter is on */
212	val = gbe->vt_xy;
213	if (GET_GBE_FIELD(VT_XY, FREEZE, val) == 1)
214		return;
215
216	/* turn off DMA */
217	val = gbe->ovr_control;
218	SET_GBE_FIELD(OVR_CONTROL, OVR_DMA_ENABLE, val, 0);
219	gbe->ovr_control = val;
220	udelay(1000);
221	val = gbe->frm_control;
222	SET_GBE_FIELD(FRM_CONTROL, FRM_DMA_ENABLE, val, 0);
223	gbe->frm_control = val;
224	udelay(1000);
225	val = gbe->did_control;
226	SET_GBE_FIELD(DID_CONTROL, DID_DMA_ENABLE, val, 0);
227	gbe->did_control = val;
228	udelay(1000);
229
230	/* We have to wait through two vertical retrace periods before
231	 * the pixel DMA is turned off for sure. */
232	for (i = 0; i < 10000; i++) {
233		val = gbe->frm_inhwctrl;
234		if (GET_GBE_FIELD(FRM_INHWCTRL, FRM_DMA_ENABLE, val)) {
235			udelay(10);
236		} else {
237			val = gbe->ovr_inhwctrl;
238			if (GET_GBE_FIELD(OVR_INHWCTRL, OVR_DMA_ENABLE, val)) {
239				udelay(10);
240			} else {
241				val = gbe->did_inhwctrl;
242				if (GET_GBE_FIELD(DID_INHWCTRL, DID_DMA_ENABLE, val)) {
243					udelay(10);
244				} else
245					break;
246			}
247		}
248	}
249	if (i == 10000)
250		printk(KERN_ERR "gbefb: turn off DMA timed out\n");
251
252	/* wait for vpixen_off */
253	val = gbe->vt_vpixen;
254	vpixen_off = GET_GBE_FIELD(VT_VPIXEN, VPIXEN_OFF, val);
255
256	for (i = 0; i < 100000; i++) {
257		val = gbe->vt_xy;
258		x = GET_GBE_FIELD(VT_XY, X, val);
259		y = GET_GBE_FIELD(VT_XY, Y, val);
260		if (y < vpixen_off)
261			break;
262		udelay(1);
263	}
264	if (i == 100000)
265		printk(KERN_ERR
266		       "gbefb: wait for vpixen_off timed out\n");
267	for (i = 0; i < 10000; i++) {
268		val = gbe->vt_xy;
269		x = GET_GBE_FIELD(VT_XY, X, val);
270		y = GET_GBE_FIELD(VT_XY, Y, val);
271		if (y > vpixen_off)
272			break;
273		udelay(1);
274	}
275	if (i == 10000)
276		printk(KERN_ERR "gbefb: wait for vpixen_off timed out\n");
277
278	/* turn off pixel counter */
279	val = 0;
280	SET_GBE_FIELD(VT_XY, FREEZE, val, 1);
281	gbe->vt_xy = val;
282	udelay(10000);
283	for (i = 0; i < 10000; i++) {
284		val = gbe->vt_xy;
285		if (GET_GBE_FIELD(VT_XY, FREEZE, val) != 1)
286			udelay(10);
287		else
288			break;
289	}
290	if (i == 10000)
291		printk(KERN_ERR "gbefb: turn off pixel clock timed out\n");
292
293	/* turn off dot clock */
294	val = gbe->dotclock;
295	SET_GBE_FIELD(DOTCLK, RUN, val, 0);
296	gbe->dotclock = val;
297	udelay(10000);
298	for (i = 0; i < 10000; i++) {
299		val = gbe->dotclock;
300		if (GET_GBE_FIELD(DOTCLK, RUN, val))
301			udelay(10);
302		else
303			break;
304	}
305	if (i == 10000)
306		printk(KERN_ERR "gbefb: turn off dotclock timed out\n");
307
308	/* reset the frame DMA FIFO */
309	val = gbe->frm_size_tile;
310	SET_GBE_FIELD(FRM_SIZE_TILE, FRM_FIFO_RESET, val, 1);
311	gbe->frm_size_tile = val;
312	SET_GBE_FIELD(FRM_SIZE_TILE, FRM_FIFO_RESET, val, 0);
313	gbe->frm_size_tile = val;
314}
315
316static void gbe_turn_on(void)
317{
318	unsigned int val, i;
319
320	/*
321	 * Check if pixel counter is off, for unknown reason this
322	 * code hangs Visual Workstations
323	 */
324	if (gbe_revision < 2) {
325		val = gbe->vt_xy;
326		if (GET_GBE_FIELD(VT_XY, FREEZE, val) == 0)
327			return;
328	}
329
330	/* turn on dot clock */
331	val = gbe->dotclock;
332	SET_GBE_FIELD(DOTCLK, RUN, val, 1);
333	gbe->dotclock = val;
334	udelay(10000);
335	for (i = 0; i < 10000; i++) {
336		val = gbe->dotclock;
337		if (GET_GBE_FIELD(DOTCLK, RUN, val) != 1)
338			udelay(10);
339		else
340			break;
341	}
342	if (i == 10000)
343		printk(KERN_ERR "gbefb: turn on dotclock timed out\n");
344
345	/* turn on pixel counter */
346	val = 0;
347	SET_GBE_FIELD(VT_XY, FREEZE, val, 0);
348	gbe->vt_xy = val;
349	udelay(10000);
350	for (i = 0; i < 10000; i++) {
351		val = gbe->vt_xy;
352		if (GET_GBE_FIELD(VT_XY, FREEZE, val))
353			udelay(10);
354		else
355			break;
356	}
357	if (i == 10000)
358		printk(KERN_ERR "gbefb: turn on pixel clock timed out\n");
359
360	/* turn on DMA */
361	val = gbe->frm_control;
362	SET_GBE_FIELD(FRM_CONTROL, FRM_DMA_ENABLE, val, 1);
363	gbe->frm_control = val;
364	udelay(1000);
365	for (i = 0; i < 10000; i++) {
366		val = gbe->frm_inhwctrl;
367		if (GET_GBE_FIELD(FRM_INHWCTRL, FRM_DMA_ENABLE, val) != 1)
368			udelay(10);
369		else
370			break;
371	}
372	if (i == 10000)
373		printk(KERN_ERR "gbefb: turn on DMA timed out\n");
374}
375
376/*
377 *  Blank the display.
378 */
379static int gbefb_blank(int blank, struct fb_info *info)
380{
381	/* 0 unblank, 1 blank, 2 no vsync, 3 no hsync, 4 off */
382	switch (blank) {
383	case FB_BLANK_UNBLANK:		/* unblank */
384		gbe_turn_on();
385		break;
386
387	case FB_BLANK_NORMAL:		/* blank */
388		gbe_turn_off();
389		break;
390
391	default:
392		/* Nothing */
393		break;
394	}
395	return 0;
396}
397
398/*
399 *  Setup flatpanel related registers.
400 */
401static void gbefb_setup_flatpanel(struct gbe_timing_info *timing)
402{
403	int fp_wid, fp_hgt, fp_vbs, fp_vbe;
404	u32 outputVal = 0;
405
406	SET_GBE_FIELD(VT_FLAGS, HDRV_INVERT, outputVal,
407		(timing->flags & FB_SYNC_HOR_HIGH_ACT) ? 0 : 1);
408	SET_GBE_FIELD(VT_FLAGS, VDRV_INVERT, outputVal,
409		(timing->flags & FB_SYNC_VERT_HIGH_ACT) ? 0 : 1);
410	gbe->vt_flags = outputVal;
411
412	/* Turn on the flat panel */
413	fp_wid = 1600;
414	fp_hgt = 1024;
415	fp_vbs = 0;
416	fp_vbe = 1600;
417	timing->pll_m = 4;
418	timing->pll_n = 1;
419	timing->pll_p = 0;
420
421	outputVal = 0;
422	SET_GBE_FIELD(FP_DE, ON, outputVal, fp_vbs);
423	SET_GBE_FIELD(FP_DE, OFF, outputVal, fp_vbe);
424	gbe->fp_de = outputVal;
425	outputVal = 0;
426	SET_GBE_FIELD(FP_HDRV, OFF, outputVal, fp_wid);
427	gbe->fp_hdrv = outputVal;
428	outputVal = 0;
429	SET_GBE_FIELD(FP_VDRV, ON, outputVal, 1);
430	SET_GBE_FIELD(FP_VDRV, OFF, outputVal, fp_hgt + 1);
431	gbe->fp_vdrv = outputVal;
432}
433
434struct gbe_pll_info {
435	int clock_rate;
436	int fvco_min;
437	int fvco_max;
438};
439
440static struct gbe_pll_info gbe_pll_table[2] = {
441	{ 20, 80, 220 },
442	{ 27, 80, 220 },
443};
444
445static int compute_gbe_timing(struct fb_var_screeninfo *var,
446			      struct gbe_timing_info *timing)
447{
448	int pll_m, pll_n, pll_p, error, best_m, best_n, best_p, best_error;
449	int pixclock;
450	struct gbe_pll_info *gbe_pll;
451
452	if (gbe_revision < 2)
453		gbe_pll = &gbe_pll_table[0];
454	else
455		gbe_pll = &gbe_pll_table[1];
456
457	/* Determine valid resolution and timing
458	 * GBE crystal runs at 20Mhz or 27Mhz
459	 * pll_m, pll_n, pll_p define the following frequencies
460	 * fvco = pll_m * 20Mhz / pll_n
461	 * fout = fvco / (2**pll_p) */
462	best_error = 1000000000;
463	best_n = best_m = best_p = 0;
464	for (pll_p = 0; pll_p < 4; pll_p++)
465		for (pll_m = 1; pll_m < 256; pll_m++)
466			for (pll_n = 1; pll_n < 64; pll_n++) {
467				pixclock = (1000000 / gbe_pll->clock_rate) *
468						(pll_n << pll_p) / pll_m;
469
470				error = var->pixclock - pixclock;
471
472				if (error < 0)
473					error = -error;
474
475				if (error < best_error &&
476				    pll_m / pll_n >
477				    gbe_pll->fvco_min / gbe_pll->clock_rate &&
478 				    pll_m / pll_n <
479				    gbe_pll->fvco_max / gbe_pll->clock_rate) {
480					best_error = error;
481					best_m = pll_m;
482					best_n = pll_n;
483					best_p = pll_p;
484				}
485			}
486
487	if (!best_n || !best_m)
488		return -EINVAL;	/* Resolution to high */
489
490	pixclock = (1000000 / gbe_pll->clock_rate) *
491		(best_n << best_p) / best_m;
492
493	/* set video timing information */
494	if (timing) {
495		timing->width = var->xres;
496		timing->height = var->yres;
497		timing->pll_m = best_m;
498		timing->pll_n = best_n;
499		timing->pll_p = best_p;
500		timing->cfreq = gbe_pll->clock_rate * 1000 * timing->pll_m /
501			(timing->pll_n << timing->pll_p);
502		timing->htotal = var->left_margin + var->xres +
503				var->right_margin + var->hsync_len;
504		timing->vtotal = var->upper_margin + var->yres +
505				var->lower_margin + var->vsync_len;
506		timing->fields_sec = 1000 * timing->cfreq / timing->htotal *
507				1000 / timing->vtotal;
508		timing->hblank_start = var->xres;
509		timing->vblank_start = var->yres;
510		timing->hblank_end = timing->htotal;
511		timing->hsync_start = var->xres + var->right_margin + 1;
512		timing->hsync_end = timing->hsync_start + var->hsync_len;
513		timing->vblank_end = timing->vtotal;
514		timing->vsync_start = var->yres + var->lower_margin + 1;
515		timing->vsync_end = timing->vsync_start + var->vsync_len;
516	}
517
518	return pixclock;
519}
520
521static void gbe_set_timing_info(struct gbe_timing_info *timing)
522{
523	int temp;
524	unsigned int val;
525
526	/* setup dot clock PLL */
527	val = 0;
528	SET_GBE_FIELD(DOTCLK, M, val, timing->pll_m - 1);
529	SET_GBE_FIELD(DOTCLK, N, val, timing->pll_n - 1);
530	SET_GBE_FIELD(DOTCLK, P, val, timing->pll_p);
531	SET_GBE_FIELD(DOTCLK, RUN, val, 0);	/* do not start yet */
532	gbe->dotclock = val;
533	udelay(10000);
534
535	/* setup pixel counter */
536	val = 0;
537	SET_GBE_FIELD(VT_XYMAX, MAXX, val, timing->htotal);
538	SET_GBE_FIELD(VT_XYMAX, MAXY, val, timing->vtotal);
539	gbe->vt_xymax = val;
540
541	/* setup video timing signals */
542	val = 0;
543	SET_GBE_FIELD(VT_VSYNC, VSYNC_ON, val, timing->vsync_start);
544	SET_GBE_FIELD(VT_VSYNC, VSYNC_OFF, val, timing->vsync_end);
545	gbe->vt_vsync = val;
546	val = 0;
547	SET_GBE_FIELD(VT_HSYNC, HSYNC_ON, val, timing->hsync_start);
548	SET_GBE_FIELD(VT_HSYNC, HSYNC_OFF, val, timing->hsync_end);
549	gbe->vt_hsync = val;
550	val = 0;
551	SET_GBE_FIELD(VT_VBLANK, VBLANK_ON, val, timing->vblank_start);
552	SET_GBE_FIELD(VT_VBLANK, VBLANK_OFF, val, timing->vblank_end);
553	gbe->vt_vblank = val;
554	val = 0;
555	SET_GBE_FIELD(VT_HBLANK, HBLANK_ON, val,
556		      timing->hblank_start - 5);
557	SET_GBE_FIELD(VT_HBLANK, HBLANK_OFF, val,
558		      timing->hblank_end - 3);
559	gbe->vt_hblank = val;
560
561	/* setup internal timing signals */
562	val = 0;
563	SET_GBE_FIELD(VT_VCMAP, VCMAP_ON, val, timing->vblank_start);
564	SET_GBE_FIELD(VT_VCMAP, VCMAP_OFF, val, timing->vblank_end);
565	gbe->vt_vcmap = val;
566	val = 0;
567	SET_GBE_FIELD(VT_HCMAP, HCMAP_ON, val, timing->hblank_start);
568	SET_GBE_FIELD(VT_HCMAP, HCMAP_OFF, val, timing->hblank_end);
569	gbe->vt_hcmap = val;
570
571	val = 0;
572	temp = timing->vblank_start - timing->vblank_end - 1;
573	if (temp > 0)
574		temp = -temp;
575
576	if (flat_panel_enabled)
577		gbefb_setup_flatpanel(timing);
578
579	SET_GBE_FIELD(DID_START_XY, DID_STARTY, val, (u32) temp);
580	if (timing->hblank_end >= 20)
581		SET_GBE_FIELD(DID_START_XY, DID_STARTX, val,
582			      timing->hblank_end - 20);
583	else
584		SET_GBE_FIELD(DID_START_XY, DID_STARTX, val,
585			      timing->htotal - (20 - timing->hblank_end));
586	gbe->did_start_xy = val;
587
588	val = 0;
589	SET_GBE_FIELD(CRS_START_XY, CRS_STARTY, val, (u32) (temp + 1));
590	if (timing->hblank_end >= GBE_CRS_MAGIC)
591		SET_GBE_FIELD(CRS_START_XY, CRS_STARTX, val,
592			      timing->hblank_end - GBE_CRS_MAGIC);
593	else
594		SET_GBE_FIELD(CRS_START_XY, CRS_STARTX, val,
595			      timing->htotal - (GBE_CRS_MAGIC -
596						timing->hblank_end));
597	gbe->crs_start_xy = val;
598
599	val = 0;
600	SET_GBE_FIELD(VC_START_XY, VC_STARTY, val, (u32) temp);
601	SET_GBE_FIELD(VC_START_XY, VC_STARTX, val, timing->hblank_end - 4);
602	gbe->vc_start_xy = val;
603
604	val = 0;
605	temp = timing->hblank_end - GBE_PIXEN_MAGIC_ON;
606	if (temp < 0)
607		temp += timing->htotal;	/* allow blank to wrap around */
608
609	SET_GBE_FIELD(VT_HPIXEN, HPIXEN_ON, val, temp);
610	SET_GBE_FIELD(VT_HPIXEN, HPIXEN_OFF, val,
611		      ((temp + timing->width -
612			GBE_PIXEN_MAGIC_OFF) % timing->htotal));
613	gbe->vt_hpixen = val;
614
615	val = 0;
616	SET_GBE_FIELD(VT_VPIXEN, VPIXEN_ON, val, timing->vblank_end);
617	SET_GBE_FIELD(VT_VPIXEN, VPIXEN_OFF, val, timing->vblank_start);
618	gbe->vt_vpixen = val;
619
620	/* turn off sync on green */
621	val = 0;
622	SET_GBE_FIELD(VT_FLAGS, SYNC_LOW, val, 1);
623	gbe->vt_flags = val;
624}
625
626/*
627 *  Set the hardware according to 'par'.
628 */
629
630static int gbefb_set_par(struct fb_info *info)
631{
632	int i;
633	unsigned int val;
634	int wholeTilesX, partTilesX, maxPixelsPerTileX;
635	int height_pix;
636	int xpmax, ypmax;	/* Monitor resolution */
637	int bytesPerPixel;	/* Bytes per pixel */
638	struct gbefb_par *par = (struct gbefb_par *) info->par;
639
640	compute_gbe_timing(&info->var, &par->timing);
641
642	bytesPerPixel = info->var.bits_per_pixel / 8;
643	info->fix.line_length = info->var.xres_virtual * bytesPerPixel;
644	xpmax = par->timing.width;
645	ypmax = par->timing.height;
646
647	/* turn off GBE */
648	gbe_turn_off();
649
650	/* set timing info */
651	gbe_set_timing_info(&par->timing);
652
653	/* initialize DIDs */
654	val = 0;
655	switch (bytesPerPixel) {
656	case 1:
657		SET_GBE_FIELD(WID, TYP, val, GBE_CMODE_I8);
658		info->fix.visual = FB_VISUAL_PSEUDOCOLOR;
659		break;
660	case 2:
661		SET_GBE_FIELD(WID, TYP, val, GBE_CMODE_ARGB5);
662		info->fix.visual = FB_VISUAL_TRUECOLOR;
663		break;
664	case 4:
665		SET_GBE_FIELD(WID, TYP, val, GBE_CMODE_RGB8);
666		info->fix.visual = FB_VISUAL_TRUECOLOR;
667		break;
668	}
669	SET_GBE_FIELD(WID, BUF, val, GBE_BMODE_BOTH);
670
671	for (i = 0; i < 32; i++)
672		gbe->mode_regs[i] = val;
673
674	/* Initialize interrupts */
675	gbe->vt_intr01 = 0xffffffff;
676	gbe->vt_intr23 = 0xffffffff;
677
678	/* HACK:
679	   The GBE hardware uses a tiled memory to screen mapping. Tiles are
680	   blocks of 512x128, 256x128 or 128x128 pixels, respectively for 8bit,
681	   16bit and 32 bit modes (64 kB). They cover the screen with partial
682	   tiles on the right and/or bottom of the screen if needed.
683	   For exemple in 640x480 8 bit mode the mapping is:
684
685	   <-------- 640 ----->
686	   <---- 512 ----><128|384 offscreen>
687	   ^  ^
688	   | 128    [tile 0]        [tile 1]
689	   |  v
690	   ^
691	   4 128    [tile 2]        [tile 3]
692	   8  v
693	   0  ^
694	   128    [tile 4]        [tile 5]
695	   |  v
696	   |  ^
697	   v  96    [tile 6]        [tile 7]
698	   32 offscreen
699
700	   Tiles have the advantage that they can be allocated individually in
701	   memory. However, this mapping is not linear at all, which is not
702	   really convienient. In order to support linear addressing, the GBE
703	   DMA hardware is fooled into thinking the screen is only one tile
704	   large and but has a greater height, so that the DMA transfer covers
705	   the same region.
706	   Tiles are still allocated as independent chunks of 64KB of
707	   continuous physical memory and remapped so that the kernel sees the
708	   framebuffer as a continuous virtual memory. The GBE tile table is
709	   set up so that each tile references one of these 64k blocks:
710
711	   GBE -> tile list    framebuffer           TLB   <------------ CPU
712	          [ tile 0 ] -> [ 64KB ]  <- [ 16x 4KB page entries ]     ^
713	             ...           ...              ...       linear virtual FB
714	          [ tile n ] -> [ 64KB ]  <- [ 16x 4KB page entries ]     v
715
716
717	   The GBE hardware is then told that the buffer is 512*tweaked_height,
718	   with tweaked_height = real_width*real_height/pixels_per_tile.
719	   Thus the GBE hardware will scan the first tile, filing the first 64k
720	   covered region of the screen, and then will proceed to the next
721	   tile, until the whole screen is covered.
722
723	   Here is what would happen at 640x480 8bit:
724
725	   normal tiling               linear
726	   ^   11111111111111112222    11111111111111111111  ^
727	   128 11111111111111112222    11111111111111111111 102 lines
728	       11111111111111112222    11111111111111111111  v
729	   V   11111111111111112222    11111111222222222222
730	       33333333333333334444    22222222222222222222
731	       33333333333333334444    22222222222222222222
732	       <      512     >        <  256 >               102*640+256 = 64k
733
734	   NOTE: The only mode for which this is not working is 800x600 8bit,
735	   as 800*600/512 = 937.5 which is not integer and thus causes
736	   flickering.
737	   I guess this is not so important as one can use 640x480 8bit or
738	   800x600 16bit anyway.
739	 */
740
741	/* Tell gbe about the tiles table location */
742	/* tile_ptr -> [ tile 1 ] -> FB mem */
743	/*             [ tile 2 ] -> FB mem */
744	/*               ...                */
745	val = 0;
746	SET_GBE_FIELD(FRM_CONTROL, FRM_TILE_PTR, val, gbe_tiles.dma >> 9);
747	SET_GBE_FIELD(FRM_CONTROL, FRM_DMA_ENABLE, val, 0); /* do not start */
748	SET_GBE_FIELD(FRM_CONTROL, FRM_LINEAR, val, 0);
749	gbe->frm_control = val;
750
751	maxPixelsPerTileX = 512 / bytesPerPixel;
752	wholeTilesX = 1;
753	partTilesX = 0;
754
755	/* Initialize the framebuffer */
756	val = 0;
757	SET_GBE_FIELD(FRM_SIZE_TILE, FRM_WIDTH_TILE, val, wholeTilesX);
758	SET_GBE_FIELD(FRM_SIZE_TILE, FRM_RHS, val, partTilesX);
759
760	switch (bytesPerPixel) {
761	case 1:
762		SET_GBE_FIELD(FRM_SIZE_TILE, FRM_DEPTH, val,
763			      GBE_FRM_DEPTH_8);
764		break;
765	case 2:
766		SET_GBE_FIELD(FRM_SIZE_TILE, FRM_DEPTH, val,
767			      GBE_FRM_DEPTH_16);
768		break;
769	case 4:
770		SET_GBE_FIELD(FRM_SIZE_TILE, FRM_DEPTH, val,
771			      GBE_FRM_DEPTH_32);
772		break;
773	}
774	gbe->frm_size_tile = val;
775
776	/* compute tweaked height */
777	height_pix = xpmax * ypmax / maxPixelsPerTileX;
778
779	val = 0;
780	SET_GBE_FIELD(FRM_SIZE_PIXEL, FB_HEIGHT_PIX, val, height_pix);
781	gbe->frm_size_pixel = val;
782
783	/* turn off DID and overlay DMA */
784	gbe->did_control = 0;
785	gbe->ovr_width_tile = 0;
786
787	/* Turn off mouse cursor */
788	gbe->crs_ctl = 0;
789
790	/* Turn on GBE */
791	gbe_turn_on();
792
793	/* Initialize the gamma map */
794	udelay(10);
795	for (i = 0; i < 256; i++)
796		gbe->gmap[i] = (i << 24) | (i << 16) | (i << 8);
797
798	/* Initialize the color map */
799	for (i = 0; i < 256; i++) {
800		int j;
801
802		for (j = 0; j < 1000 && gbe->cm_fifo >= 63; j++)
803			udelay(10);
804		if (j == 1000)
805			printk(KERN_ERR "gbefb: cmap FIFO timeout\n");
806
807		gbe->cmap[i] = (i << 8) | (i << 16) | (i << 24);
808	}
809
810	return 0;
811}
812
813static void gbefb_encode_fix(struct fb_fix_screeninfo *fix,
814			     struct fb_var_screeninfo *var)
815{
816	memset(fix, 0, sizeof(struct fb_fix_screeninfo));
817	strcpy(fix->id, "SGI GBE");
818	fix->smem_start = (unsigned long) gbe_mem;
819	fix->smem_len = gbe_mem_size;
820	fix->type = FB_TYPE_PACKED_PIXELS;
821	fix->type_aux = 0;
822	fix->accel = FB_ACCEL_NONE;
823	switch (var->bits_per_pixel) {
824	case 8:
825		fix->visual = FB_VISUAL_PSEUDOCOLOR;
826		break;
827	default:
828		fix->visual = FB_VISUAL_TRUECOLOR;
829		break;
830	}
831	fix->ywrapstep = 0;
832	fix->xpanstep = 0;
833	fix->ypanstep = 0;
834	fix->line_length = var->xres_virtual * var->bits_per_pixel / 8;
835	fix->mmio_start = GBE_BASE;
836	fix->mmio_len = sizeof(struct sgi_gbe);
837}
838
839/*
840 *  Set a single color register. The values supplied are already
841 *  rounded down to the hardware's capabilities (according to the
842 *  entries in the var structure). Return != 0 for invalid regno.
843 */
844
845static int gbefb_setcolreg(unsigned regno, unsigned red, unsigned green,
846			     unsigned blue, unsigned transp,
847			     struct fb_info *info)
848{
849	int i;
850
851	if (regno > 255)
852		return 1;
853	red >>= 8;
854	green >>= 8;
855	blue >>= 8;
856
857	switch (info->var.bits_per_pixel) {
858	case 8:
859		/* wait for the color map FIFO to have a free entry */
860		for (i = 0; i < 1000 && gbe->cm_fifo >= 63; i++)
861			udelay(10);
862		if (i == 1000) {
863			printk(KERN_ERR "gbefb: cmap FIFO timeout\n");
864			return 1;
865		}
866		gbe->cmap[regno] = (red << 24) | (green << 16) | (blue << 8);
867		break;
868	case 15:
869	case 16:
870		red >>= 3;
871		green >>= 3;
872		blue >>= 3;
873		pseudo_palette[regno] =
874			(red << info->var.red.offset) |
875			(green << info->var.green.offset) |
876			(blue << info->var.blue.offset);
877		break;
878	case 32:
879		pseudo_palette[regno] =
880			(red << info->var.red.offset) |
881			(green << info->var.green.offset) |
882			(blue << info->var.blue.offset);
883		break;
884	}
885
886	return 0;
887}
888
889/*
890 *  Check video mode validity, eventually modify var to best match.
891 */
892static int gbefb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
893{
894	unsigned int line_length;
895	struct gbe_timing_info timing;
896
897	/* Limit bpp to 8, 16, and 32 */
898	if (var->bits_per_pixel <= 8)
899		var->bits_per_pixel = 8;
900	else if (var->bits_per_pixel <= 16)
901		var->bits_per_pixel = 16;
902	else if (var->bits_per_pixel <= 32)
903		var->bits_per_pixel = 32;
904	else
905		return -EINVAL;
906
907	/* Check the mode can be mapped linearly with the tile table trick. */
908	/* This requires width x height x bytes/pixel be a multiple of 512 */
909	if ((var->xres * var->yres * var->bits_per_pixel) & 4095)
910		return -EINVAL;
911
912	var->grayscale = 0;	/* No grayscale for now */
913
914	if ((var->pixclock = compute_gbe_timing(var, &timing)) < 0)
915		return(-EINVAL);
916
917	/* Adjust virtual resolution, if necessary */
918	if (var->xres > var->xres_virtual || (!ywrap && !ypan))
919		var->xres_virtual = var->xres;
920	if (var->yres > var->yres_virtual || (!ywrap && !ypan))
921		var->yres_virtual = var->yres;
922
923	if (var->vmode & FB_VMODE_CONUPDATE) {
924		var->vmode |= FB_VMODE_YWRAP;
925		var->xoffset = info->var.xoffset;
926		var->yoffset = info->var.yoffset;
927	}
928
929	/* No grayscale for now */
930	var->grayscale = 0;
931
932	/* Memory limit */
933	line_length = var->xres_virtual * var->bits_per_pixel / 8;
934	if (line_length * var->yres_virtual > gbe_mem_size)
935		return -ENOMEM;	/* Virtual resolution too high */
936
937	switch (var->bits_per_pixel) {
938	case 8:
939		var->red.offset = 0;
940		var->red.length = 8;
941		var->green.offset = 0;
942		var->green.length = 8;
943		var->blue.offset = 0;
944		var->blue.length = 8;
945		var->transp.offset = 0;
946		var->transp.length = 0;
947		break;
948	case 16:		/* RGB 1555 */
949		var->red.offset = 10;
950		var->red.length = 5;
951		var->green.offset = 5;
952		var->green.length = 5;
953		var->blue.offset = 0;
954		var->blue.length = 5;
955		var->transp.offset = 0;
956		var->transp.length = 0;
957		break;
958	case 32:		/* RGB 8888 */
959		var->red.offset = 24;
960		var->red.length = 8;
961		var->green.offset = 16;
962		var->green.length = 8;
963		var->blue.offset = 8;
964		var->blue.length = 8;
965		var->transp.offset = 0;
966		var->transp.length = 8;
967		break;
968	}
969	var->red.msb_right = 0;
970	var->green.msb_right = 0;
971	var->blue.msb_right = 0;
972	var->transp.msb_right = 0;
973
974	var->left_margin = timing.htotal - timing.hsync_end;
975	var->right_margin = timing.hsync_start - timing.width;
976	var->upper_margin = timing.vtotal - timing.vsync_end;
977	var->lower_margin = timing.vsync_start - timing.height;
978	var->hsync_len = timing.hsync_end - timing.hsync_start;
979	var->vsync_len = timing.vsync_end - timing.vsync_start;
980
981	return 0;
982}
983
984static int gbefb_mmap(struct fb_info *info,
985			struct vm_area_struct *vma)
986{
987	unsigned long size = vma->vm_end - vma->vm_start;
988	unsigned long offset = vma->vm_pgoff << PAGE_SHIFT;
989	unsigned long addr;
990	unsigned long phys_addr, phys_size;
991	u16 *tile;
992
993	/* check range */
994	if (vma->vm_pgoff > (~0UL >> PAGE_SHIFT))
995		return -EINVAL;
996	if (offset + size > gbe_mem_size)
997		return -EINVAL;
998
999	/* remap using the fastest write-through mode on architecture */
1000	/* try not polluting the cache when possible */
1001	pgprot_val(vma->vm_page_prot) =
1002		pgprot_fb(pgprot_val(vma->vm_page_prot));
1003
1004	vma->vm_flags |= VM_IO | VM_RESERVED;
1005
1006	/* look for the starting tile */
1007	tile = &gbe_tiles.cpu[offset >> TILE_SHIFT];
1008	addr = vma->vm_start;
1009	offset &= TILE_MASK;
1010
1011	/* remap each tile separately */
1012	do {
1013		phys_addr = (((unsigned long) (*tile)) << TILE_SHIFT) + offset;
1014		if ((offset + size) < TILE_SIZE)
1015			phys_size = size;
1016		else
1017			phys_size = TILE_SIZE - offset;
1018
1019		if (remap_pfn_range(vma, addr, phys_addr >> PAGE_SHIFT,
1020						phys_size, vma->vm_page_prot))
1021			return -EAGAIN;
1022
1023		offset = 0;
1024		size -= phys_size;
1025		addr += phys_size;
1026		tile++;
1027	} while (size);
1028
1029	return 0;
1030}
1031
1032static struct fb_ops gbefb_ops = {
1033	.owner		= THIS_MODULE,
1034	.fb_check_var	= gbefb_check_var,
1035	.fb_set_par	= gbefb_set_par,
1036	.fb_setcolreg	= gbefb_setcolreg,
1037	.fb_mmap	= gbefb_mmap,
1038	.fb_blank	= gbefb_blank,
1039	.fb_fillrect	= cfb_fillrect,
1040	.fb_copyarea	= cfb_copyarea,
1041	.fb_imageblit	= cfb_imageblit,
1042};
1043
1044/*
1045 * sysfs
1046 */
1047
1048static ssize_t gbefb_show_memsize(struct device *dev, struct device_attribute *attr, char *buf)
1049{
1050	return snprintf(buf, PAGE_SIZE, "%d\n", gbe_mem_size);
1051}
1052
1053static DEVICE_ATTR(size, S_IRUGO, gbefb_show_memsize, NULL);
1054
1055static ssize_t gbefb_show_rev(struct device *device, struct device_attribute *attr, char *buf)
1056{
1057	return snprintf(buf, PAGE_SIZE, "%d\n", gbe_revision);
1058}
1059
1060static DEVICE_ATTR(revision, S_IRUGO, gbefb_show_rev, NULL);
1061
1062static void __devexit gbefb_remove_sysfs(struct device *dev)
1063{
1064	device_remove_file(dev, &dev_attr_size);
1065	device_remove_file(dev, &dev_attr_revision);
1066}
1067
1068static void gbefb_create_sysfs(struct device *dev)
1069{
1070	device_create_file(dev, &dev_attr_size);
1071	device_create_file(dev, &dev_attr_revision);
1072}
1073
1074/*
1075 * Initialization
1076 */
1077
1078int __init gbefb_setup(char *options)
1079{
1080	char *this_opt;
1081
1082	if (!options || !*options)
1083		return 0;
1084
1085	while ((this_opt = strsep(&options, ",")) != NULL) {
1086		if (!strncmp(this_opt, "monitor:", 8)) {
1087			if (!strncmp(this_opt + 8, "crt", 3)) {
1088				flat_panel_enabled = 0;
1089				default_var = &default_var_CRT;
1090				default_mode = &default_mode_CRT;
1091			} else if (!strncmp(this_opt + 8, "1600sw", 6) ||
1092				   !strncmp(this_opt + 8, "lcd", 3)) {
1093				flat_panel_enabled = 1;
1094				default_var = &default_var_LCD;
1095				default_mode = &default_mode_LCD;
1096			}
1097		} else if (!strncmp(this_opt, "mem:", 4)) {
1098			gbe_mem_size = memparse(this_opt + 4, &this_opt);
1099			if (gbe_mem_size > CONFIG_FB_GBE_MEM * 1024 * 1024)
1100				gbe_mem_size = CONFIG_FB_GBE_MEM * 1024 * 1024;
1101			if (gbe_mem_size < TILE_SIZE)
1102				gbe_mem_size = TILE_SIZE;
1103		} else
1104			mode_option = this_opt;
1105	}
1106	return 0;
1107}
1108
1109static int __init gbefb_probe(struct platform_device *p_dev)
1110{
1111	int i, ret = 0;
1112	struct fb_info *info;
1113	struct gbefb_par *par;
1114#ifndef MODULE
1115	char *options = NULL;
1116#endif
1117
1118	info = framebuffer_alloc(sizeof(struct gbefb_par), &p_dev->dev);
1119	if (!info)
1120		return -ENOMEM;
1121
1122#ifndef MODULE
1123	if (fb_get_options("gbefb", &options))
1124		return -ENODEV;
1125	gbefb_setup(options);
1126#endif
1127
1128	if (!request_region(GBE_BASE, sizeof(struct sgi_gbe), "GBE")) {
1129		printk(KERN_ERR "gbefb: couldn't reserve mmio region\n");
1130		ret = -EBUSY;
1131		goto out_release_framebuffer;
1132	}
1133
1134	gbe = (struct sgi_gbe *) ioremap(GBE_BASE, sizeof(struct sgi_gbe));
1135	if (!gbe) {
1136		printk(KERN_ERR "gbefb: couldn't map mmio region\n");
1137		ret = -ENXIO;
1138		goto out_release_mem_region;
1139	}
1140	gbe_revision = gbe->ctrlstat & 15;
1141
1142	gbe_tiles.cpu =
1143		dma_alloc_coherent(NULL, GBE_TLB_SIZE * sizeof(uint16_t),
1144				   &gbe_tiles.dma, GFP_KERNEL);
1145	if (!gbe_tiles.cpu) {
1146		printk(KERN_ERR "gbefb: couldn't allocate tiles table\n");
1147		ret = -ENOMEM;
1148		goto out_unmap;
1149	}
1150
1151	if (gbe_mem_phys) {
1152		/* memory was allocated at boot time */
1153		gbe_mem = ioremap_nocache(gbe_mem_phys, gbe_mem_size);
1154		if (!gbe_mem) {
1155			printk(KERN_ERR "gbefb: couldn't map framebuffer\n");
1156			ret = -ENOMEM;
1157			goto out_tiles_free;
1158		}
1159
1160		gbe_dma_addr = 0;
1161	} else {
1162		/* try to allocate memory with the classical allocator
1163		 * this has high chance to fail on low memory machines */
1164		gbe_mem = dma_alloc_coherent(NULL, gbe_mem_size, &gbe_dma_addr,
1165					     GFP_KERNEL);
1166		if (!gbe_mem) {
1167			printk(KERN_ERR "gbefb: couldn't allocate framebuffer memory\n");
1168			ret = -ENOMEM;
1169			goto out_tiles_free;
1170		}
1171
1172		gbe_mem_phys = (unsigned long) gbe_dma_addr;
1173	}
1174
1175#ifdef CONFIG_X86
1176	mtrr_add(gbe_mem_phys, gbe_mem_size, MTRR_TYPE_WRCOMB, 1);
1177#endif
1178
1179	/* map framebuffer memory into tiles table */
1180	for (i = 0; i < (gbe_mem_size >> TILE_SHIFT); i++)
1181		gbe_tiles.cpu[i] = (gbe_mem_phys >> TILE_SHIFT) + i;
1182
1183	info->fbops = &gbefb_ops;
1184	info->pseudo_palette = pseudo_palette;
1185	info->flags = FBINFO_DEFAULT;
1186	info->screen_base = gbe_mem;
1187	fb_alloc_cmap(&info->cmap, 256, 0);
1188
1189	/* reset GBE */
1190	gbe_reset();
1191
1192	par = info->par;
1193	/* turn on default video mode */
1194	if (fb_find_mode(&par->var, info, mode_option, NULL, 0,
1195			 default_mode, 8) == 0)
1196		par->var = *default_var;
1197	info->var = par->var;
1198	gbefb_check_var(&par->var, info);
1199	gbefb_encode_fix(&info->fix, &info->var);
1200
1201	if (register_framebuffer(info) < 0) {
1202		printk(KERN_ERR "gbefb: couldn't register framebuffer\n");
1203		ret = -ENXIO;
1204		goto out_gbe_unmap;
1205	}
1206
1207	platform_set_drvdata(p_dev, info);
1208	gbefb_create_sysfs(&p_dev->dev);
1209
1210	printk(KERN_INFO "fb%d: %s rev %d @ 0x%08x using %dkB memory\n",
1211	       info->node, info->fix.id, gbe_revision, (unsigned) GBE_BASE,
1212	       gbe_mem_size >> 10);
1213
1214	return 0;
1215
1216out_gbe_unmap:
1217	if (gbe_dma_addr)
1218		dma_free_coherent(NULL, gbe_mem_size, gbe_mem, gbe_mem_phys);
1219	else
1220		iounmap(gbe_mem);
1221out_tiles_free:
1222	dma_free_coherent(NULL, GBE_TLB_SIZE * sizeof(uint16_t),
1223			  (void *)gbe_tiles.cpu, gbe_tiles.dma);
1224out_unmap:
1225	iounmap(gbe);
1226out_release_mem_region:
1227	release_mem_region(GBE_BASE, sizeof(struct sgi_gbe));
1228out_release_framebuffer:
1229	framebuffer_release(info);
1230
1231	return ret;
1232}
1233
1234static int __devexit gbefb_remove(struct platform_device* p_dev)
1235{
1236	struct fb_info *info = platform_get_drvdata(p_dev);
1237
1238	unregister_framebuffer(info);
1239	gbe_turn_off();
1240	if (gbe_dma_addr)
1241		dma_free_coherent(NULL, gbe_mem_size, gbe_mem, gbe_mem_phys);
1242	else
1243		iounmap(gbe_mem);
1244	dma_free_coherent(NULL, GBE_TLB_SIZE * sizeof(uint16_t),
1245			  (void *)gbe_tiles.cpu, gbe_tiles.dma);
1246	release_mem_region(GBE_BASE, sizeof(struct sgi_gbe));
1247	iounmap(gbe);
1248	gbefb_remove_sysfs(&p_dev->dev);
1249	framebuffer_release(info);
1250
1251	return 0;
1252}
1253
1254static struct platform_driver gbefb_driver = {
1255	.probe = gbefb_probe,
1256	.remove = __devexit_p(gbefb_remove),
1257	.driver	= {
1258		.name = "gbefb",
1259	},
1260};
1261
1262static struct platform_device *gbefb_device;
1263
1264int __init gbefb_init(void)
1265{
1266	int ret = platform_driver_register(&gbefb_driver);
1267	if (!ret) {
1268		gbefb_device = platform_device_alloc("gbefb", 0);
1269		if (gbefb_device) {
1270			ret = platform_device_add(gbefb_device);
1271		} else {
1272			ret = -ENOMEM;
1273		}
1274		if (ret) {
1275			platform_device_put(gbefb_device);
1276			platform_driver_unregister(&gbefb_driver);
1277		}
1278	}
1279	return ret;
1280}
1281
1282void __exit gbefb_exit(void)
1283{
1284	platform_device_unregister(gbefb_device);
1285	platform_driver_unregister(&gbefb_driver);
1286}
1287
1288module_init(gbefb_init);
1289module_exit(gbefb_exit);
1290
1291MODULE_LICENSE("GPL");
1292