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