2 * SGI GBE frame buffer driver
4 * Copyright (C) 1999 Silicon Graphics, Inc. - Jeffrey Newquist
5 * Copyright (C) 2002 Vivien Chappelier <vivien.chappelier@linux-mips.org>
7 * This file is subject to the terms and conditions of the GNU General Public
8 * License. See the file COPYING in the main directory of this archive for
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>
18 #include <linux/init.h>
19 #include <linux/interrupt.h>
20 #include <linux/kernel.h>
22 #include <linux/module.h>
28 #include <asm/addrspace.h>
30 #include <asm/byteorder.h>
32 #include <asm/tlbflush.h>
34 #include <video/gbe.h>
36 static struct sgi_gbe
*gbe
;
39 struct fb_var_screeninfo var
;
40 struct gbe_timing_info timing
;
44 #ifdef CONFIG_SGI_IP32
45 #define GBE_BASE 0x16000000 /* SGI O2 */
48 #ifdef CONFIG_X86_VISWS
49 #define GBE_BASE 0xd0000000 /* SGI Visual Workstation */
52 /* macro for fastest write-though access to the framebuffer */
54 #ifdef CONFIG_CPU_R10000
55 #define pgprot_fb(_prot) (((_prot) & (~_CACHE_MASK)) | _CACHE_UNCACHED_ACCELERATED)
57 #define pgprot_fb(_prot) (((_prot) & (~_CACHE_MASK)) | _CACHE_CACHABLE_NO_WA)
61 #define pgprot_fb(_prot) ((_prot) | _PAGE_PCD)
65 * RAM we reserve for the frame buffer. This defines the maximum screen
68 #if CONFIG_FB_GBE_MEM > 8
69 #error GBE Framebuffer cannot use more than 8MB of memory
73 #define TILE_SIZE (1 << TILE_SHIFT)
74 #define TILE_MASK (TILE_SIZE - 1)
76 static unsigned int gbe_mem_size
= CONFIG_FB_GBE_MEM
* 1024*1024;
78 static dma_addr_t gbe_dma_addr
;
79 static unsigned long gbe_mem_phys
;
86 static int gbe_revision
;
88 static int ypan
, ywrap
;
90 static uint32_t pseudo_palette
[16];
91 static uint32_t gbe_cmap
[256];
92 static int gbe_turned_on
; /* 0 turned off, 1 turned on */
94 static char *mode_option __devinitdata
= NULL
;
96 /* default CRT mode */
97 static struct fb_var_screeninfo default_var_CRT __devinitdata
= {
98 /* 640x480, 60 Hz, Non-Interlaced (25.175 MHz dotclock) */
108 .green
= { 0, 8, 0 },
110 .transp
= { 0, 0, 0 },
116 .pixclock
= 39722, /* picoseconds */
124 .vmode
= FB_VMODE_NONINTERLACED
,
127 /* default LCD mode */
128 static struct fb_var_screeninfo default_var_LCD __devinitdata
= {
129 /* 1600x1024, 8 bpp */
132 .xres_virtual
= 1600,
133 .yres_virtual
= 1024,
139 .green
= { 0, 8, 0 },
141 .transp
= { 0, 0, 0 },
155 .vmode
= FB_VMODE_NONINTERLACED
158 /* default modedb mode */
159 /* 640x480, 60 Hz, Non-Interlaced (25.172 MHz dotclock) */
160 static struct fb_videomode default_mode_CRT __devinitdata
= {
172 .vmode
= FB_VMODE_NONINTERLACED
,
174 /* 1600x1024 SGI flatpanel 1600sw */
175 static struct fb_videomode default_mode_LCD __devinitdata
= {
176 /* 1600x1024, 8 bpp */
186 .vmode
= FB_VMODE_NONINTERLACED
,
189 static struct fb_videomode
*default_mode __devinitdata
= &default_mode_CRT
;
190 static struct fb_var_screeninfo
*default_var __devinitdata
= &default_var_CRT
;
192 static int flat_panel_enabled
= 0;
194 static void gbe_reset(void)
196 /* Turn on dotclock PLL */
197 gbe
->ctrlstat
= 0x300aa000;
202 * Function: gbe_turn_off
204 * Description: This should turn off the monitor and gbe. This is used
205 * when switching between the serial console and the graphics
209 static void gbe_turn_off(void)
212 unsigned int val
, x
, y
, vpixen_off
;
216 /* check if pixel counter is on */
218 if (GET_GBE_FIELD(VT_XY
, FREEZE
, val
) == 1)
222 val
= gbe
->ovr_control
;
223 SET_GBE_FIELD(OVR_CONTROL
, OVR_DMA_ENABLE
, val
, 0);
224 gbe
->ovr_control
= val
;
226 val
= gbe
->frm_control
;
227 SET_GBE_FIELD(FRM_CONTROL
, FRM_DMA_ENABLE
, val
, 0);
228 gbe
->frm_control
= val
;
230 val
= gbe
->did_control
;
231 SET_GBE_FIELD(DID_CONTROL
, DID_DMA_ENABLE
, val
, 0);
232 gbe
->did_control
= val
;
235 /* We have to wait through two vertical retrace periods before
236 * the pixel DMA is turned off for sure. */
237 for (i
= 0; i
< 10000; i
++) {
238 val
= gbe
->frm_inhwctrl
;
239 if (GET_GBE_FIELD(FRM_INHWCTRL
, FRM_DMA_ENABLE
, val
)) {
242 val
= gbe
->ovr_inhwctrl
;
243 if (GET_GBE_FIELD(OVR_INHWCTRL
, OVR_DMA_ENABLE
, val
)) {
246 val
= gbe
->did_inhwctrl
;
247 if (GET_GBE_FIELD(DID_INHWCTRL
, DID_DMA_ENABLE
, val
)) {
255 printk(KERN_ERR
"gbefb: turn off DMA timed out\n");
257 /* wait for vpixen_off */
258 val
= gbe
->vt_vpixen
;
259 vpixen_off
= GET_GBE_FIELD(VT_VPIXEN
, VPIXEN_OFF
, val
);
261 for (i
= 0; i
< 100000; i
++) {
263 x
= GET_GBE_FIELD(VT_XY
, X
, val
);
264 y
= GET_GBE_FIELD(VT_XY
, Y
, val
);
271 "gbefb: wait for vpixen_off timed out\n");
272 for (i
= 0; i
< 10000; i
++) {
274 x
= GET_GBE_FIELD(VT_XY
, X
, val
);
275 y
= GET_GBE_FIELD(VT_XY
, Y
, val
);
281 printk(KERN_ERR
"gbefb: wait for vpixen_off timed out\n");
283 /* turn off pixel counter */
285 SET_GBE_FIELD(VT_XY
, FREEZE
, val
, 1);
288 for (i
= 0; i
< 10000; i
++) {
290 if (GET_GBE_FIELD(VT_XY
, FREEZE
, val
) != 1)
296 printk(KERN_ERR
"gbefb: turn off pixel clock timed out\n");
298 /* turn off dot clock */
300 SET_GBE_FIELD(DOTCLK
, RUN
, val
, 0);
303 for (i
= 0; i
< 10000; i
++) {
305 if (GET_GBE_FIELD(DOTCLK
, RUN
, val
))
311 printk(KERN_ERR
"gbefb: turn off dotclock timed out\n");
313 /* reset the frame DMA FIFO */
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
;
321 static void gbe_turn_on(void)
326 * Check if pixel counter is off, for unknown reason this
327 * code hangs Visual Workstations
329 if (gbe_revision
< 2) {
331 if (GET_GBE_FIELD(VT_XY
, FREEZE
, val
) == 0)
335 /* turn on dot clock */
337 SET_GBE_FIELD(DOTCLK
, RUN
, val
, 1);
340 for (i
= 0; i
< 10000; i
++) {
342 if (GET_GBE_FIELD(DOTCLK
, RUN
, val
) != 1)
348 printk(KERN_ERR
"gbefb: turn on dotclock timed out\n");
350 /* turn on pixel counter */
352 SET_GBE_FIELD(VT_XY
, FREEZE
, val
, 0);
355 for (i
= 0; i
< 10000; i
++) {
357 if (GET_GBE_FIELD(VT_XY
, FREEZE
, val
))
363 printk(KERN_ERR
"gbefb: turn on pixel clock timed out\n");
366 val
= gbe
->frm_control
;
367 SET_GBE_FIELD(FRM_CONTROL
, FRM_DMA_ENABLE
, val
, 1);
368 gbe
->frm_control
= val
;
370 for (i
= 0; i
< 10000; i
++) {
371 val
= gbe
->frm_inhwctrl
;
372 if (GET_GBE_FIELD(FRM_INHWCTRL
, FRM_DMA_ENABLE
, val
) != 1)
378 printk(KERN_ERR
"gbefb: turn on DMA timed out\n");
383 static void gbe_loadcmap(void)
387 for (i
= 0; i
< 256; i
++) {
388 for (j
= 0; j
< 1000 && gbe
->cm_fifo
>= 63; j
++)
391 printk(KERN_ERR
"gbefb: cmap FIFO timeout\n");
393 gbe
->cmap
[i
] = gbe_cmap
[i
];
400 static int gbefb_blank(int blank
, struct fb_info
*info
)
402 /* 0 unblank, 1 blank, 2 no vsync, 3 no hsync, 4 off */
404 case FB_BLANK_UNBLANK
: /* unblank */
409 case FB_BLANK_NORMAL
: /* blank */
421 * Setup flatpanel related registers.
423 static void gbefb_setup_flatpanel(struct gbe_timing_info
*timing
)
425 int fp_wid
, fp_hgt
, fp_vbs
, fp_vbe
;
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
;
434 /* Turn on the flat panel */
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
;
448 SET_GBE_FIELD(FP_HDRV
, OFF
, outputVal
, fp_wid
);
449 gbe
->fp_hdrv
= outputVal
;
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
;
456 struct gbe_pll_info
{
462 static struct gbe_pll_info gbe_pll_table
[2] = {
467 static int compute_gbe_timing(struct fb_var_screeninfo
*var
,
468 struct gbe_timing_info
*timing
)
470 int pll_m
, pll_n
, pll_p
, error
, best_m
, best_n
, best_p
, best_error
;
472 struct gbe_pll_info
*gbe_pll
;
474 if (gbe_revision
< 2)
475 gbe_pll
= &gbe_pll_table
[0];
477 gbe_pll
= &gbe_pll_table
[1];
479 /* Determine valid resolution and timing
480 * GBE crystal runs at 20Mhz or 27Mhz
481 * pll_m, pll_n, pll_p define the following frequencies
482 * fvco = pll_m * 20Mhz / pll_n
483 * fout = fvco / (2**pll_p) */
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
;
492 error
= var
->pixclock
- pixclock
;
497 if (error
< best_error
&&
499 gbe_pll
->fvco_min
/ gbe_pll
->clock_rate
&&
501 gbe_pll
->fvco_max
/ gbe_pll
->clock_rate
) {
509 if (!best_n
|| !best_m
)
510 return -EINVAL
; /* Resolution to high */
512 pixclock
= (1000000 / gbe_pll
->clock_rate
) *
513 (best_n
<< best_p
) / best_m
;
515 /* set video timing information */
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
;
543 static void gbe_set_timing_info(struct gbe_timing_info
*timing
)
548 /* setup dot clock PLL */
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); /* do not start yet */
557 /* setup pixel counter */
559 SET_GBE_FIELD(VT_XYMAX
, MAXX
, val
, timing
->htotal
);
560 SET_GBE_FIELD(VT_XYMAX
, MAXY
, val
, timing
->vtotal
);
563 /* setup video timing signals */
565 SET_GBE_FIELD(VT_VSYNC
, VSYNC_ON
, val
, timing
->vsync_start
);
566 SET_GBE_FIELD(VT_VSYNC
, VSYNC_OFF
, val
, timing
->vsync_end
);
569 SET_GBE_FIELD(VT_HSYNC
, HSYNC_ON
, val
, timing
->hsync_start
);
570 SET_GBE_FIELD(VT_HSYNC
, HSYNC_OFF
, val
, timing
->hsync_end
);
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
;
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
;
583 /* setup internal timing signals */
585 SET_GBE_FIELD(VT_VCMAP
, VCMAP_ON
, val
, timing
->vblank_start
);
586 SET_GBE_FIELD(VT_VCMAP
, VCMAP_OFF
, val
, timing
->vblank_end
);
589 SET_GBE_FIELD(VT_HCMAP
, HCMAP_ON
, val
, timing
->hblank_start
);
590 SET_GBE_FIELD(VT_HCMAP
, HCMAP_OFF
, val
, timing
->hblank_end
);
594 temp
= timing
->vblank_start
- timing
->vblank_end
- 1;
598 if (flat_panel_enabled
)
599 gbefb_setup_flatpanel(timing
);
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);
606 SET_GBE_FIELD(DID_START_XY
, DID_STARTX
, val
,
607 timing
->htotal
- (20 - timing
->hblank_end
));
608 gbe
->did_start_xy
= val
;
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
);
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
;
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
;
627 temp
= timing
->hblank_end
- GBE_PIXEN_MAGIC_ON
;
629 temp
+= timing
->htotal
; /* allow blank to wrap around */
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
;
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
;
642 /* turn off sync on green */
644 SET_GBE_FIELD(VT_FLAGS
, SYNC_LOW
, val
, 1);
649 * Set the hardware according to 'par'.
652 static int gbefb_set_par(struct fb_info
*info
)
656 int wholeTilesX
, partTilesX
, maxPixelsPerTileX
;
658 int xpmax
, ypmax
; /* Monitor resolution */
659 int bytesPerPixel
; /* Bytes per pixel */
660 struct gbefb_par
*par
= (struct gbefb_par
*) info
->par
;
662 compute_gbe_timing(&info
->var
, &par
->timing
);
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
;
672 /* set timing info */
673 gbe_set_timing_info(&par
->timing
);
675 /* initialize DIDs */
677 switch (bytesPerPixel
) {
679 SET_GBE_FIELD(WID
, TYP
, val
, GBE_CMODE_I8
);
680 info
->fix
.visual
= FB_VISUAL_PSEUDOCOLOR
;
683 SET_GBE_FIELD(WID
, TYP
, val
, GBE_CMODE_ARGB5
);
684 info
->fix
.visual
= FB_VISUAL_TRUECOLOR
;
687 SET_GBE_FIELD(WID
, TYP
, val
, GBE_CMODE_RGB8
);
688 info
->fix
.visual
= FB_VISUAL_TRUECOLOR
;
691 SET_GBE_FIELD(WID
, BUF
, val
, GBE_BMODE_BOTH
);
693 for (i
= 0; i
< 32; i
++)
694 gbe
->mode_regs
[i
] = val
;
696 /* Initialize interrupts */
697 gbe
->vt_intr01
= 0xffffffff;
698 gbe
->vt_intr23
= 0xffffffff;
701 The GBE hardware uses a tiled memory to screen mapping. Tiles are
702 blocks of 512x128, 256x128 or 128x128 pixels, respectively for 8bit,
703 16bit and 32 bit modes (64 kB). They cover the screen with partial
704 tiles on the right and/or bottom of the screen if needed.
705 For example in 640x480 8 bit mode the mapping is:
708 <---- 512 ----><128|384 offscreen>
710 | 128 [tile 0] [tile 1]
713 4 128 [tile 2] [tile 3]
716 128 [tile 4] [tile 5]
719 v 96 [tile 6] [tile 7]
722 Tiles have the advantage that they can be allocated individually in
723 memory. However, this mapping is not linear at all, which is not
724 really convienient. In order to support linear addressing, the GBE
725 DMA hardware is fooled into thinking the screen is only one tile
726 large and but has a greater height, so that the DMA transfer covers
728 Tiles are still allocated as independent chunks of 64KB of
729 continuous physical memory and remapped so that the kernel sees the
730 framebuffer as a continuous virtual memory. The GBE tile table is
731 set up so that each tile references one of these 64k blocks:
733 GBE -> tile list framebuffer TLB <------------ CPU
734 [ tile 0 ] -> [ 64KB ] <- [ 16x 4KB page entries ] ^
735 ... ... ... linear virtual FB
736 [ tile n ] -> [ 64KB ] <- [ 16x 4KB page entries ] v
739 The GBE hardware is then told that the buffer is 512*tweaked_height,
740 with tweaked_height = real_width*real_height/pixels_per_tile.
741 Thus the GBE hardware will scan the first tile, filing the first 64k
742 covered region of the screen, and then will proceed to the next
743 tile, until the whole screen is covered.
745 Here is what would happen at 640x480 8bit:
748 ^ 11111111111111112222 11111111111111111111 ^
749 128 11111111111111112222 11111111111111111111 102 lines
750 11111111111111112222 11111111111111111111 v
751 V 11111111111111112222 11111111222222222222
752 33333333333333334444 22222222222222222222
753 33333333333333334444 22222222222222222222
754 < 512 > < 256 > 102*640+256 = 64k
756 NOTE: The only mode for which this is not working is 800x600 8bit,
757 as 800*600/512 = 937.5 which is not integer and thus causes
759 I guess this is not so important as one can use 640x480 8bit or
760 800x600 16bit anyway.
763 /* Tell gbe about the tiles table location */
764 /* tile_ptr -> [ tile 1 ] -> FB mem */
765 /* [ tile 2 ] -> FB mem */
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); /* do not start */
770 SET_GBE_FIELD(FRM_CONTROL
, FRM_LINEAR
, val
, 0);
771 gbe
->frm_control
= val
;
773 maxPixelsPerTileX
= 512 / bytesPerPixel
;
777 /* Initialize the framebuffer */
779 SET_GBE_FIELD(FRM_SIZE_TILE
, FRM_WIDTH_TILE
, val
, wholeTilesX
);
780 SET_GBE_FIELD(FRM_SIZE_TILE
, FRM_RHS
, val
, partTilesX
);
782 switch (bytesPerPixel
) {
784 SET_GBE_FIELD(FRM_SIZE_TILE
, FRM_DEPTH
, val
,
788 SET_GBE_FIELD(FRM_SIZE_TILE
, FRM_DEPTH
, val
,
792 SET_GBE_FIELD(FRM_SIZE_TILE
, FRM_DEPTH
, val
,
796 gbe
->frm_size_tile
= val
;
798 /* compute tweaked height */
799 height_pix
= xpmax
* ypmax
/ maxPixelsPerTileX
;
802 SET_GBE_FIELD(FRM_SIZE_PIXEL
, FB_HEIGHT_PIX
, val
, height_pix
);
803 gbe
->frm_size_pixel
= val
;
805 /* turn off DID and overlay DMA */
806 gbe
->did_control
= 0;
807 gbe
->ovr_width_tile
= 0;
809 /* Turn off mouse cursor */
815 /* Initialize the gamma map */
817 for (i
= 0; i
< 256; i
++)
818 gbe
->gmap
[i
] = (i
<< 24) | (i
<< 16) | (i
<< 8);
820 /* Initialize the color map */
821 for (i
= 0; i
< 256; i
++)
822 gbe_cmap
[i
] = (i
<< 8) | (i
<< 16) | (i
<< 24);
829 static void gbefb_encode_fix(struct fb_fix_screeninfo
*fix
,
830 struct fb_var_screeninfo
*var
)
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
;
838 fix
->accel
= FB_ACCEL_NONE
;
839 switch (var
->bits_per_pixel
) {
841 fix
->visual
= FB_VISUAL_PSEUDOCOLOR
;
844 fix
->visual
= FB_VISUAL_TRUECOLOR
;
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
);
856 * Set a single color register. The values supplied are already
857 * rounded down to the hardware's capabilities (according to the
858 * entries in the var structure). Return != 0 for invalid regno.
861 static int gbefb_setcolreg(unsigned regno
, unsigned red
, unsigned green
,
862 unsigned blue
, unsigned transp
,
863 struct fb_info
*info
)
873 if (info
->var
.bits_per_pixel
<= 8) {
874 gbe_cmap
[regno
] = (red
<< 24) | (green
<< 16) | (blue
<< 8);
876 /* wait for the color map FIFO to have a free entry */
877 for (i
= 0; i
< 1000 && gbe
->cm_fifo
>= 63; i
++)
880 printk(KERN_ERR
"gbefb: cmap FIFO timeout\n");
883 gbe
->cmap
[regno
] = gbe_cmap
[regno
];
885 } else if (regno
< 16) {
886 switch (info
->var
.bits_per_pixel
) {
892 pseudo_palette
[regno
] =
893 (red
<< info
->var
.red
.offset
) |
894 (green
<< info
->var
.green
.offset
) |
895 (blue
<< info
->var
.blue
.offset
);
898 pseudo_palette
[regno
] =
899 (red
<< info
->var
.red
.offset
) |
900 (green
<< info
->var
.green
.offset
) |
901 (blue
<< info
->var
.blue
.offset
);
910 * Check video mode validity, eventually modify var to best match.
912 static int gbefb_check_var(struct fb_var_screeninfo
*var
, struct fb_info
*info
)
914 unsigned int line_length
;
915 struct gbe_timing_info timing
;
918 /* Limit bpp to 8, 16, and 32 */
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;
928 /* Check the mode can be mapped linearly with the tile table trick. */
929 /* This requires width x height x bytes/pixel be a multiple of 512 */
930 if ((var
->xres
* var
->yres
* var
->bits_per_pixel
) & 4095)
933 var
->grayscale
= 0; /* No grayscale for now */
935 ret
= compute_gbe_timing(var
, &timing
);
940 /* Adjust virtual resolution, if necessary */
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
;
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
;
952 /* No grayscale for now */
956 line_length
= var
->xres_virtual
* var
->bits_per_pixel
/ 8;
957 if (line_length
* var
->yres_virtual
> gbe_mem_size
)
958 return -ENOMEM
; /* Virtual resolution too high */
960 switch (var
->bits_per_pixel
) {
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;
971 case 16: /* RGB 1555 */
972 var
->red
.offset
= 10;
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;
981 case 32: /* RGB 8888 */
982 var
->red
.offset
= 24;
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;
992 var
->red
.msb_right
= 0;
993 var
->green
.msb_right
= 0;
994 var
->blue
.msb_right
= 0;
995 var
->transp
.msb_right
= 0;
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
;
1007 static int gbefb_mmap(struct fb_info
*info
,
1008 struct vm_area_struct
*vma
)
1010 unsigned long size
= vma
->vm_end
- vma
->vm_start
;
1011 unsigned long offset
= vma
->vm_pgoff
<< PAGE_SHIFT
;
1013 unsigned long phys_addr
, phys_size
;
1017 if (vma
->vm_pgoff
> (~0UL >> PAGE_SHIFT
))
1019 if (offset
+ size
> gbe_mem_size
)
1022 /* remap using the fastest write-through mode on architecture */
1023 /* try not polluting the cache when possible */
1024 pgprot_val(vma
->vm_page_prot
) =
1025 pgprot_fb(pgprot_val(vma
->vm_page_prot
));
1027 vma
->vm_flags
|= VM_IO
| VM_RESERVED
;
1029 /* look for the starting tile */
1030 tile
= &gbe_tiles
.cpu
[offset
>> TILE_SHIFT
];
1031 addr
= vma
->vm_start
;
1032 offset
&= TILE_MASK
;
1034 /* remap each tile separately */
1036 phys_addr
= (((unsigned long) (*tile
)) << TILE_SHIFT
) + offset
;
1037 if ((offset
+ size
) < TILE_SIZE
)
1040 phys_size
= TILE_SIZE
- offset
;
1042 if (remap_pfn_range(vma
, addr
, phys_addr
>> PAGE_SHIFT
,
1043 phys_size
, vma
->vm_page_prot
))
1055 static struct fb_ops gbefb_ops
= {
1056 .owner
= THIS_MODULE
,
1057 .fb_check_var
= gbefb_check_var
,
1058 .fb_set_par
= gbefb_set_par
,
1059 .fb_setcolreg
= gbefb_setcolreg
,
1060 .fb_mmap
= gbefb_mmap
,
1061 .fb_blank
= gbefb_blank
,
1062 .fb_fillrect
= cfb_fillrect
,
1063 .fb_copyarea
= cfb_copyarea
,
1064 .fb_imageblit
= cfb_imageblit
,
1071 static ssize_t
gbefb_show_memsize(struct device
*dev
, struct device_attribute
*attr
, char *buf
)
1073 return snprintf(buf
, PAGE_SIZE
, "%d\n", gbe_mem_size
);
1076 static DEVICE_ATTR(size
, S_IRUGO
, gbefb_show_memsize
, NULL
);
1078 static ssize_t
gbefb_show_rev(struct device
*device
, struct device_attribute
*attr
, char *buf
)
1080 return snprintf(buf
, PAGE_SIZE
, "%d\n", gbe_revision
);
1083 static DEVICE_ATTR(revision
, S_IRUGO
, gbefb_show_rev
, NULL
);
1085 static void __devexit
gbefb_remove_sysfs(struct device
*dev
)
1087 device_remove_file(dev
, &dev_attr_size
);
1088 device_remove_file(dev
, &dev_attr_revision
);
1091 static void gbefb_create_sysfs(struct device
*dev
)
1093 device_create_file(dev
, &dev_attr_size
);
1094 device_create_file(dev
, &dev_attr_revision
);
1101 static int __devinit
gbefb_setup(char *options
)
1105 if (!options
|| !*options
)
1108 while ((this_opt
= strsep(&options
, ",")) != NULL
) {
1109 if (!strncmp(this_opt
, "monitor:", 8)) {
1110 if (!strncmp(this_opt
+ 8, "crt", 3)) {
1111 flat_panel_enabled
= 0;
1112 default_var
= &default_var_CRT
;
1113 default_mode
= &default_mode_CRT
;
1114 } else if (!strncmp(this_opt
+ 8, "1600sw", 6) ||
1115 !strncmp(this_opt
+ 8, "lcd", 3)) {
1116 flat_panel_enabled
= 1;
1117 default_var
= &default_var_LCD
;
1118 default_mode
= &default_mode_LCD
;
1120 } else if (!strncmp(this_opt
, "mem:", 4)) {
1121 gbe_mem_size
= memparse(this_opt
+ 4, &this_opt
);
1122 if (gbe_mem_size
> CONFIG_FB_GBE_MEM
* 1024 * 1024)
1123 gbe_mem_size
= CONFIG_FB_GBE_MEM
* 1024 * 1024;
1124 if (gbe_mem_size
< TILE_SIZE
)
1125 gbe_mem_size
= TILE_SIZE
;
1127 mode_option
= this_opt
;
1132 static int __devinit
gbefb_probe(struct platform_device
*p_dev
)
1135 struct fb_info
*info
;
1136 struct gbefb_par
*par
;
1138 char *options
= NULL
;
1141 info
= framebuffer_alloc(sizeof(struct gbefb_par
), &p_dev
->dev
);
1146 if (fb_get_options("gbefb", &options
)) {
1148 goto out_release_framebuffer
;
1150 gbefb_setup(options
);
1153 if (!request_mem_region(GBE_BASE
, sizeof(struct sgi_gbe
), "GBE")) {
1154 printk(KERN_ERR
"gbefb: couldn't reserve mmio region\n");
1156 goto out_release_framebuffer
;
1159 gbe
= (struct sgi_gbe
*) ioremap(GBE_BASE
, sizeof(struct sgi_gbe
));
1161 printk(KERN_ERR
"gbefb: couldn't map mmio region\n");
1163 goto out_release_mem_region
;
1165 gbe_revision
= gbe
->ctrlstat
& 15;
1168 dma_alloc_coherent(NULL
, GBE_TLB_SIZE
* sizeof(uint16_t),
1169 &gbe_tiles
.dma
, GFP_KERNEL
);
1170 if (!gbe_tiles
.cpu
) {
1171 printk(KERN_ERR
"gbefb: couldn't allocate tiles table\n");
1177 /* memory was allocated at boot time */
1178 gbe_mem
= ioremap_nocache(gbe_mem_phys
, gbe_mem_size
);
1180 printk(KERN_ERR
"gbefb: couldn't map framebuffer\n");
1182 goto out_tiles_free
;
1187 /* try to allocate memory with the classical allocator
1188 * this has high chance to fail on low memory machines */
1189 gbe_mem
= dma_alloc_coherent(NULL
, gbe_mem_size
, &gbe_dma_addr
,
1192 printk(KERN_ERR
"gbefb: couldn't allocate framebuffer memory\n");
1194 goto out_tiles_free
;
1197 gbe_mem_phys
= (unsigned long) gbe_dma_addr
;
1201 mtrr_add(gbe_mem_phys
, gbe_mem_size
, MTRR_TYPE_WRCOMB
, 1);
1204 /* map framebuffer memory into tiles table */
1205 for (i
= 0; i
< (gbe_mem_size
>> TILE_SHIFT
); i
++)
1206 gbe_tiles
.cpu
[i
] = (gbe_mem_phys
>> TILE_SHIFT
) + i
;
1208 info
->fbops
= &gbefb_ops
;
1209 info
->pseudo_palette
= pseudo_palette
;
1210 info
->flags
= FBINFO_DEFAULT
;
1211 info
->screen_base
= gbe_mem
;
1212 fb_alloc_cmap(&info
->cmap
, 256, 0);
1218 /* turn on default video mode */
1219 if (fb_find_mode(&par
->var
, info
, mode_option
, NULL
, 0,
1220 default_mode
, 8) == 0)
1221 par
->var
= *default_var
;
1222 info
->var
= par
->var
;
1223 gbefb_check_var(&par
->var
, info
);
1224 gbefb_encode_fix(&info
->fix
, &info
->var
);
1226 if (register_framebuffer(info
) < 0) {
1227 printk(KERN_ERR
"gbefb: couldn't register framebuffer\n");
1232 platform_set_drvdata(p_dev
, info
);
1233 gbefb_create_sysfs(&p_dev
->dev
);
1235 printk(KERN_INFO
"fb%d: %s rev %d @ 0x%08x using %dkB memory\n",
1236 info
->node
, info
->fix
.id
, gbe_revision
, (unsigned) GBE_BASE
,
1237 gbe_mem_size
>> 10);
1243 dma_free_coherent(NULL
, gbe_mem_size
, gbe_mem
, gbe_mem_phys
);
1247 dma_free_coherent(NULL
, GBE_TLB_SIZE
* sizeof(uint16_t),
1248 (void *)gbe_tiles
.cpu
, gbe_tiles
.dma
);
1251 out_release_mem_region
:
1252 release_mem_region(GBE_BASE
, sizeof(struct sgi_gbe
));
1253 out_release_framebuffer
:
1254 framebuffer_release(info
);
1259 static int __devexit
gbefb_remove(struct platform_device
* p_dev
)
1261 struct fb_info
*info
= platform_get_drvdata(p_dev
);
1263 unregister_framebuffer(info
);
1266 dma_free_coherent(NULL
, gbe_mem_size
, gbe_mem
, gbe_mem_phys
);
1269 dma_free_coherent(NULL
, GBE_TLB_SIZE
* sizeof(uint16_t),
1270 (void *)gbe_tiles
.cpu
, gbe_tiles
.dma
);
1271 release_mem_region(GBE_BASE
, sizeof(struct sgi_gbe
));
1273 gbefb_remove_sysfs(&p_dev
->dev
);
1274 framebuffer_release(info
);
1279 static struct platform_driver gbefb_driver
= {
1280 .probe
= gbefb_probe
,
1281 .remove
= __devexit_p(gbefb_remove
),
1287 static struct platform_device
*gbefb_device
;
1289 static int __init
gbefb_init(void)
1291 int ret
= platform_driver_register(&gbefb_driver
);
1293 gbefb_device
= platform_device_alloc("gbefb", 0);
1295 ret
= platform_device_add(gbefb_device
);
1300 platform_device_put(gbefb_device
);
1301 platform_driver_unregister(&gbefb_driver
);
1307 static void __exit
gbefb_exit(void)
1309 platform_device_unregister(gbefb_device
);
1310 platform_driver_unregister(&gbefb_driver
);
1313 module_init(gbefb_init
);
1314 module_exit(gbefb_exit
);
1316 MODULE_LICENSE("GPL");