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