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