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