1
2
3
4
5
6
7
8
9
10
11
12#include <linux/delay.h>
13#include <linux/platform_device.h>
14#include <linux/dma-mapping.h>
15#include <linux/errno.h>
16#include <linux/fb.h>
17#include <linux/init.h>
18#include <linux/interrupt.h>
19#include <linux/kernel.h>
20#include <linux/mm.h>
21#include <linux/module.h>
22
23#ifdef CONFIG_X86
24#include <asm/mtrr.h>
25#endif
26#ifdef CONFIG_MIPS
27#include <asm/addrspace.h>
28#endif
29#include <asm/byteorder.h>
30#include <asm/io.h>
31#include <asm/tlbflush.h>
32
33#include <video/gbe.h>
34
35static struct sgi_gbe *gbe;
36
37struct gbefb_par {
38 struct fb_var_screeninfo var;
39 struct gbe_timing_info timing;
40 int valid;
41};
42
43#ifdef CONFIG_SGI_IP32
44#define GBE_BASE 0x16000000
45#endif
46
47#ifdef CONFIG_X86_VISWS
48#define GBE_BASE 0xd0000000
49#endif
50
51
52#ifdef CONFIG_MIPS
53#ifdef CONFIG_CPU_R10000
54#define pgprot_fb(_prot) (((_prot) & (~_CACHE_MASK)) | _CACHE_UNCACHED_ACCELERATED)
55#else
56#define pgprot_fb(_prot) (((_prot) & (~_CACHE_MASK)) | _CACHE_CACHABLE_NO_WA)
57#endif
58#endif
59#ifdef CONFIG_X86
60#define pgprot_fb(_prot) ((_prot) | _PAGE_PCD)
61#endif
62
63
64
65
66
67#if CONFIG_FB_GBE_MEM > 8
68#error GBE Framebuffer cannot use more than 8MB of memory
69#endif
70
71#define TILE_SHIFT 16
72#define TILE_SIZE (1 << TILE_SHIFT)
73#define TILE_MASK (TILE_SIZE - 1)
74
75static unsigned int gbe_mem_size = CONFIG_FB_GBE_MEM * 1024*1024;
76static void *gbe_mem;
77static dma_addr_t gbe_dma_addr;
78static unsigned long gbe_mem_phys;
79
80static struct {
81 uint16_t *cpu;
82 dma_addr_t dma;
83} gbe_tiles;
84
85static int gbe_revision;
86
87static int ypan, ywrap;
88
89static uint32_t pseudo_palette[16];
90static uint32_t gbe_cmap[256];
91static int gbe_turned_on;
92
93static char *mode_option __initdata = NULL;
94
95
96static struct fb_var_screeninfo default_var_CRT __initdata = {
97
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,
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
127static struct fb_var_screeninfo default_var_LCD __initdata = {
128
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
158
159static 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
174static struct fb_videomode default_mode_LCD __initdata = {
175
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
188static struct fb_videomode *default_mode __initdata = &default_mode_CRT;
189static struct fb_var_screeninfo *default_var __initdata = &default_var_CRT;
190
191static int flat_panel_enabled = 0;
192
193static void gbe_reset(void)
194{
195
196 gbe->ctrlstat = 0x300aa000;
197}
198
199
200
201
202
203
204
205
206
207
208static void gbe_turn_off(void)
209{
210 int i;
211 unsigned int val, x, y, vpixen_off;
212
213 gbe_turned_on = 0;
214
215
216 val = gbe->vt_xy;
217 if (GET_GBE_FIELD(VT_XY, FREEZE, val) == 1)
218 return;
219
220
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
235
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
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
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
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
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
320static void gbe_turn_on(void)
321{
322 unsigned int val, i;
323
324
325
326
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
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
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
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 gbe_turned_on = 1;
380}
381
382static void gbe_loadcmap(void)
383{
384 int i, j;
385
386 for (i = 0; i < 256; i++) {
387 for (j = 0; j < 1000 && gbe->cm_fifo >= 63; j++)
388 udelay(10);
389 if (j == 1000)
390 printk(KERN_ERR "gbefb: cmap FIFO timeout\n");
391
392 gbe->cmap[i] = gbe_cmap[i];
393 }
394}
395
396
397
398
399static int gbefb_blank(int blank, struct fb_info *info)
400{
401
402 switch (blank) {
403 case FB_BLANK_UNBLANK:
404 gbe_turn_on();
405 gbe_loadcmap();
406 break;
407
408 case FB_BLANK_NORMAL:
409 gbe_turn_off();
410 break;
411
412 default:
413
414 break;
415 }
416 return 0;
417}
418
419
420
421
422static void gbefb_setup_flatpanel(struct gbe_timing_info *timing)
423{
424 int fp_wid, fp_hgt, fp_vbs, fp_vbe;
425 u32 outputVal = 0;
426
427 SET_GBE_FIELD(VT_FLAGS, HDRV_INVERT, outputVal,
428 (timing->flags & FB_SYNC_HOR_HIGH_ACT) ? 0 : 1);
429 SET_GBE_FIELD(VT_FLAGS, VDRV_INVERT, outputVal,
430 (timing->flags & FB_SYNC_VERT_HIGH_ACT) ? 0 : 1);
431 gbe->vt_flags = outputVal;
432
433
434 fp_wid = 1600;
435 fp_hgt = 1024;
436 fp_vbs = 0;
437 fp_vbe = 1600;
438 timing->pll_m = 4;
439 timing->pll_n = 1;
440 timing->pll_p = 0;
441
442 outputVal = 0;
443 SET_GBE_FIELD(FP_DE, ON, outputVal, fp_vbs);
444 SET_GBE_FIELD(FP_DE, OFF, outputVal, fp_vbe);
445 gbe->fp_de = outputVal;
446 outputVal = 0;
447 SET_GBE_FIELD(FP_HDRV, OFF, outputVal, fp_wid);
448 gbe->fp_hdrv = outputVal;
449 outputVal = 0;
450 SET_GBE_FIELD(FP_VDRV, ON, outputVal, 1);
451 SET_GBE_FIELD(FP_VDRV, OFF, outputVal, fp_hgt + 1);
452 gbe->fp_vdrv = outputVal;
453}
454
455struct gbe_pll_info {
456 int clock_rate;
457 int fvco_min;
458 int fvco_max;
459};
460
461static struct gbe_pll_info gbe_pll_table[2] = {
462 { 20, 80, 220 },
463 { 27, 80, 220 },
464};
465
466static int compute_gbe_timing(struct fb_var_screeninfo *var,
467 struct gbe_timing_info *timing)
468{
469 int pll_m, pll_n, pll_p, error, best_m, best_n, best_p, best_error;
470 int pixclock;
471 struct gbe_pll_info *gbe_pll;
472
473 if (gbe_revision < 2)
474 gbe_pll = &gbe_pll_table[0];
475 else
476 gbe_pll = &gbe_pll_table[1];
477
478
479
480
481
482
483 best_error = 1000000000;
484 best_n = best_m = best_p = 0;
485 for (pll_p = 0; pll_p < 4; pll_p++)
486 for (pll_m = 1; pll_m < 256; pll_m++)
487 for (pll_n = 1; pll_n < 64; pll_n++) {
488 pixclock = (1000000 / gbe_pll->clock_rate) *
489 (pll_n << pll_p) / pll_m;
490
491 error = var->pixclock - pixclock;
492
493 if (error < 0)
494 error = -error;
495
496 if (error < best_error &&
497 pll_m / pll_n >
498 gbe_pll->fvco_min / gbe_pll->clock_rate &&
499 pll_m / pll_n <
500 gbe_pll->fvco_max / gbe_pll->clock_rate) {
501 best_error = error;
502 best_m = pll_m;
503 best_n = pll_n;
504 best_p = pll_p;
505 }
506 }
507
508 if (!best_n || !best_m)
509 return -EINVAL;
510
511 pixclock = (1000000 / gbe_pll->clock_rate) *
512 (best_n << best_p) / best_m;
513
514
515 if (timing) {
516 timing->width = var->xres;
517 timing->height = var->yres;
518 timing->pll_m = best_m;
519 timing->pll_n = best_n;
520 timing->pll_p = best_p;
521 timing->cfreq = gbe_pll->clock_rate * 1000 * timing->pll_m /
522 (timing->pll_n << timing->pll_p);
523 timing->htotal = var->left_margin + var->xres +
524 var->right_margin + var->hsync_len;
525 timing->vtotal = var->upper_margin + var->yres +
526 var->lower_margin + var->vsync_len;
527 timing->fields_sec = 1000 * timing->cfreq / timing->htotal *
528 1000 / timing->vtotal;
529 timing->hblank_start = var->xres;
530 timing->vblank_start = var->yres;
531 timing->hblank_end = timing->htotal;
532 timing->hsync_start = var->xres + var->right_margin + 1;
533 timing->hsync_end = timing->hsync_start + var->hsync_len;
534 timing->vblank_end = timing->vtotal;
535 timing->vsync_start = var->yres + var->lower_margin + 1;
536 timing->vsync_end = timing->vsync_start + var->vsync_len;
537 }
538
539 return pixclock;
540}
541
542static void gbe_set_timing_info(struct gbe_timing_info *timing)
543{
544 int temp;
545 unsigned int val;
546
547
548 val = 0;
549 SET_GBE_FIELD(DOTCLK, M, val, timing->pll_m - 1);
550 SET_GBE_FIELD(DOTCLK, N, val, timing->pll_n - 1);
551 SET_GBE_FIELD(DOTCLK, P, val, timing->pll_p);
552 SET_GBE_FIELD(DOTCLK, RUN, val, 0);
553 gbe->dotclock = val;
554 udelay(10000);
555
556
557 val = 0;
558 SET_GBE_FIELD(VT_XYMAX, MAXX, val, timing->htotal);
559 SET_GBE_FIELD(VT_XYMAX, MAXY, val, timing->vtotal);
560 gbe->vt_xymax = val;
561
562
563 val = 0;
564 SET_GBE_FIELD(VT_VSYNC, VSYNC_ON, val, timing->vsync_start);
565 SET_GBE_FIELD(VT_VSYNC, VSYNC_OFF, val, timing->vsync_end);
566 gbe->vt_vsync = val;
567 val = 0;
568 SET_GBE_FIELD(VT_HSYNC, HSYNC_ON, val, timing->hsync_start);
569 SET_GBE_FIELD(VT_HSYNC, HSYNC_OFF, val, timing->hsync_end);
570 gbe->vt_hsync = val;
571 val = 0;
572 SET_GBE_FIELD(VT_VBLANK, VBLANK_ON, val, timing->vblank_start);
573 SET_GBE_FIELD(VT_VBLANK, VBLANK_OFF, val, timing->vblank_end);
574 gbe->vt_vblank = val;
575 val = 0;
576 SET_GBE_FIELD(VT_HBLANK, HBLANK_ON, val,
577 timing->hblank_start - 5);
578 SET_GBE_FIELD(VT_HBLANK, HBLANK_OFF, val,
579 timing->hblank_end - 3);
580 gbe->vt_hblank = val;
581
582
583 val = 0;
584 SET_GBE_FIELD(VT_VCMAP, VCMAP_ON, val, timing->vblank_start);
585 SET_GBE_FIELD(VT_VCMAP, VCMAP_OFF, val, timing->vblank_end);
586 gbe->vt_vcmap = val;
587 val = 0;
588 SET_GBE_FIELD(VT_HCMAP, HCMAP_ON, val, timing->hblank_start);
589 SET_GBE_FIELD(VT_HCMAP, HCMAP_OFF, val, timing->hblank_end);
590 gbe->vt_hcmap = val;
591
592 val = 0;
593 temp = timing->vblank_start - timing->vblank_end - 1;
594 if (temp > 0)
595 temp = -temp;
596
597 if (flat_panel_enabled)
598 gbefb_setup_flatpanel(timing);
599
600 SET_GBE_FIELD(DID_START_XY, DID_STARTY, val, (u32) temp);
601 if (timing->hblank_end >= 20)
602 SET_GBE_FIELD(DID_START_XY, DID_STARTX, val,
603 timing->hblank_end - 20);
604 else
605 SET_GBE_FIELD(DID_START_XY, DID_STARTX, val,
606 timing->htotal - (20 - timing->hblank_end));
607 gbe->did_start_xy = val;
608
609 val = 0;
610 SET_GBE_FIELD(CRS_START_XY, CRS_STARTY, val, (u32) (temp + 1));
611 if (timing->hblank_end >= GBE_CRS_MAGIC)
612 SET_GBE_FIELD(CRS_START_XY, CRS_STARTX, val,
613 timing->hblank_end - GBE_CRS_MAGIC);
614 else
615 SET_GBE_FIELD(CRS_START_XY, CRS_STARTX, val,
616 timing->htotal - (GBE_CRS_MAGIC -
617 timing->hblank_end));
618 gbe->crs_start_xy = val;
619
620 val = 0;
621 SET_GBE_FIELD(VC_START_XY, VC_STARTY, val, (u32) temp);
622 SET_GBE_FIELD(VC_START_XY, VC_STARTX, val, timing->hblank_end - 4);
623 gbe->vc_start_xy = val;
624
625 val = 0;
626 temp = timing->hblank_end - GBE_PIXEN_MAGIC_ON;
627 if (temp < 0)
628 temp += timing->htotal;
629
630 SET_GBE_FIELD(VT_HPIXEN, HPIXEN_ON, val, temp);
631 SET_GBE_FIELD(VT_HPIXEN, HPIXEN_OFF, val,
632 ((temp + timing->width -
633 GBE_PIXEN_MAGIC_OFF) % timing->htotal));
634 gbe->vt_hpixen = val;
635
636 val = 0;
637 SET_GBE_FIELD(VT_VPIXEN, VPIXEN_ON, val, timing->vblank_end);
638 SET_GBE_FIELD(VT_VPIXEN, VPIXEN_OFF, val, timing->vblank_start);
639 gbe->vt_vpixen = val;
640
641
642 val = 0;
643 SET_GBE_FIELD(VT_FLAGS, SYNC_LOW, val, 1);
644 gbe->vt_flags = val;
645}
646
647
648
649
650
651static int gbefb_set_par(struct fb_info *info)
652{
653 int i;
654 unsigned int val;
655 int wholeTilesX, partTilesX, maxPixelsPerTileX;
656 int height_pix;
657 int xpmax, ypmax;
658 int bytesPerPixel;
659 struct gbefb_par *par = (struct gbefb_par *) info->par;
660
661 compute_gbe_timing(&info->var, &par->timing);
662
663 bytesPerPixel = info->var.bits_per_pixel / 8;
664 info->fix.line_length = info->var.xres_virtual * bytesPerPixel;
665 xpmax = par->timing.width;
666 ypmax = par->timing.height;
667
668
669 gbe_turn_off();
670
671
672 gbe_set_timing_info(&par->timing);
673
674
675 val = 0;
676 switch (bytesPerPixel) {
677 case 1:
678 SET_GBE_FIELD(WID, TYP, val, GBE_CMODE_I8);
679 info->fix.visual = FB_VISUAL_PSEUDOCOLOR;
680 break;
681 case 2:
682 SET_GBE_FIELD(WID, TYP, val, GBE_CMODE_ARGB5);
683 info->fix.visual = FB_VISUAL_TRUECOLOR;
684 break;
685 case 4:
686 SET_GBE_FIELD(WID, TYP, val, GBE_CMODE_RGB8);
687 info->fix.visual = FB_VISUAL_TRUECOLOR;
688 break;
689 }
690 SET_GBE_FIELD(WID, BUF, val, GBE_BMODE_BOTH);
691
692 for (i = 0; i < 32; i++)
693 gbe->mode_regs[i] = val;
694
695
696 gbe->vt_intr01 = 0xffffffff;
697 gbe->vt_intr23 = 0xffffffff;
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766 val = 0;
767 SET_GBE_FIELD(FRM_CONTROL, FRM_TILE_PTR, val, gbe_tiles.dma >> 9);
768 SET_GBE_FIELD(FRM_CONTROL, FRM_DMA_ENABLE, val, 0);
769 SET_GBE_FIELD(FRM_CONTROL, FRM_LINEAR, val, 0);
770 gbe->frm_control = val;
771
772 maxPixelsPerTileX = 512 / bytesPerPixel;
773 wholeTilesX = 1;
774 partTilesX = 0;
775
776
777 val = 0;
778 SET_GBE_FIELD(FRM_SIZE_TILE, FRM_WIDTH_TILE, val, wholeTilesX);
779 SET_GBE_FIELD(FRM_SIZE_TILE, FRM_RHS, val, partTilesX);
780
781 switch (bytesPerPixel) {
782 case 1:
783 SET_GBE_FIELD(FRM_SIZE_TILE, FRM_DEPTH, val,
784 GBE_FRM_DEPTH_8);
785 break;
786 case 2:
787 SET_GBE_FIELD(FRM_SIZE_TILE, FRM_DEPTH, val,
788 GBE_FRM_DEPTH_16);
789 break;
790 case 4:
791 SET_GBE_FIELD(FRM_SIZE_TILE, FRM_DEPTH, val,
792 GBE_FRM_DEPTH_32);
793 break;
794 }
795 gbe->frm_size_tile = val;
796
797
798 height_pix = xpmax * ypmax / maxPixelsPerTileX;
799
800 val = 0;
801 SET_GBE_FIELD(FRM_SIZE_PIXEL, FB_HEIGHT_PIX, val, height_pix);
802 gbe->frm_size_pixel = val;
803
804
805 gbe->did_control = 0;
806 gbe->ovr_width_tile = 0;
807
808
809 gbe->crs_ctl = 0;
810
811
812 gbe_turn_on();
813
814
815 udelay(10);
816 for (i = 0; i < 256; i++)
817 gbe->gmap[i] = (i << 24) | (i << 16) | (i << 8);
818
819
820 for (i = 0; i < 256; i++)
821 gbe_cmap[i] = (i << 8) | (i << 16) | (i << 24);
822
823 gbe_loadcmap();
824
825 return 0;
826}
827
828static void gbefb_encode_fix(struct fb_fix_screeninfo *fix,
829 struct fb_var_screeninfo *var)
830{
831 memset(fix, 0, sizeof(struct fb_fix_screeninfo));
832 strcpy(fix->id, "SGI GBE");
833 fix->smem_start = (unsigned long) gbe_mem;
834 fix->smem_len = gbe_mem_size;
835 fix->type = FB_TYPE_PACKED_PIXELS;
836 fix->type_aux = 0;
837 fix->accel = FB_ACCEL_NONE;
838 switch (var->bits_per_pixel) {
839 case 8:
840 fix->visual = FB_VISUAL_PSEUDOCOLOR;
841 break;
842 default:
843 fix->visual = FB_VISUAL_TRUECOLOR;
844 break;
845 }
846 fix->ywrapstep = 0;
847 fix->xpanstep = 0;
848 fix->ypanstep = 0;
849 fix->line_length = var->xres_virtual * var->bits_per_pixel / 8;
850 fix->mmio_start = GBE_BASE;
851 fix->mmio_len = sizeof(struct sgi_gbe);
852}
853
854
855
856
857
858
859
860static int gbefb_setcolreg(unsigned regno, unsigned red, unsigned green,
861 unsigned blue, unsigned transp,
862 struct fb_info *info)
863{
864 int i;
865
866 if (regno > 255)
867 return 1;
868 red >>= 8;
869 green >>= 8;
870 blue >>= 8;
871
872 if (info->var.bits_per_pixel <= 8) {
873 gbe_cmap[regno] = (red << 24) | (green << 16) | (blue << 8);
874 if (gbe_turned_on) {
875
876 for (i = 0; i < 1000 && gbe->cm_fifo >= 63; i++)
877 udelay(10);
878 if (i == 1000) {
879 printk(KERN_ERR "gbefb: cmap FIFO timeout\n");
880 return 1;
881 }
882 gbe->cmap[regno] = gbe_cmap[regno];
883 }
884 } else if (regno < 16) {
885 switch (info->var.bits_per_pixel) {
886 case 15:
887 case 16:
888 red >>= 3;
889 green >>= 3;
890 blue >>= 3;
891 pseudo_palette[regno] =
892 (red << info->var.red.offset) |
893 (green << info->var.green.offset) |
894 (blue << info->var.blue.offset);
895 break;
896 case 32:
897 pseudo_palette[regno] =
898 (red << info->var.red.offset) |
899 (green << info->var.green.offset) |
900 (blue << info->var.blue.offset);
901 break;
902 }
903 }
904
905 return 0;
906}
907
908
909
910
911static int gbefb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
912{
913 unsigned int line_length;
914 struct gbe_timing_info timing;
915 int ret;
916
917
918 if (var->bits_per_pixel <= 8)
919 var->bits_per_pixel = 8;
920 else if (var->bits_per_pixel <= 16)
921 var->bits_per_pixel = 16;
922 else if (var->bits_per_pixel <= 32)
923 var->bits_per_pixel = 32;
924 else
925 return -EINVAL;
926
927
928
929 if ((var->xres * var->yres * var->bits_per_pixel) & 4095)
930 return -EINVAL;
931
932 var->grayscale = 0;
933
934 ret = compute_gbe_timing(var, &timing);
935 var->pixclock = ret;
936 if (ret < 0)
937 return -EINVAL;
938
939
940 if (var->xres > var->xres_virtual || (!ywrap && !ypan))
941 var->xres_virtual = var->xres;
942 if (var->yres > var->yres_virtual || (!ywrap && !ypan))
943 var->yres_virtual = var->yres;
944
945 if (var->vmode & FB_VMODE_CONUPDATE) {
946 var->vmode |= FB_VMODE_YWRAP;
947 var->xoffset = info->var.xoffset;
948 var->yoffset = info->var.yoffset;
949 }
950
951
952 var->grayscale = 0;
953
954
955 line_length = var->xres_virtual * var->bits_per_pixel / 8;
956 if (line_length * var->yres_virtual > gbe_mem_size)
957 return -ENOMEM;
958
959 switch (var->bits_per_pixel) {
960 case 8:
961 var->red.offset = 0;
962 var->red.length = 8;
963 var->green.offset = 0;
964 var->green.length = 8;
965 var->blue.offset = 0;
966 var->blue.length = 8;
967 var->transp.offset = 0;
968 var->transp.length = 0;
969 break;
970 case 16:
971 var->red.offset = 10;
972 var->red.length = 5;
973 var->green.offset = 5;
974 var->green.length = 5;
975 var->blue.offset = 0;
976 var->blue.length = 5;
977 var->transp.offset = 0;
978 var->transp.length = 0;
979 break;
980 case 32:
981 var->red.offset = 24;
982 var->red.length = 8;
983 var->green.offset = 16;
984 var->green.length = 8;
985 var->blue.offset = 8;
986 var->blue.length = 8;
987 var->transp.offset = 0;
988 var->transp.length = 8;
989 break;
990 }
991 var->red.msb_right = 0;
992 var->green.msb_right = 0;
993 var->blue.msb_right = 0;
994 var->transp.msb_right = 0;
995
996 var->left_margin = timing.htotal - timing.hsync_end;
997 var->right_margin = timing.hsync_start - timing.width;
998 var->upper_margin = timing.vtotal - timing.vsync_end;
999 var->lower_margin = timing.vsync_start - timing.height;
1000 var->hsync_len = timing.hsync_end - timing.hsync_start;
1001 var->vsync_len = timing.vsync_end - timing.vsync_start;
1002
1003 return 0;
1004}
1005
1006static int gbefb_mmap(struct fb_info *info,
1007 struct vm_area_struct *vma)
1008{
1009 unsigned long size = vma->vm_end - vma->vm_start;
1010 unsigned long offset = vma->vm_pgoff << PAGE_SHIFT;
1011 unsigned long addr;
1012 unsigned long phys_addr, phys_size;
1013 u16 *tile;
1014
1015
1016 if (vma->vm_pgoff > (~0UL >> PAGE_SHIFT))
1017 return -EINVAL;
1018 if (offset + size > gbe_mem_size)
1019 return -EINVAL;
1020
1021
1022
1023 pgprot_val(vma->vm_page_prot) =
1024 pgprot_fb(pgprot_val(vma->vm_page_prot));
1025
1026 vma->vm_flags |= VM_IO | VM_RESERVED;
1027
1028
1029 tile = &gbe_tiles.cpu[offset >> TILE_SHIFT];
1030 addr = vma->vm_start;
1031 offset &= TILE_MASK;
1032
1033
1034 do {
1035 phys_addr = (((unsigned long) (*tile)) << TILE_SHIFT) + offset;
1036 if ((offset + size) < TILE_SIZE)
1037 phys_size = size;
1038 else
1039 phys_size = TILE_SIZE - offset;
1040
1041 if (remap_pfn_range(vma, addr, phys_addr >> PAGE_SHIFT,
1042 phys_size, vma->vm_page_prot))
1043 return -EAGAIN;
1044
1045 offset = 0;
1046 size -= phys_size;
1047 addr += phys_size;
1048 tile++;
1049 } while (size);
1050
1051 return 0;
1052}
1053
1054static struct fb_ops gbefb_ops = {
1055 .owner = THIS_MODULE,
1056 .fb_check_var = gbefb_check_var,
1057 .fb_set_par = gbefb_set_par,
1058 .fb_setcolreg = gbefb_setcolreg,
1059 .fb_mmap = gbefb_mmap,
1060 .fb_blank = gbefb_blank,
1061 .fb_fillrect = cfb_fillrect,
1062 .fb_copyarea = cfb_copyarea,
1063 .fb_imageblit = cfb_imageblit,
1064};
1065
1066
1067
1068
1069
1070static ssize_t gbefb_show_memsize(struct device *dev, struct device_attribute *attr, char *buf)
1071{
1072 return snprintf(buf, PAGE_SIZE, "%d\n", gbe_mem_size);
1073}
1074
1075static DEVICE_ATTR(size, S_IRUGO, gbefb_show_memsize, NULL);
1076
1077static ssize_t gbefb_show_rev(struct device *device, struct device_attribute *attr, char *buf)
1078{
1079 return snprintf(buf, PAGE_SIZE, "%d\n", gbe_revision);
1080}
1081
1082static DEVICE_ATTR(revision, S_IRUGO, gbefb_show_rev, NULL);
1083
1084static void __devexit gbefb_remove_sysfs(struct device *dev)
1085{
1086 device_remove_file(dev, &dev_attr_size);
1087 device_remove_file(dev, &dev_attr_revision);
1088}
1089
1090static void gbefb_create_sysfs(struct device *dev)
1091{
1092 device_create_file(dev, &dev_attr_size);
1093 device_create_file(dev, &dev_attr_revision);
1094}
1095
1096
1097
1098
1099
1100static int __init gbefb_setup(char *options)
1101{
1102 char *this_opt;
1103
1104 if (!options || !*options)
1105 return 0;
1106
1107 while ((this_opt = strsep(&options, ",")) != NULL) {
1108 if (!strncmp(this_opt, "monitor:", 8)) {
1109 if (!strncmp(this_opt + 8, "crt", 3)) {
1110 flat_panel_enabled = 0;
1111 default_var = &default_var_CRT;
1112 default_mode = &default_mode_CRT;
1113 } else if (!strncmp(this_opt + 8, "1600sw", 6) ||
1114 !strncmp(this_opt + 8, "lcd", 3)) {
1115 flat_panel_enabled = 1;
1116 default_var = &default_var_LCD;
1117 default_mode = &default_mode_LCD;
1118 }
1119 } else if (!strncmp(this_opt, "mem:", 4)) {
1120 gbe_mem_size = memparse(this_opt + 4, &this_opt);
1121 if (gbe_mem_size > CONFIG_FB_GBE_MEM * 1024 * 1024)
1122 gbe_mem_size = CONFIG_FB_GBE_MEM * 1024 * 1024;
1123 if (gbe_mem_size < TILE_SIZE)
1124 gbe_mem_size = TILE_SIZE;
1125 } else
1126 mode_option = this_opt;
1127 }
1128 return 0;
1129}
1130
1131static int __init gbefb_probe(struct platform_device *p_dev)
1132{
1133 int i, ret = 0;
1134 struct fb_info *info;
1135 struct gbefb_par *par;
1136#ifndef MODULE
1137 char *options = NULL;
1138#endif
1139
1140 info = framebuffer_alloc(sizeof(struct gbefb_par), &p_dev->dev);
1141 if (!info)
1142 return -ENOMEM;
1143
1144#ifndef MODULE
1145 if (fb_get_options("gbefb", &options))
1146 return -ENODEV;
1147 gbefb_setup(options);
1148#endif
1149
1150 if (!request_mem_region(GBE_BASE, sizeof(struct sgi_gbe), "GBE")) {
1151 printk(KERN_ERR "gbefb: couldn't reserve mmio region\n");
1152 ret = -EBUSY;
1153 goto out_release_framebuffer;
1154 }
1155
1156 gbe = (struct sgi_gbe *) ioremap(GBE_BASE, sizeof(struct sgi_gbe));
1157 if (!gbe) {
1158 printk(KERN_ERR "gbefb: couldn't map mmio region\n");
1159 ret = -ENXIO;
1160 goto out_release_mem_region;
1161 }
1162 gbe_revision = gbe->ctrlstat & 15;
1163
1164 gbe_tiles.cpu =
1165 dma_alloc_coherent(NULL, GBE_TLB_SIZE * sizeof(uint16_t),
1166 &gbe_tiles.dma, GFP_KERNEL);
1167 if (!gbe_tiles.cpu) {
1168 printk(KERN_ERR "gbefb: couldn't allocate tiles table\n");
1169 ret = -ENOMEM;
1170 goto out_unmap;
1171 }
1172
1173 if (gbe_mem_phys) {
1174
1175 gbe_mem = ioremap_nocache(gbe_mem_phys, gbe_mem_size);
1176 if (!gbe_mem) {
1177 printk(KERN_ERR "gbefb: couldn't map framebuffer\n");
1178 ret = -ENOMEM;
1179 goto out_tiles_free;
1180 }
1181
1182 gbe_dma_addr = 0;
1183 } else {
1184
1185
1186 gbe_mem = dma_alloc_coherent(NULL, gbe_mem_size, &gbe_dma_addr,
1187 GFP_KERNEL);
1188 if (!gbe_mem) {
1189 printk(KERN_ERR "gbefb: couldn't allocate framebuffer memory\n");
1190 ret = -ENOMEM;
1191 goto out_tiles_free;
1192 }
1193
1194 gbe_mem_phys = (unsigned long) gbe_dma_addr;
1195 }
1196
1197#ifdef CONFIG_X86
1198 mtrr_add(gbe_mem_phys, gbe_mem_size, MTRR_TYPE_WRCOMB, 1);
1199#endif
1200
1201
1202 for (i = 0; i < (gbe_mem_size >> TILE_SHIFT); i++)
1203 gbe_tiles.cpu[i] = (gbe_mem_phys >> TILE_SHIFT) + i;
1204
1205 info->fbops = &gbefb_ops;
1206 info->pseudo_palette = pseudo_palette;
1207 info->flags = FBINFO_DEFAULT;
1208 info->screen_base = gbe_mem;
1209 fb_alloc_cmap(&info->cmap, 256, 0);
1210
1211
1212 gbe_reset();
1213
1214 par = info->par;
1215
1216 if (fb_find_mode(&par->var, info, mode_option, NULL, 0,
1217 default_mode, 8) == 0)
1218 par->var = *default_var;
1219 info->var = par->var;
1220 gbefb_check_var(&par->var, info);
1221 gbefb_encode_fix(&info->fix, &info->var);
1222
1223 if (register_framebuffer(info) < 0) {
1224 printk(KERN_ERR "gbefb: couldn't register framebuffer\n");
1225 ret = -ENXIO;
1226 goto out_gbe_unmap;
1227 }
1228
1229 platform_set_drvdata(p_dev, info);
1230 gbefb_create_sysfs(&p_dev->dev);
1231
1232 printk(KERN_INFO "fb%d: %s rev %d @ 0x%08x using %dkB memory\n",
1233 info->node, info->fix.id, gbe_revision, (unsigned) GBE_BASE,
1234 gbe_mem_size >> 10);
1235
1236 return 0;
1237
1238out_gbe_unmap:
1239 if (gbe_dma_addr)
1240 dma_free_coherent(NULL, gbe_mem_size, gbe_mem, gbe_mem_phys);
1241 else
1242 iounmap(gbe_mem);
1243out_tiles_free:
1244 dma_free_coherent(NULL, GBE_TLB_SIZE * sizeof(uint16_t),
1245 (void *)gbe_tiles.cpu, gbe_tiles.dma);
1246out_unmap:
1247 iounmap(gbe);
1248out_release_mem_region:
1249 release_mem_region(GBE_BASE, sizeof(struct sgi_gbe));
1250out_release_framebuffer:
1251 framebuffer_release(info);
1252
1253 return ret;
1254}
1255
1256static int __devexit gbefb_remove(struct platform_device* p_dev)
1257{
1258 struct fb_info *info = platform_get_drvdata(p_dev);
1259
1260 unregister_framebuffer(info);
1261 gbe_turn_off();
1262 if (gbe_dma_addr)
1263 dma_free_coherent(NULL, gbe_mem_size, gbe_mem, gbe_mem_phys);
1264 else
1265 iounmap(gbe_mem);
1266 dma_free_coherent(NULL, GBE_TLB_SIZE * sizeof(uint16_t),
1267 (void *)gbe_tiles.cpu, gbe_tiles.dma);
1268 release_mem_region(GBE_BASE, sizeof(struct sgi_gbe));
1269 iounmap(gbe);
1270 gbefb_remove_sysfs(&p_dev->dev);
1271 framebuffer_release(info);
1272
1273 return 0;
1274}
1275
1276static struct platform_driver gbefb_driver = {
1277 .probe = gbefb_probe,
1278 .remove = __devexit_p(gbefb_remove),
1279 .driver = {
1280 .name = "gbefb",
1281 },
1282};
1283
1284static struct platform_device *gbefb_device;
1285
1286static int __init gbefb_init(void)
1287{
1288 int ret = platform_driver_register(&gbefb_driver);
1289 if (!ret) {
1290 gbefb_device = platform_device_alloc("gbefb", 0);
1291 if (gbefb_device) {
1292 ret = platform_device_add(gbefb_device);
1293 } else {
1294 ret = -ENOMEM;
1295 }
1296 if (ret) {
1297 platform_device_put(gbefb_device);
1298 platform_driver_unregister(&gbefb_driver);
1299 }
1300 }
1301 return ret;
1302}
1303
1304static void __exit gbefb_exit(void)
1305{
1306 platform_device_unregister(gbefb_device);
1307 platform_driver_unregister(&gbefb_driver);
1308}
1309
1310module_init(gbefb_init);
1311module_exit(gbefb_exit);
1312
1313MODULE_LICENSE("GPL");
1314