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/gfp.h>
17#include <linux/fb.h>
18#include <linux/init.h>
19#include <linux/interrupt.h>
20#include <linux/kernel.h>
21#include <linux/mm.h>
22#include <linux/module.h>
23#include <linux/io.h>
24
25#ifdef CONFIG_X86
26#include <asm/mtrr.h>
27#endif
28#ifdef CONFIG_MIPS
29#include <asm/addrspace.h>
30#endif
31#include <asm/byteorder.h>
32#include <asm/tlbflush.h>
33
34#include <video/gbe.h>
35
36static struct sgi_gbe *gbe;
37
38struct gbefb_par {
39 struct fb_var_screeninfo var;
40 struct gbe_timing_info timing;
41 int valid;
42};
43
44#ifdef CONFIG_SGI_IP32
45#define GBE_BASE 0x16000000
46#endif
47
48#ifdef CONFIG_X86_VISWS
49#define GBE_BASE 0xd0000000
50#endif
51
52
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
66
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
76static unsigned int gbe_mem_size = CONFIG_FB_GBE_MEM * 1024*1024;
77static void *gbe_mem;
78static dma_addr_t gbe_dma_addr;
79static unsigned long gbe_mem_phys;
80
81static struct {
82 uint16_t *cpu;
83 dma_addr_t dma;
84} gbe_tiles;
85
86static int gbe_revision;
87
88static int ypan, ywrap;
89
90static uint32_t pseudo_palette[16];
91static uint32_t gbe_cmap[256];
92static int gbe_turned_on;
93
94static char *mode_option = NULL;
95
96
97static struct fb_var_screeninfo default_var_CRT = {
98
99 .xres = 640,
100 .yres = 480,
101 .xres_virtual = 640,
102 .yres_virtual = 480,
103 .xoffset = 0,
104 .yoffset = 0,
105 .bits_per_pixel = 8,
106 .grayscale = 0,
107 .red = { 0, 8, 0 },
108 .green = { 0, 8, 0 },
109 .blue = { 0, 8, 0 },
110 .transp = { 0, 0, 0 },
111 .nonstd = 0,
112 .activate = 0,
113 .height = -1,
114 .width = -1,
115 .accel_flags = 0,
116 .pixclock = 39722,
117 .left_margin = 48,
118 .right_margin = 16,
119 .upper_margin = 33,
120 .lower_margin = 10,
121 .hsync_len = 96,
122 .vsync_len = 2,
123 .sync = 0,
124 .vmode = FB_VMODE_NONINTERLACED,
125};
126
127
128static struct fb_var_screeninfo default_var_LCD = {
129
130 .xres = 1600,
131 .yres = 1024,
132 .xres_virtual = 1600,
133 .yres_virtual = 1024,
134 .xoffset = 0,
135 .yoffset = 0,
136 .bits_per_pixel = 8,
137 .grayscale = 0,
138 .red = { 0, 8, 0 },
139 .green = { 0, 8, 0 },
140 .blue = { 0, 8, 0 },
141 .transp = { 0, 0, 0 },
142 .nonstd = 0,
143 .activate = 0,
144 .height = -1,
145 .width = -1,
146 .accel_flags = 0,
147 .pixclock = 9353,
148 .left_margin = 20,
149 .right_margin = 30,
150 .upper_margin = 37,
151 .lower_margin = 3,
152 .hsync_len = 20,
153 .vsync_len = 3,
154 .sync = 0,
155 .vmode = FB_VMODE_NONINTERLACED
156};
157
158
159
160static struct fb_videomode default_mode_CRT = {
161 .refresh = 60,
162 .xres = 640,
163 .yres = 480,
164 .pixclock = 39722,
165 .left_margin = 48,
166 .right_margin = 16,
167 .upper_margin = 33,
168 .lower_margin = 10,
169 .hsync_len = 96,
170 .vsync_len = 2,
171 .sync = 0,
172 .vmode = FB_VMODE_NONINTERLACED,
173};
174
175static struct fb_videomode default_mode_LCD = {
176
177 .xres = 1600,
178 .yres = 1024,
179 .pixclock = 9353,
180 .left_margin = 20,
181 .right_margin = 30,
182 .upper_margin = 37,
183 .lower_margin = 3,
184 .hsync_len = 20,
185 .vsync_len = 3,
186 .vmode = FB_VMODE_NONINTERLACED,
187};
188
189static struct fb_videomode *default_mode = &default_mode_CRT;
190static struct fb_var_screeninfo *default_var = &default_var_CRT;
191
192static int flat_panel_enabled = 0;
193
194static void gbe_reset(void)
195{
196
197 gbe->ctrlstat = 0x300aa000;
198}
199
200
201
202
203
204
205
206
207
208
209static void gbe_turn_off(void)
210{
211 int i;
212 unsigned int val, x, y, vpixen_off;
213
214 gbe_turned_on = 0;
215
216
217 val = gbe->vt_xy;
218 if (GET_GBE_FIELD(VT_XY, FREEZE, val) == 1)
219 return;
220
221
222 val = gbe->ovr_control;
223 SET_GBE_FIELD(OVR_CONTROL, OVR_DMA_ENABLE, val, 0);
224 gbe->ovr_control = val;
225 udelay(1000);
226 val = gbe->frm_control;
227 SET_GBE_FIELD(FRM_CONTROL, FRM_DMA_ENABLE, val, 0);
228 gbe->frm_control = val;
229 udelay(1000);
230 val = gbe->did_control;
231 SET_GBE_FIELD(DID_CONTROL, DID_DMA_ENABLE, val, 0);
232 gbe->did_control = val;
233 udelay(1000);
234
235
236
237 for (i = 0; i < 10000; i++) {
238 val = gbe->frm_inhwctrl;
239 if (GET_GBE_FIELD(FRM_INHWCTRL, FRM_DMA_ENABLE, val)) {
240 udelay(10);
241 } else {
242 val = gbe->ovr_inhwctrl;
243 if (GET_GBE_FIELD(OVR_INHWCTRL, OVR_DMA_ENABLE, val)) {
244 udelay(10);
245 } else {
246 val = gbe->did_inhwctrl;
247 if (GET_GBE_FIELD(DID_INHWCTRL, DID_DMA_ENABLE, val)) {
248 udelay(10);
249 } else
250 break;
251 }
252 }
253 }
254 if (i == 10000)
255 printk(KERN_ERR "gbefb: turn off DMA timed out\n");
256
257
258 val = gbe->vt_vpixen;
259 vpixen_off = GET_GBE_FIELD(VT_VPIXEN, VPIXEN_OFF, val);
260
261 for (i = 0; i < 100000; i++) {
262 val = gbe->vt_xy;
263 x = GET_GBE_FIELD(VT_XY, X, val);
264 y = GET_GBE_FIELD(VT_XY, Y, val);
265 if (y < vpixen_off)
266 break;
267 udelay(1);
268 }
269 if (i == 100000)
270 printk(KERN_ERR
271 "gbefb: wait for vpixen_off timed out\n");
272 for (i = 0; i < 10000; i++) {
273 val = gbe->vt_xy;
274 x = GET_GBE_FIELD(VT_XY, X, val);
275 y = GET_GBE_FIELD(VT_XY, Y, val);
276 if (y > vpixen_off)
277 break;
278 udelay(1);
279 }
280 if (i == 10000)
281 printk(KERN_ERR "gbefb: wait for vpixen_off timed out\n");
282
283
284 val = 0;
285 SET_GBE_FIELD(VT_XY, FREEZE, val, 1);
286 gbe->vt_xy = val;
287 udelay(10000);
288 for (i = 0; i < 10000; i++) {
289 val = gbe->vt_xy;
290 if (GET_GBE_FIELD(VT_XY, FREEZE, val) != 1)
291 udelay(10);
292 else
293 break;
294 }
295 if (i == 10000)
296 printk(KERN_ERR "gbefb: turn off pixel clock timed out\n");
297
298
299 val = gbe->dotclock;
300 SET_GBE_FIELD(DOTCLK, RUN, val, 0);
301 gbe->dotclock = val;
302 udelay(10000);
303 for (i = 0; i < 10000; i++) {
304 val = gbe->dotclock;
305 if (GET_GBE_FIELD(DOTCLK, RUN, val))
306 udelay(10);
307 else
308 break;
309 }
310 if (i == 10000)
311 printk(KERN_ERR "gbefb: turn off dotclock timed out\n");
312
313
314 val = gbe->frm_size_tile;
315 SET_GBE_FIELD(FRM_SIZE_TILE, FRM_FIFO_RESET, val, 1);
316 gbe->frm_size_tile = val;
317 SET_GBE_FIELD(FRM_SIZE_TILE, FRM_FIFO_RESET, val, 0);
318 gbe->frm_size_tile = val;
319}
320
321static void gbe_turn_on(void)
322{
323 unsigned int val, i;
324
325
326
327
328
329 if (gbe_revision < 2) {
330 val = gbe->vt_xy;
331 if (GET_GBE_FIELD(VT_XY, FREEZE, val) == 0)
332 return;
333 }
334
335
336 val = gbe->dotclock;
337 SET_GBE_FIELD(DOTCLK, RUN, val, 1);
338 gbe->dotclock = val;
339 udelay(10000);
340 for (i = 0; i < 10000; i++) {
341 val = gbe->dotclock;
342 if (GET_GBE_FIELD(DOTCLK, RUN, val) != 1)
343 udelay(10);
344 else
345 break;
346 }
347 if (i == 10000)
348 printk(KERN_ERR "gbefb: turn on dotclock timed out\n");
349
350
351 val = 0;
352 SET_GBE_FIELD(VT_XY, FREEZE, val, 0);
353 gbe->vt_xy = val;
354 udelay(10000);
355 for (i = 0; i < 10000; i++) {
356 val = gbe->vt_xy;
357 if (GET_GBE_FIELD(VT_XY, FREEZE, val))
358 udelay(10);
359 else
360 break;
361 }
362 if (i == 10000)
363 printk(KERN_ERR "gbefb: turn on pixel clock timed out\n");
364
365
366 val = gbe->frm_control;
367 SET_GBE_FIELD(FRM_CONTROL, FRM_DMA_ENABLE, val, 1);
368 gbe->frm_control = val;
369 udelay(1000);
370 for (i = 0; i < 10000; i++) {
371 val = gbe->frm_inhwctrl;
372 if (GET_GBE_FIELD(FRM_INHWCTRL, FRM_DMA_ENABLE, val) != 1)
373 udelay(10);
374 else
375 break;
376 }
377 if (i == 10000)
378 printk(KERN_ERR "gbefb: turn on DMA timed out\n");
379
380 gbe_turned_on = 1;
381}
382
383static void gbe_loadcmap(void)
384{
385 int i, j;
386
387 for (i = 0; i < 256; i++) {
388 for (j = 0; j < 1000 && gbe->cm_fifo >= 63; j++)
389 udelay(10);
390 if (j == 1000)
391 printk(KERN_ERR "gbefb: cmap FIFO timeout\n");
392
393 gbe->cmap[i] = gbe_cmap[i];
394 }
395}
396
397
398
399
400static int gbefb_blank(int blank, struct fb_info *info)
401{
402
403 switch (blank) {
404 case FB_BLANK_UNBLANK:
405 gbe_turn_on();
406 gbe_loadcmap();
407 break;
408
409 case FB_BLANK_NORMAL:
410 gbe_turn_off();
411 break;
412
413 default:
414
415 break;
416 }
417 return 0;
418}
419
420
421
422
423static void gbefb_setup_flatpanel(struct gbe_timing_info *timing)
424{
425 int fp_wid, fp_hgt, fp_vbs, fp_vbe;
426 u32 outputVal = 0;
427
428 SET_GBE_FIELD(VT_FLAGS, HDRV_INVERT, outputVal,
429 (timing->flags & FB_SYNC_HOR_HIGH_ACT) ? 0 : 1);
430 SET_GBE_FIELD(VT_FLAGS, VDRV_INVERT, outputVal,
431 (timing->flags & FB_SYNC_VERT_HIGH_ACT) ? 0 : 1);
432 gbe->vt_flags = outputVal;
433
434
435 fp_wid = 1600;
436 fp_hgt = 1024;
437 fp_vbs = 0;
438 fp_vbe = 1600;
439 timing->pll_m = 4;
440 timing->pll_n = 1;
441 timing->pll_p = 0;
442
443 outputVal = 0;
444 SET_GBE_FIELD(FP_DE, ON, outputVal, fp_vbs);
445 SET_GBE_FIELD(FP_DE, OFF, outputVal, fp_vbe);
446 gbe->fp_de = outputVal;
447 outputVal = 0;
448 SET_GBE_FIELD(FP_HDRV, OFF, outputVal, fp_wid);
449 gbe->fp_hdrv = outputVal;
450 outputVal = 0;
451 SET_GBE_FIELD(FP_VDRV, ON, outputVal, 1);
452 SET_GBE_FIELD(FP_VDRV, OFF, outputVal, fp_hgt + 1);
453 gbe->fp_vdrv = outputVal;
454}
455
456struct gbe_pll_info {
457 int clock_rate;
458 int fvco_min;
459 int fvco_max;
460};
461
462static struct gbe_pll_info gbe_pll_table[2] = {
463 { 20, 80, 220 },
464 { 27, 80, 220 },
465};
466
467static int compute_gbe_timing(struct fb_var_screeninfo *var,
468 struct gbe_timing_info *timing)
469{
470 int pll_m, pll_n, pll_p, error, best_m, best_n, best_p, best_error;
471 int pixclock;
472 struct gbe_pll_info *gbe_pll;
473
474 if (gbe_revision < 2)
475 gbe_pll = &gbe_pll_table[0];
476 else
477 gbe_pll = &gbe_pll_table[1];
478
479
480
481
482
483
484 best_error = 1000000000;
485 best_n = best_m = best_p = 0;
486 for (pll_p = 0; pll_p < 4; pll_p++)
487 for (pll_m = 1; pll_m < 256; pll_m++)
488 for (pll_n = 1; pll_n < 64; pll_n++) {
489 pixclock = (1000000 / gbe_pll->clock_rate) *
490 (pll_n << pll_p) / pll_m;
491
492 error = var->pixclock - pixclock;
493
494 if (error < 0)
495 error = -error;
496
497 if (error < best_error &&
498 pll_m / pll_n >
499 gbe_pll->fvco_min / gbe_pll->clock_rate &&
500 pll_m / pll_n <
501 gbe_pll->fvco_max / gbe_pll->clock_rate) {
502 best_error = error;
503 best_m = pll_m;
504 best_n = pll_n;
505 best_p = pll_p;
506 }
507 }
508
509 if (!best_n || !best_m)
510 return -EINVAL;
511
512 pixclock = (1000000 / gbe_pll->clock_rate) *
513 (best_n << best_p) / best_m;
514
515
516 if (timing) {
517 timing->width = var->xres;
518 timing->height = var->yres;
519 timing->pll_m = best_m;
520 timing->pll_n = best_n;
521 timing->pll_p = best_p;
522 timing->cfreq = gbe_pll->clock_rate * 1000 * timing->pll_m /
523 (timing->pll_n << timing->pll_p);
524 timing->htotal = var->left_margin + var->xres +
525 var->right_margin + var->hsync_len;
526 timing->vtotal = var->upper_margin + var->yres +
527 var->lower_margin + var->vsync_len;
528 timing->fields_sec = 1000 * timing->cfreq / timing->htotal *
529 1000 / timing->vtotal;
530 timing->hblank_start = var->xres;
531 timing->vblank_start = var->yres;
532 timing->hblank_end = timing->htotal;
533 timing->hsync_start = var->xres + var->right_margin + 1;
534 timing->hsync_end = timing->hsync_start + var->hsync_len;
535 timing->vblank_end = timing->vtotal;
536 timing->vsync_start = var->yres + var->lower_margin + 1;
537 timing->vsync_end = timing->vsync_start + var->vsync_len;
538 }
539
540 return pixclock;
541}
542
543static void gbe_set_timing_info(struct gbe_timing_info *timing)
544{
545 int temp;
546 unsigned int val;
547
548
549 val = 0;
550 SET_GBE_FIELD(DOTCLK, M, val, timing->pll_m - 1);
551 SET_GBE_FIELD(DOTCLK, N, val, timing->pll_n - 1);
552 SET_GBE_FIELD(DOTCLK, P, val, timing->pll_p);
553 SET_GBE_FIELD(DOTCLK, RUN, val, 0);
554 gbe->dotclock = val;
555 udelay(10000);
556
557
558 val = 0;
559 SET_GBE_FIELD(VT_XYMAX, MAXX, val, timing->htotal);
560 SET_GBE_FIELD(VT_XYMAX, MAXY, val, timing->vtotal);
561 gbe->vt_xymax = val;
562
563
564 val = 0;
565 SET_GBE_FIELD(VT_VSYNC, VSYNC_ON, val, timing->vsync_start);
566 SET_GBE_FIELD(VT_VSYNC, VSYNC_OFF, val, timing->vsync_end);
567 gbe->vt_vsync = val;
568 val = 0;
569 SET_GBE_FIELD(VT_HSYNC, HSYNC_ON, val, timing->hsync_start);
570 SET_GBE_FIELD(VT_HSYNC, HSYNC_OFF, val, timing->hsync_end);
571 gbe->vt_hsync = val;
572 val = 0;
573 SET_GBE_FIELD(VT_VBLANK, VBLANK_ON, val, timing->vblank_start);
574 SET_GBE_FIELD(VT_VBLANK, VBLANK_OFF, val, timing->vblank_end);
575 gbe->vt_vblank = val;
576 val = 0;
577 SET_GBE_FIELD(VT_HBLANK, HBLANK_ON, val,
578 timing->hblank_start - 5);
579 SET_GBE_FIELD(VT_HBLANK, HBLANK_OFF, val,
580 timing->hblank_end - 3);
581 gbe->vt_hblank = val;
582
583
584 val = 0;
585 SET_GBE_FIELD(VT_VCMAP, VCMAP_ON, val, timing->vblank_start);
586 SET_GBE_FIELD(VT_VCMAP, VCMAP_OFF, val, timing->vblank_end);
587 gbe->vt_vcmap = val;
588 val = 0;
589 SET_GBE_FIELD(VT_HCMAP, HCMAP_ON, val, timing->hblank_start);
590 SET_GBE_FIELD(VT_HCMAP, HCMAP_OFF, val, timing->hblank_end);
591 gbe->vt_hcmap = val;
592
593 val = 0;
594 temp = timing->vblank_start - timing->vblank_end - 1;
595 if (temp > 0)
596 temp = -temp;
597
598 if (flat_panel_enabled)
599 gbefb_setup_flatpanel(timing);
600
601 SET_GBE_FIELD(DID_START_XY, DID_STARTY, val, (u32) temp);
602 if (timing->hblank_end >= 20)
603 SET_GBE_FIELD(DID_START_XY, DID_STARTX, val,
604 timing->hblank_end - 20);
605 else
606 SET_GBE_FIELD(DID_START_XY, DID_STARTX, val,
607 timing->htotal - (20 - timing->hblank_end));
608 gbe->did_start_xy = val;
609
610 val = 0;
611 SET_GBE_FIELD(CRS_START_XY, CRS_STARTY, val, (u32) (temp + 1));
612 if (timing->hblank_end >= GBE_CRS_MAGIC)
613 SET_GBE_FIELD(CRS_START_XY, CRS_STARTX, val,
614 timing->hblank_end - GBE_CRS_MAGIC);
615 else
616 SET_GBE_FIELD(CRS_START_XY, CRS_STARTX, val,
617 timing->htotal - (GBE_CRS_MAGIC -
618 timing->hblank_end));
619 gbe->crs_start_xy = val;
620
621 val = 0;
622 SET_GBE_FIELD(VC_START_XY, VC_STARTY, val, (u32) temp);
623 SET_GBE_FIELD(VC_START_XY, VC_STARTX, val, timing->hblank_end - 4);
624 gbe->vc_start_xy = val;
625
626 val = 0;
627 temp = timing->hblank_end - GBE_PIXEN_MAGIC_ON;
628 if (temp < 0)
629 temp += timing->htotal;
630
631 SET_GBE_FIELD(VT_HPIXEN, HPIXEN_ON, val, temp);
632 SET_GBE_FIELD(VT_HPIXEN, HPIXEN_OFF, val,
633 ((temp + timing->width -
634 GBE_PIXEN_MAGIC_OFF) % timing->htotal));
635 gbe->vt_hpixen = val;
636
637 val = 0;
638 SET_GBE_FIELD(VT_VPIXEN, VPIXEN_ON, val, timing->vblank_end);
639 SET_GBE_FIELD(VT_VPIXEN, VPIXEN_OFF, val, timing->vblank_start);
640 gbe->vt_vpixen = val;
641
642
643 val = 0;
644 SET_GBE_FIELD(VT_FLAGS, SYNC_LOW, val, 1);
645 gbe->vt_flags = val;
646}
647
648
649
650
651
652static int gbefb_set_par(struct fb_info *info)
653{
654 int i;
655 unsigned int val;
656 int wholeTilesX, partTilesX, maxPixelsPerTileX;
657 int height_pix;
658 int xpmax, ypmax;
659 int bytesPerPixel;
660 struct gbefb_par *par = (struct gbefb_par *) info->par;
661
662 compute_gbe_timing(&info->var, &par->timing);
663
664 bytesPerPixel = info->var.bits_per_pixel / 8;
665 info->fix.line_length = info->var.xres_virtual * bytesPerPixel;
666 xpmax = par->timing.width;
667 ypmax = par->timing.height;
668
669
670 gbe_turn_off();
671
672
673 gbe_set_timing_info(&par->timing);
674
675
676 val = 0;
677 switch (bytesPerPixel) {
678 case 1:
679 SET_GBE_FIELD(WID, TYP, val, GBE_CMODE_I8);
680 info->fix.visual = FB_VISUAL_PSEUDOCOLOR;
681 break;
682 case 2:
683 SET_GBE_FIELD(WID, TYP, val, GBE_CMODE_ARGB5);
684 info->fix.visual = FB_VISUAL_TRUECOLOR;
685 break;
686 case 4:
687 SET_GBE_FIELD(WID, TYP, val, GBE_CMODE_RGB8);
688 info->fix.visual = FB_VISUAL_TRUECOLOR;
689 break;
690 }
691 SET_GBE_FIELD(WID, BUF, val, GBE_BMODE_BOTH);
692
693 for (i = 0; i < 32; i++)
694 gbe->mode_regs[i] = val;
695
696
697 gbe->vt_intr01 = 0xffffffff;
698 gbe->vt_intr23 = 0xffffffff;
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
767 val = 0;
768 SET_GBE_FIELD(FRM_CONTROL, FRM_TILE_PTR, val, gbe_tiles.dma >> 9);
769 SET_GBE_FIELD(FRM_CONTROL, FRM_DMA_ENABLE, val, 0);
770 SET_GBE_FIELD(FRM_CONTROL, FRM_LINEAR, val, 0);
771 gbe->frm_control = val;
772
773 maxPixelsPerTileX = 512 / bytesPerPixel;
774 wholeTilesX = 1;
775 partTilesX = 0;
776
777
778 val = 0;
779 SET_GBE_FIELD(FRM_SIZE_TILE, FRM_WIDTH_TILE, val, wholeTilesX);
780 SET_GBE_FIELD(FRM_SIZE_TILE, FRM_RHS, val, partTilesX);
781
782 switch (bytesPerPixel) {
783 case 1:
784 SET_GBE_FIELD(FRM_SIZE_TILE, FRM_DEPTH, val,
785 GBE_FRM_DEPTH_8);
786 break;
787 case 2:
788 SET_GBE_FIELD(FRM_SIZE_TILE, FRM_DEPTH, val,
789 GBE_FRM_DEPTH_16);
790 break;
791 case 4:
792 SET_GBE_FIELD(FRM_SIZE_TILE, FRM_DEPTH, val,
793 GBE_FRM_DEPTH_32);
794 break;
795 }
796 gbe->frm_size_tile = val;
797
798
799 height_pix = xpmax * ypmax / maxPixelsPerTileX;
800
801 val = 0;
802 SET_GBE_FIELD(FRM_SIZE_PIXEL, FB_HEIGHT_PIX, val, height_pix);
803 gbe->frm_size_pixel = val;
804
805
806 gbe->did_control = 0;
807 gbe->ovr_width_tile = 0;
808
809
810 gbe->crs_ctl = 0;
811
812
813 gbe_turn_on();
814
815
816 udelay(10);
817 for (i = 0; i < 256; i++)
818 gbe->gmap[i] = (i << 24) | (i << 16) | (i << 8);
819
820
821 for (i = 0; i < 256; i++)
822 gbe_cmap[i] = (i << 8) | (i << 16) | (i << 24);
823
824 gbe_loadcmap();
825
826 return 0;
827}
828
829static void gbefb_encode_fix(struct fb_fix_screeninfo *fix,
830 struct fb_var_screeninfo *var)
831{
832 memset(fix, 0, sizeof(struct fb_fix_screeninfo));
833 strcpy(fix->id, "SGI GBE");
834 fix->smem_start = (unsigned long) gbe_mem;
835 fix->smem_len = gbe_mem_size;
836 fix->type = FB_TYPE_PACKED_PIXELS;
837 fix->type_aux = 0;
838 fix->accel = FB_ACCEL_NONE;
839 switch (var->bits_per_pixel) {
840 case 8:
841 fix->visual = FB_VISUAL_PSEUDOCOLOR;
842 break;
843 default:
844 fix->visual = FB_VISUAL_TRUECOLOR;
845 break;
846 }
847 fix->ywrapstep = 0;
848 fix->xpanstep = 0;
849 fix->ypanstep = 0;
850 fix->line_length = var->xres_virtual * var->bits_per_pixel / 8;
851 fix->mmio_start = GBE_BASE;
852 fix->mmio_len = sizeof(struct sgi_gbe);
853}
854
855
856
857
858
859
860
861static int gbefb_setcolreg(unsigned regno, unsigned red, unsigned green,
862 unsigned blue, unsigned transp,
863 struct fb_info *info)
864{
865 int i;
866
867 if (regno > 255)
868 return 1;
869 red >>= 8;
870 green >>= 8;
871 blue >>= 8;
872
873 if (info->var.bits_per_pixel <= 8) {
874 gbe_cmap[regno] = (red << 24) | (green << 16) | (blue << 8);
875 if (gbe_turned_on) {
876
877 for (i = 0; i < 1000 && gbe->cm_fifo >= 63; i++)
878 udelay(10);
879 if (i == 1000) {
880 printk(KERN_ERR "gbefb: cmap FIFO timeout\n");
881 return 1;
882 }
883 gbe->cmap[regno] = gbe_cmap[regno];
884 }
885 } else if (regno < 16) {
886 switch (info->var.bits_per_pixel) {
887 case 15:
888 case 16:
889 red >>= 3;
890 green >>= 3;
891 blue >>= 3;
892 pseudo_palette[regno] =
893 (red << info->var.red.offset) |
894 (green << info->var.green.offset) |
895 (blue << info->var.blue.offset);
896 break;
897 case 32:
898 pseudo_palette[regno] =
899 (red << info->var.red.offset) |
900 (green << info->var.green.offset) |
901 (blue << info->var.blue.offset);
902 break;
903 }
904 }
905
906 return 0;
907}
908
909
910
911
912static int gbefb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
913{
914 unsigned int line_length;
915 struct gbe_timing_info timing;
916 int ret;
917
918
919 if (var->bits_per_pixel <= 8)
920 var->bits_per_pixel = 8;
921 else if (var->bits_per_pixel <= 16)
922 var->bits_per_pixel = 16;
923 else if (var->bits_per_pixel <= 32)
924 var->bits_per_pixel = 32;
925 else
926 return -EINVAL;
927
928
929
930 if ((var->xres * var->yres * var->bits_per_pixel) & 4095)
931 return -EINVAL;
932
933 var->grayscale = 0;
934
935 ret = compute_gbe_timing(var, &timing);
936 var->pixclock = ret;
937 if (ret < 0)
938 return -EINVAL;
939
940
941 if (var->xres > var->xres_virtual || (!ywrap && !ypan))
942 var->xres_virtual = var->xres;
943 if (var->yres > var->yres_virtual || (!ywrap && !ypan))
944 var->yres_virtual = var->yres;
945
946 if (var->vmode & FB_VMODE_CONUPDATE) {
947 var->vmode |= FB_VMODE_YWRAP;
948 var->xoffset = info->var.xoffset;
949 var->yoffset = info->var.yoffset;
950 }
951
952
953 var->grayscale = 0;
954
955
956 line_length = var->xres_virtual * var->bits_per_pixel / 8;
957 if (line_length * var->yres_virtual > gbe_mem_size)
958 return -ENOMEM;
959
960 switch (var->bits_per_pixel) {
961 case 8:
962 var->red.offset = 0;
963 var->red.length = 8;
964 var->green.offset = 0;
965 var->green.length = 8;
966 var->blue.offset = 0;
967 var->blue.length = 8;
968 var->transp.offset = 0;
969 var->transp.length = 0;
970 break;
971 case 16:
972 var->red.offset = 10;
973 var->red.length = 5;
974 var->green.offset = 5;
975 var->green.length = 5;
976 var->blue.offset = 0;
977 var->blue.length = 5;
978 var->transp.offset = 0;
979 var->transp.length = 0;
980 break;
981 case 32:
982 var->red.offset = 24;
983 var->red.length = 8;
984 var->green.offset = 16;
985 var->green.length = 8;
986 var->blue.offset = 8;
987 var->blue.length = 8;
988 var->transp.offset = 0;
989 var->transp.length = 8;
990 break;
991 }
992 var->red.msb_right = 0;
993 var->green.msb_right = 0;
994 var->blue.msb_right = 0;
995 var->transp.msb_right = 0;
996
997 var->left_margin = timing.htotal - timing.hsync_end;
998 var->right_margin = timing.hsync_start - timing.width;
999 var->upper_margin = timing.vtotal - timing.vsync_end;
1000 var->lower_margin = timing.vsync_start - timing.height;
1001 var->hsync_len = timing.hsync_end - timing.hsync_start;
1002 var->vsync_len = timing.vsync_end - timing.vsync_start;
1003
1004 return 0;
1005}
1006
1007static int gbefb_mmap(struct fb_info *info,
1008 struct vm_area_struct *vma)
1009{
1010 unsigned long size = vma->vm_end - vma->vm_start;
1011 unsigned long offset = vma->vm_pgoff << PAGE_SHIFT;
1012 unsigned long addr;
1013 unsigned long phys_addr, phys_size;
1014 u16 *tile;
1015
1016
1017 if (vma->vm_pgoff > (~0UL >> PAGE_SHIFT))
1018 return -EINVAL;
1019 if (size > gbe_mem_size)
1020 return -EINVAL;
1021 if (offset > gbe_mem_size - size)
1022 return -EINVAL;
1023
1024
1025
1026 pgprot_val(vma->vm_page_prot) =
1027 pgprot_fb(pgprot_val(vma->vm_page_prot));
1028
1029
1030
1031
1032 tile = &gbe_tiles.cpu[offset >> TILE_SHIFT];
1033 addr = vma->vm_start;
1034 offset &= TILE_MASK;
1035
1036
1037 do {
1038 phys_addr = (((unsigned long) (*tile)) << TILE_SHIFT) + offset;
1039 if ((offset + size) < TILE_SIZE)
1040 phys_size = size;
1041 else
1042 phys_size = TILE_SIZE - offset;
1043
1044 if (remap_pfn_range(vma, addr, phys_addr >> PAGE_SHIFT,
1045 phys_size, vma->vm_page_prot))
1046 return -EAGAIN;
1047
1048 offset = 0;
1049 size -= phys_size;
1050 addr += phys_size;
1051 tile++;
1052 } while (size);
1053
1054 return 0;
1055}
1056
1057static struct fb_ops gbefb_ops = {
1058 .owner = THIS_MODULE,
1059 .fb_check_var = gbefb_check_var,
1060 .fb_set_par = gbefb_set_par,
1061 .fb_setcolreg = gbefb_setcolreg,
1062 .fb_mmap = gbefb_mmap,
1063 .fb_blank = gbefb_blank,
1064 .fb_fillrect = cfb_fillrect,
1065 .fb_copyarea = cfb_copyarea,
1066 .fb_imageblit = cfb_imageblit,
1067};
1068
1069
1070
1071
1072
1073static ssize_t gbefb_show_memsize(struct device *dev, struct device_attribute *attr, char *buf)
1074{
1075 return snprintf(buf, PAGE_SIZE, "%d\n", gbe_mem_size);
1076}
1077
1078static DEVICE_ATTR(size, S_IRUGO, gbefb_show_memsize, NULL);
1079
1080static ssize_t gbefb_show_rev(struct device *device, struct device_attribute *attr, char *buf)
1081{
1082 return snprintf(buf, PAGE_SIZE, "%d\n", gbe_revision);
1083}
1084
1085static DEVICE_ATTR(revision, S_IRUGO, gbefb_show_rev, NULL);
1086
1087static void gbefb_remove_sysfs(struct device *dev)
1088{
1089 device_remove_file(dev, &dev_attr_size);
1090 device_remove_file(dev, &dev_attr_revision);
1091}
1092
1093static void gbefb_create_sysfs(struct device *dev)
1094{
1095 device_create_file(dev, &dev_attr_size);
1096 device_create_file(dev, &dev_attr_revision);
1097}
1098
1099
1100
1101
1102
1103static int gbefb_setup(char *options)
1104{
1105 char *this_opt;
1106
1107 if (!options || !*options)
1108 return 0;
1109
1110 while ((this_opt = strsep(&options, ",")) != NULL) {
1111 if (!strncmp(this_opt, "monitor:", 8)) {
1112 if (!strncmp(this_opt + 8, "crt", 3)) {
1113 flat_panel_enabled = 0;
1114 default_var = &default_var_CRT;
1115 default_mode = &default_mode_CRT;
1116 } else if (!strncmp(this_opt + 8, "1600sw", 6) ||
1117 !strncmp(this_opt + 8, "lcd", 3)) {
1118 flat_panel_enabled = 1;
1119 default_var = &default_var_LCD;
1120 default_mode = &default_mode_LCD;
1121 }
1122 } else if (!strncmp(this_opt, "mem:", 4)) {
1123 gbe_mem_size = memparse(this_opt + 4, &this_opt);
1124 if (gbe_mem_size > CONFIG_FB_GBE_MEM * 1024 * 1024)
1125 gbe_mem_size = CONFIG_FB_GBE_MEM * 1024 * 1024;
1126 if (gbe_mem_size < TILE_SIZE)
1127 gbe_mem_size = TILE_SIZE;
1128 } else
1129 mode_option = this_opt;
1130 }
1131 return 0;
1132}
1133
1134static int gbefb_probe(struct platform_device *p_dev)
1135{
1136 int i, ret = 0;
1137 struct fb_info *info;
1138 struct gbefb_par *par;
1139#ifndef MODULE
1140 char *options = NULL;
1141#endif
1142
1143 info = framebuffer_alloc(sizeof(struct gbefb_par), &p_dev->dev);
1144 if (!info)
1145 return -ENOMEM;
1146
1147#ifndef MODULE
1148 if (fb_get_options("gbefb", &options)) {
1149 ret = -ENODEV;
1150 goto out_release_framebuffer;
1151 }
1152 gbefb_setup(options);
1153#endif
1154
1155 if (!request_mem_region(GBE_BASE, sizeof(struct sgi_gbe), "GBE")) {
1156 printk(KERN_ERR "gbefb: couldn't reserve mmio region\n");
1157 ret = -EBUSY;
1158 goto out_release_framebuffer;
1159 }
1160
1161 gbe = (struct sgi_gbe *) devm_ioremap(&p_dev->dev, GBE_BASE,
1162 sizeof(struct sgi_gbe));
1163 if (!gbe) {
1164 printk(KERN_ERR "gbefb: couldn't map mmio region\n");
1165 ret = -ENXIO;
1166 goto out_release_mem_region;
1167 }
1168 gbe_revision = gbe->ctrlstat & 15;
1169
1170 gbe_tiles.cpu =
1171 dma_alloc_coherent(NULL, GBE_TLB_SIZE * sizeof(uint16_t),
1172 &gbe_tiles.dma, GFP_KERNEL);
1173 if (!gbe_tiles.cpu) {
1174 printk(KERN_ERR "gbefb: couldn't allocate tiles table\n");
1175 ret = -ENOMEM;
1176 goto out_release_mem_region;
1177 }
1178
1179 if (gbe_mem_phys) {
1180
1181 gbe_mem = devm_ioremap_nocache(&p_dev->dev, gbe_mem_phys,
1182 gbe_mem_size);
1183 if (!gbe_mem) {
1184 printk(KERN_ERR "gbefb: couldn't map framebuffer\n");
1185 ret = -ENOMEM;
1186 goto out_tiles_free;
1187 }
1188
1189 gbe_dma_addr = 0;
1190 } else {
1191
1192
1193 gbe_mem = dma_alloc_coherent(NULL, gbe_mem_size, &gbe_dma_addr,
1194 GFP_KERNEL);
1195 if (!gbe_mem) {
1196 printk(KERN_ERR "gbefb: couldn't allocate framebuffer memory\n");
1197 ret = -ENOMEM;
1198 goto out_tiles_free;
1199 }
1200
1201 gbe_mem_phys = (unsigned long) gbe_dma_addr;
1202 }
1203
1204#ifdef CONFIG_X86
1205 mtrr_add(gbe_mem_phys, gbe_mem_size, MTRR_TYPE_WRCOMB, 1);
1206#endif
1207
1208
1209 for (i = 0; i < (gbe_mem_size >> TILE_SHIFT); i++)
1210 gbe_tiles.cpu[i] = (gbe_mem_phys >> TILE_SHIFT) + i;
1211
1212 info->fbops = &gbefb_ops;
1213 info->pseudo_palette = pseudo_palette;
1214 info->flags = FBINFO_DEFAULT;
1215 info->screen_base = gbe_mem;
1216 fb_alloc_cmap(&info->cmap, 256, 0);
1217
1218
1219 gbe_reset();
1220
1221 par = info->par;
1222
1223 if (fb_find_mode(&par->var, info, mode_option, NULL, 0,
1224 default_mode, 8) == 0)
1225 par->var = *default_var;
1226 info->var = par->var;
1227 gbefb_check_var(&par->var, info);
1228 gbefb_encode_fix(&info->fix, &info->var);
1229
1230 if (register_framebuffer(info) < 0) {
1231 printk(KERN_ERR "gbefb: couldn't register framebuffer\n");
1232 ret = -ENXIO;
1233 goto out_gbe_unmap;
1234 }
1235
1236 platform_set_drvdata(p_dev, info);
1237 gbefb_create_sysfs(&p_dev->dev);
1238
1239 printk(KERN_INFO "fb%d: %s rev %d @ 0x%08x using %dkB memory\n",
1240 info->node, info->fix.id, gbe_revision, (unsigned) GBE_BASE,
1241 gbe_mem_size >> 10);
1242
1243 return 0;
1244
1245out_gbe_unmap:
1246 if (gbe_dma_addr)
1247 dma_free_coherent(NULL, gbe_mem_size, gbe_mem, gbe_mem_phys);
1248out_tiles_free:
1249 dma_free_coherent(NULL, GBE_TLB_SIZE * sizeof(uint16_t),
1250 (void *)gbe_tiles.cpu, gbe_tiles.dma);
1251out_release_mem_region:
1252 release_mem_region(GBE_BASE, sizeof(struct sgi_gbe));
1253out_release_framebuffer:
1254 framebuffer_release(info);
1255
1256 return ret;
1257}
1258
1259static int gbefb_remove(struct platform_device* p_dev)
1260{
1261 struct fb_info *info = platform_get_drvdata(p_dev);
1262
1263 unregister_framebuffer(info);
1264 gbe_turn_off();
1265 if (gbe_dma_addr)
1266 dma_free_coherent(NULL, gbe_mem_size, gbe_mem, gbe_mem_phys);
1267 dma_free_coherent(NULL, GBE_TLB_SIZE * sizeof(uint16_t),
1268 (void *)gbe_tiles.cpu, gbe_tiles.dma);
1269 release_mem_region(GBE_BASE, sizeof(struct sgi_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 = 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