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