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/config.h>
13 #include <linux/delay.h>
14 #include <linux/device.h>
15 #include <linux/dma-mapping.h>
16 #include <linux/errno.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 unsigned long gbe_mem_phys
;
86 static int gbe_revision
;
88 static int ypan
, ywrap
;
90 static uint32_t pseudo_palette
[256];
92 static char *mode_option __initdata
= NULL
;
94 /* default CRT mode */
95 static struct fb_var_screeninfo default_var_CRT __initdata
= {
96 /* 640x480, 60 Hz, Non-Interlaced (25.175 MHz dotclock) */
106 .green
= { 0, 8, 0 },
108 .transp
= { 0, 0, 0 },
114 .pixclock
= 39722, /* picoseconds */
122 .vmode
= FB_VMODE_NONINTERLACED
,
125 /* default LCD mode */
126 static struct fb_var_screeninfo default_var_LCD __initdata
= {
127 /* 1600x1024, 8 bpp */
130 .xres_virtual
= 1600,
131 .yres_virtual
= 1024,
137 .green
= { 0, 8, 0 },
139 .transp
= { 0, 0, 0 },
153 .vmode
= FB_VMODE_NONINTERLACED
156 /* default modedb mode */
157 /* 640x480, 60 Hz, Non-Interlaced (25.172 MHz dotclock) */
158 static struct fb_videomode default_mode_CRT __initdata
= {
170 .vmode
= FB_VMODE_NONINTERLACED
,
172 /* 1600x1024 SGI flatpanel 1600sw */
173 static struct fb_videomode default_mode_LCD __initdata
= {
174 /* 1600x1024, 8 bpp */
184 .vmode
= FB_VMODE_NONINTERLACED
,
187 struct fb_videomode
*default_mode
= &default_mode_CRT
;
188 struct fb_var_screeninfo
*default_var
= &default_var_CRT
;
190 static int flat_panel_enabled
= 0;
192 static void gbe_reset(void)
194 /* Turn on dotclock PLL */
195 gbe
->ctrlstat
= 0x300aa000;
200 * Function: gbe_turn_off
202 * Description: This should turn off the monitor and gbe. This is used
203 * when switching between the serial console and the graphics
207 void gbe_turn_off(void)
210 unsigned int val
, x
, y
, vpixen_off
;
212 /* check if pixel counter is on */
214 if (GET_GBE_FIELD(VT_XY
, FREEZE
, val
) == 1)
218 val
= gbe
->ovr_control
;
219 SET_GBE_FIELD(OVR_CONTROL
, OVR_DMA_ENABLE
, val
, 0);
220 gbe
->ovr_control
= val
;
222 val
= gbe
->frm_control
;
223 SET_GBE_FIELD(FRM_CONTROL
, FRM_DMA_ENABLE
, val
, 0);
224 gbe
->frm_control
= val
;
226 val
= gbe
->did_control
;
227 SET_GBE_FIELD(DID_CONTROL
, DID_DMA_ENABLE
, val
, 0);
228 gbe
->did_control
= val
;
231 /* We have to wait through two vertical retrace periods before
232 * the pixel DMA is turned off for sure. */
233 for (i
= 0; i
< 10000; i
++) {
234 val
= gbe
->frm_inhwctrl
;
235 if (GET_GBE_FIELD(FRM_INHWCTRL
, FRM_DMA_ENABLE
, val
)) {
238 val
= gbe
->ovr_inhwctrl
;
239 if (GET_GBE_FIELD(OVR_INHWCTRL
, OVR_DMA_ENABLE
, val
)) {
242 val
= gbe
->did_inhwctrl
;
243 if (GET_GBE_FIELD(DID_INHWCTRL
, DID_DMA_ENABLE
, val
)) {
251 printk(KERN_ERR
"gbefb: turn off DMA timed out\n");
253 /* wait for vpixen_off */
254 val
= gbe
->vt_vpixen
;
255 vpixen_off
= GET_GBE_FIELD(VT_VPIXEN
, VPIXEN_OFF
, val
);
257 for (i
= 0; i
< 100000; i
++) {
259 x
= GET_GBE_FIELD(VT_XY
, X
, val
);
260 y
= GET_GBE_FIELD(VT_XY
, Y
, val
);
267 "gbefb: wait for vpixen_off timed out\n");
268 for (i
= 0; i
< 10000; i
++) {
270 x
= GET_GBE_FIELD(VT_XY
, X
, val
);
271 y
= GET_GBE_FIELD(VT_XY
, Y
, val
);
277 printk(KERN_ERR
"gbefb: wait for vpixen_off timed out\n");
279 /* turn off pixel counter */
281 SET_GBE_FIELD(VT_XY
, FREEZE
, val
, 1);
284 for (i
= 0; i
< 10000; i
++) {
286 if (GET_GBE_FIELD(VT_XY
, FREEZE
, val
) != 1)
292 printk(KERN_ERR
"gbefb: turn off pixel clock timed out\n");
294 /* turn off dot clock */
296 SET_GBE_FIELD(DOTCLK
, RUN
, val
, 0);
299 for (i
= 0; i
< 10000; i
++) {
301 if (GET_GBE_FIELD(DOTCLK
, RUN
, val
))
307 printk(KERN_ERR
"gbefb: turn off dotclock timed out\n");
309 /* reset the frame DMA FIFO */
310 val
= gbe
->frm_size_tile
;
311 SET_GBE_FIELD(FRM_SIZE_TILE
, FRM_FIFO_RESET
, val
, 1);
312 gbe
->frm_size_tile
= val
;
313 SET_GBE_FIELD(FRM_SIZE_TILE
, FRM_FIFO_RESET
, val
, 0);
314 gbe
->frm_size_tile
= val
;
317 static void gbe_turn_on(void)
322 * Check if pixel counter is off, for unknown reason this
323 * code hangs Visual Workstations
325 if (gbe_revision
< 2) {
327 if (GET_GBE_FIELD(VT_XY
, FREEZE
, val
) == 0)
331 /* turn on dot clock */
333 SET_GBE_FIELD(DOTCLK
, RUN
, val
, 1);
336 for (i
= 0; i
< 10000; i
++) {
338 if (GET_GBE_FIELD(DOTCLK
, RUN
, val
) != 1)
344 printk(KERN_ERR
"gbefb: turn on dotclock timed out\n");
346 /* turn on pixel counter */
348 SET_GBE_FIELD(VT_XY
, FREEZE
, val
, 0);
351 for (i
= 0; i
< 10000; i
++) {
353 if (GET_GBE_FIELD(VT_XY
, FREEZE
, val
))
359 printk(KERN_ERR
"gbefb: turn on pixel clock timed out\n");
362 val
= gbe
->frm_control
;
363 SET_GBE_FIELD(FRM_CONTROL
, FRM_DMA_ENABLE
, val
, 1);
364 gbe
->frm_control
= val
;
366 for (i
= 0; i
< 10000; i
++) {
367 val
= gbe
->frm_inhwctrl
;
368 if (GET_GBE_FIELD(FRM_INHWCTRL
, FRM_DMA_ENABLE
, val
) != 1)
374 printk(KERN_ERR
"gbefb: turn on DMA timed out\n");
380 static int gbefb_blank(int blank
, struct fb_info
*info
)
382 /* 0 unblank, 1 blank, 2 no vsync, 3 no hsync, 4 off */
384 case FB_BLANK_UNBLANK
: /* unblank */
388 case FB_BLANK_NORMAL
: /* blank */
400 * Setup flatpanel related registers.
402 static void gbefb_setup_flatpanel(struct gbe_timing_info
*timing
)
404 int fp_wid
, fp_hgt
, fp_vbs
, fp_vbe
;
407 SET_GBE_FIELD(VT_FLAGS
, HDRV_INVERT
, outputVal
,
408 (timing
->flags
& FB_SYNC_HOR_HIGH_ACT
) ? 0 : 1);
409 SET_GBE_FIELD(VT_FLAGS
, VDRV_INVERT
, outputVal
,
410 (timing
->flags
& FB_SYNC_VERT_HIGH_ACT
) ? 0 : 1);
411 gbe
->vt_flags
= outputVal
;
413 /* Turn on the flat panel */
423 SET_GBE_FIELD(FP_DE
, ON
, outputVal
, fp_vbs
);
424 SET_GBE_FIELD(FP_DE
, OFF
, outputVal
, fp_vbe
);
425 gbe
->fp_de
= outputVal
;
427 SET_GBE_FIELD(FP_HDRV
, OFF
, outputVal
, fp_wid
);
428 gbe
->fp_hdrv
= outputVal
;
430 SET_GBE_FIELD(FP_VDRV
, ON
, outputVal
, 1);
431 SET_GBE_FIELD(FP_VDRV
, OFF
, outputVal
, fp_hgt
+ 1);
432 gbe
->fp_vdrv
= outputVal
;
435 struct gbe_pll_info
{
441 static struct gbe_pll_info gbe_pll_table
[2] = {
446 static int compute_gbe_timing(struct fb_var_screeninfo
*var
,
447 struct gbe_timing_info
*timing
)
449 int pll_m
, pll_n
, pll_p
, error
, best_m
, best_n
, best_p
, best_error
;
451 struct gbe_pll_info
*gbe_pll
;
453 if (gbe_revision
< 2)
454 gbe_pll
= &gbe_pll_table
[0];
456 gbe_pll
= &gbe_pll_table
[1];
458 /* Determine valid resolution and timing
459 * GBE crystal runs at 20Mhz or 27Mhz
460 * pll_m, pll_n, pll_p define the following frequencies
461 * fvco = pll_m * 20Mhz / pll_n
462 * fout = fvco / (2**pll_p) */
463 best_error
= 1000000000;
464 best_n
= best_m
= best_p
= 0;
465 for (pll_p
= 0; pll_p
< 4; pll_p
++)
466 for (pll_m
= 1; pll_m
< 256; pll_m
++)
467 for (pll_n
= 1; pll_n
< 64; pll_n
++) {
468 pixclock
= (1000000 / gbe_pll
->clock_rate
) *
469 (pll_n
<< pll_p
) / pll_m
;
471 error
= var
->pixclock
- pixclock
;
476 if (error
< best_error
&&
478 gbe_pll
->fvco_min
/ gbe_pll
->clock_rate
&&
480 gbe_pll
->fvco_max
/ gbe_pll
->clock_rate
) {
488 if (!best_n
|| !best_m
)
489 return -EINVAL
; /* Resolution to high */
491 pixclock
= (1000000 / gbe_pll
->clock_rate
) *
492 (best_n
<< best_p
) / best_m
;
494 /* set video timing information */
496 timing
->width
= var
->xres
;
497 timing
->height
= var
->yres
;
498 timing
->pll_m
= best_m
;
499 timing
->pll_n
= best_n
;
500 timing
->pll_p
= best_p
;
501 timing
->cfreq
= gbe_pll
->clock_rate
* 1000 * timing
->pll_m
/
502 (timing
->pll_n
<< timing
->pll_p
);
503 timing
->htotal
= var
->left_margin
+ var
->xres
+
504 var
->right_margin
+ var
->hsync_len
;
505 timing
->vtotal
= var
->upper_margin
+ var
->yres
+
506 var
->lower_margin
+ var
->vsync_len
;
507 timing
->fields_sec
= 1000 * timing
->cfreq
/ timing
->htotal
*
508 1000 / timing
->vtotal
;
509 timing
->hblank_start
= var
->xres
;
510 timing
->vblank_start
= var
->yres
;
511 timing
->hblank_end
= timing
->htotal
;
512 timing
->hsync_start
= var
->xres
+ var
->right_margin
+ 1;
513 timing
->hsync_end
= timing
->hsync_start
+ var
->hsync_len
;
514 timing
->vblank_end
= timing
->vtotal
;
515 timing
->vsync_start
= var
->yres
+ var
->lower_margin
+ 1;
516 timing
->vsync_end
= timing
->vsync_start
+ var
->vsync_len
;
522 static void gbe_set_timing_info(struct gbe_timing_info
*timing
)
527 /* setup dot clock PLL */
529 SET_GBE_FIELD(DOTCLK
, M
, val
, timing
->pll_m
- 1);
530 SET_GBE_FIELD(DOTCLK
, N
, val
, timing
->pll_n
- 1);
531 SET_GBE_FIELD(DOTCLK
, P
, val
, timing
->pll_p
);
532 SET_GBE_FIELD(DOTCLK
, RUN
, val
, 0); /* do not start yet */
536 /* setup pixel counter */
538 SET_GBE_FIELD(VT_XYMAX
, MAXX
, val
, timing
->htotal
);
539 SET_GBE_FIELD(VT_XYMAX
, MAXY
, val
, timing
->vtotal
);
542 /* setup video timing signals */
544 SET_GBE_FIELD(VT_VSYNC
, VSYNC_ON
, val
, timing
->vsync_start
);
545 SET_GBE_FIELD(VT_VSYNC
, VSYNC_OFF
, val
, timing
->vsync_end
);
548 SET_GBE_FIELD(VT_HSYNC
, HSYNC_ON
, val
, timing
->hsync_start
);
549 SET_GBE_FIELD(VT_HSYNC
, HSYNC_OFF
, val
, timing
->hsync_end
);
552 SET_GBE_FIELD(VT_VBLANK
, VBLANK_ON
, val
, timing
->vblank_start
);
553 SET_GBE_FIELD(VT_VBLANK
, VBLANK_OFF
, val
, timing
->vblank_end
);
554 gbe
->vt_vblank
= val
;
556 SET_GBE_FIELD(VT_HBLANK
, HBLANK_ON
, val
,
557 timing
->hblank_start
- 5);
558 SET_GBE_FIELD(VT_HBLANK
, HBLANK_OFF
, val
,
559 timing
->hblank_end
- 3);
560 gbe
->vt_hblank
= val
;
562 /* setup internal timing signals */
564 SET_GBE_FIELD(VT_VCMAP
, VCMAP_ON
, val
, timing
->vblank_start
);
565 SET_GBE_FIELD(VT_VCMAP
, VCMAP_OFF
, val
, timing
->vblank_end
);
568 SET_GBE_FIELD(VT_HCMAP
, HCMAP_ON
, val
, timing
->hblank_start
);
569 SET_GBE_FIELD(VT_HCMAP
, HCMAP_OFF
, val
, timing
->hblank_end
);
573 temp
= timing
->vblank_start
- timing
->vblank_end
- 1;
577 if (flat_panel_enabled
)
578 gbefb_setup_flatpanel(timing
);
580 SET_GBE_FIELD(DID_START_XY
, DID_STARTY
, val
, (u32
) temp
);
581 if (timing
->hblank_end
>= 20)
582 SET_GBE_FIELD(DID_START_XY
, DID_STARTX
, val
,
583 timing
->hblank_end
- 20);
585 SET_GBE_FIELD(DID_START_XY
, DID_STARTX
, val
,
586 timing
->htotal
- (20 - timing
->hblank_end
));
587 gbe
->did_start_xy
= val
;
590 SET_GBE_FIELD(CRS_START_XY
, CRS_STARTY
, val
, (u32
) (temp
+ 1));
591 if (timing
->hblank_end
>= GBE_CRS_MAGIC
)
592 SET_GBE_FIELD(CRS_START_XY
, CRS_STARTX
, val
,
593 timing
->hblank_end
- GBE_CRS_MAGIC
);
595 SET_GBE_FIELD(CRS_START_XY
, CRS_STARTX
, val
,
596 timing
->htotal
- (GBE_CRS_MAGIC
-
597 timing
->hblank_end
));
598 gbe
->crs_start_xy
= val
;
601 SET_GBE_FIELD(VC_START_XY
, VC_STARTY
, val
, (u32
) temp
);
602 SET_GBE_FIELD(VC_START_XY
, VC_STARTX
, val
, timing
->hblank_end
- 4);
603 gbe
->vc_start_xy
= val
;
606 temp
= timing
->hblank_end
- GBE_PIXEN_MAGIC_ON
;
608 temp
+= timing
->htotal
; /* allow blank to wrap around */
610 SET_GBE_FIELD(VT_HPIXEN
, HPIXEN_ON
, val
, temp
);
611 SET_GBE_FIELD(VT_HPIXEN
, HPIXEN_OFF
, val
,
612 ((temp
+ timing
->width
-
613 GBE_PIXEN_MAGIC_OFF
) % timing
->htotal
));
614 gbe
->vt_hpixen
= val
;
617 SET_GBE_FIELD(VT_VPIXEN
, VPIXEN_ON
, val
, timing
->vblank_end
);
618 SET_GBE_FIELD(VT_VPIXEN
, VPIXEN_OFF
, val
, timing
->vblank_start
);
619 gbe
->vt_vpixen
= val
;
621 /* turn off sync on green */
623 SET_GBE_FIELD(VT_FLAGS
, SYNC_LOW
, val
, 1);
628 * Set the hardware according to 'par'.
631 static int gbefb_set_par(struct fb_info
*info
)
635 int wholeTilesX
, partTilesX
, maxPixelsPerTileX
;
637 int xpmax
, ypmax
; /* Monitor resolution */
638 int bytesPerPixel
; /* Bytes per pixel */
639 struct gbefb_par
*par
= (struct gbefb_par
*) info
->par
;
641 compute_gbe_timing(&info
->var
, &par
->timing
);
643 bytesPerPixel
= info
->var
.bits_per_pixel
/ 8;
644 info
->fix
.line_length
= info
->var
.xres_virtual
* bytesPerPixel
;
645 xpmax
= par
->timing
.width
;
646 ypmax
= par
->timing
.height
;
651 /* set timing info */
652 gbe_set_timing_info(&par
->timing
);
654 /* initialize DIDs */
656 switch (bytesPerPixel
) {
658 SET_GBE_FIELD(WID
, TYP
, val
, GBE_CMODE_I8
);
661 SET_GBE_FIELD(WID
, TYP
, val
, GBE_CMODE_ARGB5
);
664 SET_GBE_FIELD(WID
, TYP
, val
, GBE_CMODE_RGB8
);
667 SET_GBE_FIELD(WID
, BUF
, val
, GBE_BMODE_BOTH
);
669 for (i
= 0; i
< 32; i
++)
670 gbe
->mode_regs
[i
] = val
;
672 /* Initialize interrupts */
673 gbe
->vt_intr01
= 0xffffffff;
674 gbe
->vt_intr23
= 0xffffffff;
677 The GBE hardware uses a tiled memory to screen mapping. Tiles are
678 blocks of 512x128, 256x128 or 128x128 pixels, respectively for 8bit,
679 16bit and 32 bit modes (64 kB). They cover the screen with partial
680 tiles on the right and/or bottom of the screen if needed.
681 For exemple in 640x480 8 bit mode the mapping is:
684 <---- 512 ----><128|384 offscreen>
686 | 128 [tile 0] [tile 1]
689 4 128 [tile 2] [tile 3]
692 128 [tile 4] [tile 5]
695 v 96 [tile 6] [tile 7]
698 Tiles have the advantage that they can be allocated individually in
699 memory. However, this mapping is not linear at all, which is not
700 really convienient. In order to support linear addressing, the GBE
701 DMA hardware is fooled into thinking the screen is only one tile
702 large and but has a greater height, so that the DMA transfer covers
704 Tiles are still allocated as independent chunks of 64KB of
705 continuous physical memory and remapped so that the kernel sees the
706 framebuffer as a continuous virtual memory. The GBE tile table is
707 set up so that each tile references one of these 64k blocks:
709 GBE -> tile list framebuffer TLB <------------ CPU
710 [ tile 0 ] -> [ 64KB ] <- [ 16x 4KB page entries ] ^
711 ... ... ... linear virtual FB
712 [ tile n ] -> [ 64KB ] <- [ 16x 4KB page entries ] v
715 The GBE hardware is then told that the buffer is 512*tweaked_height,
716 with tweaked_height = real_width*real_height/pixels_per_tile.
717 Thus the GBE hardware will scan the first tile, filing the first 64k
718 covered region of the screen, and then will proceed to the next
719 tile, until the whole screen is covered.
721 Here is what would happen at 640x480 8bit:
724 ^ 11111111111111112222 11111111111111111111 ^
725 128 11111111111111112222 11111111111111111111 102 lines
726 11111111111111112222 11111111111111111111 v
727 V 11111111111111112222 11111111222222222222
728 33333333333333334444 22222222222222222222
729 33333333333333334444 22222222222222222222
730 < 512 > < 256 > 102*640+256 = 64k
732 NOTE: The only mode for which this is not working is 800x600 8bit,
733 as 800*600/512 = 937.5 which is not integer and thus causes
735 I guess this is not so important as one can use 640x480 8bit or
736 800x600 16bit anyway.
739 /* Tell gbe about the tiles table location */
740 /* tile_ptr -> [ tile 1 ] -> FB mem */
741 /* [ tile 2 ] -> FB mem */
744 SET_GBE_FIELD(FRM_CONTROL
, FRM_TILE_PTR
, val
, gbe_tiles
.dma
>> 9);
745 SET_GBE_FIELD(FRM_CONTROL
, FRM_DMA_ENABLE
, val
, 0); /* do not start */
746 SET_GBE_FIELD(FRM_CONTROL
, FRM_LINEAR
, val
, 0);
747 gbe
->frm_control
= val
;
749 maxPixelsPerTileX
= 512 / bytesPerPixel
;
753 /* Initialize the framebuffer */
755 SET_GBE_FIELD(FRM_SIZE_TILE
, FRM_WIDTH_TILE
, val
, wholeTilesX
);
756 SET_GBE_FIELD(FRM_SIZE_TILE
, FRM_RHS
, val
, partTilesX
);
758 switch (bytesPerPixel
) {
760 SET_GBE_FIELD(FRM_SIZE_TILE
, FRM_DEPTH
, val
,
764 SET_GBE_FIELD(FRM_SIZE_TILE
, FRM_DEPTH
, val
,
768 SET_GBE_FIELD(FRM_SIZE_TILE
, FRM_DEPTH
, val
,
772 gbe
->frm_size_tile
= val
;
774 /* compute tweaked height */
775 height_pix
= xpmax
* ypmax
/ maxPixelsPerTileX
;
778 SET_GBE_FIELD(FRM_SIZE_PIXEL
, FB_HEIGHT_PIX
, val
, height_pix
);
779 gbe
->frm_size_pixel
= val
;
781 /* turn off DID and overlay DMA */
782 gbe
->did_control
= 0;
783 gbe
->ovr_width_tile
= 0;
785 /* Turn off mouse cursor */
791 /* Initialize the gamma map */
793 for (i
= 0; i
< 256; i
++)
794 gbe
->gmap
[i
] = (i
<< 24) | (i
<< 16) | (i
<< 8);
796 /* Initialize the color map */
797 for (i
= 0; i
< 256; i
++) {
800 for (j
= 0; j
< 1000 && gbe
->cm_fifo
>= 63; j
++)
803 printk(KERN_ERR
"gbefb: cmap FIFO timeout\n");
805 gbe
->cmap
[i
] = (i
<< 8) | (i
<< 16) | (i
<< 24);
811 static void gbefb_encode_fix(struct fb_fix_screeninfo
*fix
,
812 struct fb_var_screeninfo
*var
)
814 memset(fix
, 0, sizeof(struct fb_fix_screeninfo
));
815 strcpy(fix
->id
, "SGI GBE");
816 fix
->smem_start
= (unsigned long) gbe_mem
;
817 fix
->smem_len
= gbe_mem_size
;
818 fix
->type
= FB_TYPE_PACKED_PIXELS
;
820 fix
->accel
= FB_ACCEL_NONE
;
821 switch (var
->bits_per_pixel
) {
823 fix
->visual
= FB_VISUAL_PSEUDOCOLOR
;
826 fix
->visual
= FB_VISUAL_TRUECOLOR
;
832 fix
->line_length
= var
->xres_virtual
* var
->bits_per_pixel
/ 8;
833 fix
->mmio_start
= GBE_BASE
;
834 fix
->mmio_len
= sizeof(struct sgi_gbe
);
838 * Set a single color register. The values supplied are already
839 * rounded down to the hardware's capabilities (according to the
840 * entries in the var structure). Return != 0 for invalid regno.
843 static int gbefb_setcolreg(unsigned regno
, unsigned red
, unsigned green
,
844 unsigned blue
, unsigned transp
,
845 struct fb_info
*info
)
855 switch (info
->var
.bits_per_pixel
) {
857 /* wait for the color map FIFO to have a free entry */
858 for (i
= 0; i
< 1000 && gbe
->cm_fifo
>= 63; i
++)
861 printk(KERN_ERR
"gbefb: cmap FIFO timeout\n");
864 gbe
->cmap
[regno
] = (red
<< 24) | (green
<< 16) | (blue
<< 8);
871 pseudo_palette
[regno
] =
872 (red
<< info
->var
.red
.offset
) |
873 (green
<< info
->var
.green
.offset
) |
874 (blue
<< info
->var
.blue
.offset
);
877 pseudo_palette
[regno
] =
878 (red
<< info
->var
.red
.offset
) |
879 (green
<< info
->var
.green
.offset
) |
880 (blue
<< info
->var
.blue
.offset
);
888 * Check video mode validity, eventually modify var to best match.
890 static int gbefb_check_var(struct fb_var_screeninfo
*var
, struct fb_info
*info
)
892 unsigned int line_length
;
893 struct gbe_timing_info timing
;
895 /* Limit bpp to 8, 16, and 32 */
896 if (var
->bits_per_pixel
<= 8)
897 var
->bits_per_pixel
= 8;
898 else if (var
->bits_per_pixel
<= 16)
899 var
->bits_per_pixel
= 16;
900 else if (var
->bits_per_pixel
<= 32)
901 var
->bits_per_pixel
= 32;
905 /* Check the mode can be mapped linearly with the tile table trick. */
906 /* This requires width x height x bytes/pixel be a multiple of 512 */
907 if ((var
->xres
* var
->yres
* var
->bits_per_pixel
) & 4095)
910 var
->grayscale
= 0; /* No grayscale for now */
912 if ((var
->pixclock
= compute_gbe_timing(var
, &timing
)) < 0)
915 /* Adjust virtual resolution, if necessary */
916 if (var
->xres
> var
->xres_virtual
|| (!ywrap
&& !ypan
))
917 var
->xres_virtual
= var
->xres
;
918 if (var
->yres
> var
->yres_virtual
|| (!ywrap
&& !ypan
))
919 var
->yres_virtual
= var
->yres
;
921 if (var
->vmode
& FB_VMODE_CONUPDATE
) {
922 var
->vmode
|= FB_VMODE_YWRAP
;
923 var
->xoffset
= info
->var
.xoffset
;
924 var
->yoffset
= info
->var
.yoffset
;
927 /* No grayscale for now */
931 line_length
= var
->xres_virtual
* var
->bits_per_pixel
/ 8;
932 if (line_length
* var
->yres_virtual
> gbe_mem_size
)
933 return -ENOMEM
; /* Virtual resolution too high */
935 switch (var
->bits_per_pixel
) {
939 var
->green
.offset
= 0;
940 var
->green
.length
= 8;
941 var
->blue
.offset
= 0;
942 var
->blue
.length
= 8;
943 var
->transp
.offset
= 0;
944 var
->transp
.length
= 0;
946 case 16: /* RGB 1555 */
947 var
->red
.offset
= 10;
949 var
->green
.offset
= 5;
950 var
->green
.length
= 5;
951 var
->blue
.offset
= 0;
952 var
->blue
.length
= 5;
953 var
->transp
.offset
= 0;
954 var
->transp
.length
= 0;
956 case 32: /* RGB 8888 */
957 var
->red
.offset
= 24;
959 var
->green
.offset
= 16;
960 var
->green
.length
= 8;
961 var
->blue
.offset
= 8;
962 var
->blue
.length
= 8;
963 var
->transp
.offset
= 0;
964 var
->transp
.length
= 8;
967 var
->red
.msb_right
= 0;
968 var
->green
.msb_right
= 0;
969 var
->blue
.msb_right
= 0;
970 var
->transp
.msb_right
= 0;
972 var
->left_margin
= timing
.htotal
- timing
.hsync_end
;
973 var
->right_margin
= timing
.hsync_start
- timing
.width
;
974 var
->upper_margin
= timing
.vtotal
- timing
.vsync_end
;
975 var
->lower_margin
= timing
.vsync_start
- timing
.height
;
976 var
->hsync_len
= timing
.hsync_end
- timing
.hsync_start
;
977 var
->vsync_len
= timing
.vsync_end
- timing
.vsync_start
;
982 static int gbefb_mmap(struct fb_info
*info
, struct file
*file
,
983 struct vm_area_struct
*vma
)
985 unsigned long size
= vma
->vm_end
- vma
->vm_start
;
986 unsigned long offset
= vma
->vm_pgoff
<< PAGE_SHIFT
;
988 unsigned long phys_addr
, phys_size
;
992 if (vma
->vm_pgoff
> (~0UL >> PAGE_SHIFT
))
994 if (offset
+ size
> gbe_mem_size
)
997 /* remap using the fastest write-through mode on architecture */
998 /* try not polluting the cache when possible */
999 pgprot_val(vma
->vm_page_prot
) =
1000 pgprot_fb(pgprot_val(vma
->vm_page_prot
));
1002 vma
->vm_flags
|= VM_IO
| VM_RESERVED
;
1003 vma
->vm_file
= file
;
1005 /* look for the starting tile */
1006 tile
= &gbe_tiles
.cpu
[offset
>> TILE_SHIFT
];
1007 addr
= vma
->vm_start
;
1008 offset
&= TILE_MASK
;
1010 /* remap each tile separately */
1012 phys_addr
= (((unsigned long) (*tile
)) << TILE_SHIFT
) + offset
;
1013 if ((offset
+ size
) < TILE_SIZE
)
1016 phys_size
= TILE_SIZE
- offset
;
1018 if (remap_pfn_range(vma
, addr
, phys_addr
>> PAGE_SHIFT
,
1019 phys_size
, vma
->vm_page_prot
))
1031 static struct fb_ops gbefb_ops
= {
1032 .owner
= THIS_MODULE
,
1033 .fb_check_var
= gbefb_check_var
,
1034 .fb_set_par
= gbefb_set_par
,
1035 .fb_setcolreg
= gbefb_setcolreg
,
1036 .fb_mmap
= gbefb_mmap
,
1037 .fb_blank
= gbefb_blank
,
1038 .fb_fillrect
= cfb_fillrect
,
1039 .fb_copyarea
= cfb_copyarea
,
1040 .fb_imageblit
= cfb_imageblit
,
1041 .fb_cursor
= soft_cursor
,
1048 static ssize_t
gbefb_show_memsize(struct device
*dev
, struct device_attribute
*attr
, char *buf
)
1050 return snprintf(buf
, PAGE_SIZE
, "%d\n", gbe_mem_size
);
1053 static DEVICE_ATTR(size
, S_IRUGO
, gbefb_show_memsize
, NULL
);
1055 static ssize_t
gbefb_show_rev(struct device
*device
, struct device_attribute
*attr
, char *buf
)
1057 return snprintf(buf
, PAGE_SIZE
, "%d\n", gbe_revision
);
1060 static DEVICE_ATTR(revision
, S_IRUGO
, gbefb_show_rev
, NULL
);
1062 static void __devexit
gbefb_remove_sysfs(struct device
*dev
)
1064 device_remove_file(dev
, &dev_attr_size
);
1065 device_remove_file(dev
, &dev_attr_revision
);
1068 static void gbefb_create_sysfs(struct device
*dev
)
1070 device_create_file(dev
, &dev_attr_size
);
1071 device_create_file(dev
, &dev_attr_revision
);
1078 int __init
gbefb_setup(char *options
)
1082 if (!options
|| !*options
)
1085 while ((this_opt
= strsep(&options
, ",")) != NULL
) {
1086 if (!strncmp(this_opt
, "monitor:", 8)) {
1087 if (!strncmp(this_opt
+ 8, "crt", 3)) {
1088 flat_panel_enabled
= 0;
1089 default_var
= &default_var_CRT
;
1090 default_mode
= &default_mode_CRT
;
1091 } else if (!strncmp(this_opt
+ 8, "1600sw", 6) ||
1092 !strncmp(this_opt
+ 8, "lcd", 3)) {
1093 flat_panel_enabled
= 1;
1094 default_var
= &default_var_LCD
;
1095 default_mode
= &default_mode_LCD
;
1097 } else if (!strncmp(this_opt
, "mem:", 4)) {
1098 gbe_mem_size
= memparse(this_opt
+ 4, &this_opt
);
1099 if (gbe_mem_size
> CONFIG_FB_GBE_MEM
* 1024 * 1024)
1100 gbe_mem_size
= CONFIG_FB_GBE_MEM
* 1024 * 1024;
1101 if (gbe_mem_size
< TILE_SIZE
)
1102 gbe_mem_size
= TILE_SIZE
;
1104 mode_option
= this_opt
;
1109 static int __init
gbefb_probe(struct device
*dev
)
1112 struct fb_info
*info
;
1113 struct gbefb_par
*par
;
1114 struct platform_device
*p_dev
= to_platform_device(dev
);
1116 char *options
= NULL
;
1119 info
= framebuffer_alloc(sizeof(struct gbefb_par
), &p_dev
->dev
);
1124 if (fb_get_options("gbefb", &options
))
1126 gbefb_setup(options
);
1129 if (!request_mem_region(GBE_BASE
, sizeof(struct sgi_gbe
), "GBE")) {
1130 printk(KERN_ERR
"gbefb: couldn't reserve mmio region\n");
1132 goto out_release_framebuffer
;
1135 gbe
= (struct sgi_gbe
*) ioremap(GBE_BASE
, sizeof(struct sgi_gbe
));
1137 printk(KERN_ERR
"gbefb: couldn't map mmio region\n");
1139 goto out_release_mem_region
;
1141 gbe_revision
= gbe
->ctrlstat
& 15;
1144 dma_alloc_coherent(NULL
, GBE_TLB_SIZE
* sizeof(uint16_t),
1145 &gbe_tiles
.dma
, GFP_KERNEL
);
1146 if (!gbe_tiles
.cpu
) {
1147 printk(KERN_ERR
"gbefb: couldn't allocate tiles table\n");
1153 /* memory was allocated at boot time */
1154 gbe_mem
= ioremap_nocache(gbe_mem_phys
, gbe_mem_size
);
1157 /* try to allocate memory with the classical allocator
1158 * this has high chance to fail on low memory machines */
1159 gbe_mem
= dma_alloc_coherent(NULL
, gbe_mem_size
, &gbe_dma_addr
,
1161 gbe_mem_phys
= (unsigned long) gbe_dma_addr
;
1165 mtrr_add(gbe_mem_phys
, gbe_mem_size
, MTRR_TYPE_WRCOMB
, 1);
1169 printk(KERN_ERR
"gbefb: couldn't map framebuffer\n");
1171 goto out_tiles_free
;
1174 /* map framebuffer memory into tiles table */
1175 for (i
= 0; i
< (gbe_mem_size
>> TILE_SHIFT
); i
++)
1176 gbe_tiles
.cpu
[i
] = (gbe_mem_phys
>> TILE_SHIFT
) + i
;
1178 info
->fbops
= &gbefb_ops
;
1179 info
->pseudo_palette
= pseudo_palette
;
1180 info
->flags
= FBINFO_DEFAULT
;
1181 info
->screen_base
= gbe_mem
;
1182 fb_alloc_cmap(&info
->cmap
, 256, 0);
1188 /* turn on default video mode */
1189 if (fb_find_mode(&par
->var
, info
, mode_option
, NULL
, 0,
1190 default_mode
, 8) == 0)
1191 par
->var
= *default_var
;
1192 info
->var
= par
->var
;
1193 gbefb_check_var(&par
->var
, info
);
1194 gbefb_encode_fix(&info
->fix
, &info
->var
);
1196 if (register_framebuffer(info
) < 0) {
1197 printk(KERN_ERR
"gbefb: couldn't register framebuffer\n");
1202 dev_set_drvdata(&p_dev
->dev
, info
);
1203 gbefb_create_sysfs(dev
);
1205 printk(KERN_INFO
"fb%d: %s rev %d @ 0x%08x using %dkB memory\n",
1206 info
->node
, info
->fix
.id
, gbe_revision
, (unsigned) GBE_BASE
,
1207 gbe_mem_size
>> 10);
1213 dma_free_coherent(NULL
, gbe_mem_size
, gbe_mem
, gbe_mem_phys
);
1217 dma_free_coherent(NULL
, GBE_TLB_SIZE
* sizeof(uint16_t),
1218 (void *)gbe_tiles
.cpu
, gbe_tiles
.dma
);
1221 out_release_mem_region
:
1222 release_mem_region(GBE_BASE
, sizeof(struct sgi_gbe
));
1223 out_release_framebuffer
:
1224 framebuffer_release(info
);
1229 static int __devexit
gbefb_remove(struct device
* dev
)
1231 struct platform_device
*p_dev
= to_platform_device(dev
);
1232 struct fb_info
*info
= dev_get_drvdata(&p_dev
->dev
);
1234 unregister_framebuffer(info
);
1237 dma_free_coherent(NULL
, gbe_mem_size
, gbe_mem
, gbe_mem_phys
);
1240 dma_free_coherent(NULL
, GBE_TLB_SIZE
* sizeof(uint16_t),
1241 (void *)gbe_tiles
.cpu
, gbe_tiles
.dma
);
1242 release_mem_region(GBE_BASE
, sizeof(struct sgi_gbe
));
1244 gbefb_remove_sysfs(dev
);
1245 framebuffer_release(info
);
1250 static struct device_driver gbefb_driver
= {
1252 .bus
= &platform_bus_type
,
1253 .probe
= gbefb_probe
,
1254 .remove
= __devexit_p(gbefb_remove
),
1257 static struct platform_device gbefb_device
= {
1261 int __init
gbefb_init(void)
1263 int ret
= driver_register(&gbefb_driver
);
1265 ret
= platform_device_register(&gbefb_device
);
1267 driver_unregister(&gbefb_driver
);
1272 void __exit
gbefb_exit(void)
1274 driver_unregister(&gbefb_driver
);
1277 module_init(gbefb_init
);
1278 module_exit(gbefb_exit
);
1280 MODULE_LICENSE("GPL");