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>
29 #include <asm/addrspace.h>
31 #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 /* macro for fastest write-though access to the framebuffer */
50 #ifdef CONFIG_CPU_R10000
51 #define pgprot_fb(_prot) (((_prot) & (~_CACHE_MASK)) | _CACHE_UNCACHED_ACCELERATED)
53 #define pgprot_fb(_prot) (((_prot) & (~_CACHE_MASK)) | _CACHE_CACHABLE_NO_WA)
57 #define pgprot_fb(_prot) ((_prot) | _PAGE_PCD)
61 * RAM we reserve for the frame buffer. This defines the maximum screen
64 #if CONFIG_FB_GBE_MEM > 8
65 #error GBE Framebuffer cannot use more than 8MB of memory
69 #define TILE_SIZE (1 << TILE_SHIFT)
70 #define TILE_MASK (TILE_SIZE - 1)
72 static unsigned int gbe_mem_size
= CONFIG_FB_GBE_MEM
* 1024*1024;
74 static dma_addr_t gbe_dma_addr
;
75 static unsigned long gbe_mem_phys
;
82 static int gbe_revision
;
84 static int ypan
, ywrap
;
86 static uint32_t pseudo_palette
[16];
87 static uint32_t gbe_cmap
[256];
88 static int gbe_turned_on
; /* 0 turned off, 1 turned on */
90 static char *mode_option
= NULL
;
92 /* default CRT mode */
93 static struct fb_var_screeninfo default_var_CRT
= {
94 /* 640x480, 60 Hz, Non-Interlaced (25.175 MHz dotclock) */
104 .green
= { 0, 8, 0 },
106 .transp
= { 0, 0, 0 },
112 .pixclock
= 39722, /* picoseconds */
120 .vmode
= FB_VMODE_NONINTERLACED
,
123 /* default LCD mode */
124 static struct fb_var_screeninfo default_var_LCD
= {
125 /* 1600x1024, 8 bpp */
128 .xres_virtual
= 1600,
129 .yres_virtual
= 1024,
135 .green
= { 0, 8, 0 },
137 .transp
= { 0, 0, 0 },
151 .vmode
= FB_VMODE_NONINTERLACED
154 /* default modedb mode */
155 /* 640x480, 60 Hz, Non-Interlaced (25.172 MHz dotclock) */
156 static struct fb_videomode default_mode_CRT
= {
168 .vmode
= FB_VMODE_NONINTERLACED
,
170 /* 1600x1024 SGI flatpanel 1600sw */
171 static struct fb_videomode default_mode_LCD
= {
172 /* 1600x1024, 8 bpp */
182 .vmode
= FB_VMODE_NONINTERLACED
,
185 static struct fb_videomode
*default_mode
= &default_mode_CRT
;
186 static struct fb_var_screeninfo
*default_var
= &default_var_CRT
;
188 static int flat_panel_enabled
= 0;
190 static void gbe_reset(void)
192 /* Turn on dotclock PLL */
193 gbe
->ctrlstat
= 0x300aa000;
198 * Function: gbe_turn_off
200 * Description: This should turn off the monitor and gbe. This is used
201 * when switching between the serial console and the graphics
205 static void gbe_turn_off(void)
208 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");
379 static void gbe_loadcmap(void)
383 for (i
= 0; i
< 256; i
++) {
384 for (j
= 0; j
< 1000 && gbe
->cm_fifo
>= 63; j
++)
387 printk(KERN_ERR
"gbefb: cmap FIFO timeout\n");
389 gbe
->cmap
[i
] = gbe_cmap
[i
];
396 static int gbefb_blank(int blank
, struct fb_info
*info
)
398 /* 0 unblank, 1 blank, 2 no vsync, 3 no hsync, 4 off */
400 case FB_BLANK_UNBLANK
: /* unblank */
405 case FB_BLANK_NORMAL
: /* blank */
417 * Setup flatpanel related registers.
419 static void gbefb_setup_flatpanel(struct gbe_timing_info
*timing
)
421 int fp_wid
, fp_hgt
, fp_vbs
, fp_vbe
;
424 SET_GBE_FIELD(VT_FLAGS
, HDRV_INVERT
, outputVal
,
425 (timing
->flags
& FB_SYNC_HOR_HIGH_ACT
) ? 0 : 1);
426 SET_GBE_FIELD(VT_FLAGS
, VDRV_INVERT
, outputVal
,
427 (timing
->flags
& FB_SYNC_VERT_HIGH_ACT
) ? 0 : 1);
428 gbe
->vt_flags
= outputVal
;
430 /* Turn on the flat panel */
440 SET_GBE_FIELD(FP_DE
, ON
, outputVal
, fp_vbs
);
441 SET_GBE_FIELD(FP_DE
, OFF
, outputVal
, fp_vbe
);
442 gbe
->fp_de
= outputVal
;
444 SET_GBE_FIELD(FP_HDRV
, OFF
, outputVal
, fp_wid
);
445 gbe
->fp_hdrv
= outputVal
;
447 SET_GBE_FIELD(FP_VDRV
, ON
, outputVal
, 1);
448 SET_GBE_FIELD(FP_VDRV
, OFF
, outputVal
, fp_hgt
+ 1);
449 gbe
->fp_vdrv
= outputVal
;
452 struct gbe_pll_info
{
458 static struct gbe_pll_info gbe_pll_table
[2] = {
463 static int compute_gbe_timing(struct fb_var_screeninfo
*var
,
464 struct gbe_timing_info
*timing
)
466 int pll_m
, pll_n
, pll_p
, error
, best_m
, best_n
, best_p
, best_error
;
468 struct gbe_pll_info
*gbe_pll
;
470 if (gbe_revision
< 2)
471 gbe_pll
= &gbe_pll_table
[0];
473 gbe_pll
= &gbe_pll_table
[1];
475 /* Determine valid resolution and timing
476 * GBE crystal runs at 20Mhz or 27Mhz
477 * pll_m, pll_n, pll_p define the following frequencies
478 * fvco = pll_m * 20Mhz / pll_n
479 * fout = fvco / (2**pll_p) */
480 best_error
= 1000000000;
481 best_n
= best_m
= best_p
= 0;
482 for (pll_p
= 0; pll_p
< 4; pll_p
++)
483 for (pll_m
= 1; pll_m
< 256; pll_m
++)
484 for (pll_n
= 1; pll_n
< 64; pll_n
++) {
485 pixclock
= (1000000 / gbe_pll
->clock_rate
) *
486 (pll_n
<< pll_p
) / pll_m
;
488 error
= var
->pixclock
- pixclock
;
493 if (error
< best_error
&&
495 gbe_pll
->fvco_min
/ gbe_pll
->clock_rate
&&
497 gbe_pll
->fvco_max
/ gbe_pll
->clock_rate
) {
505 if (!best_n
|| !best_m
)
506 return -EINVAL
; /* Resolution to high */
508 pixclock
= (1000000 / gbe_pll
->clock_rate
) *
509 (best_n
<< best_p
) / best_m
;
511 /* set video timing information */
513 timing
->width
= var
->xres
;
514 timing
->height
= var
->yres
;
515 timing
->pll_m
= best_m
;
516 timing
->pll_n
= best_n
;
517 timing
->pll_p
= best_p
;
518 timing
->cfreq
= gbe_pll
->clock_rate
* 1000 * timing
->pll_m
/
519 (timing
->pll_n
<< timing
->pll_p
);
520 timing
->htotal
= var
->left_margin
+ var
->xres
+
521 var
->right_margin
+ var
->hsync_len
;
522 timing
->vtotal
= var
->upper_margin
+ var
->yres
+
523 var
->lower_margin
+ var
->vsync_len
;
524 timing
->fields_sec
= 1000 * timing
->cfreq
/ timing
->htotal
*
525 1000 / timing
->vtotal
;
526 timing
->hblank_start
= var
->xres
;
527 timing
->vblank_start
= var
->yres
;
528 timing
->hblank_end
= timing
->htotal
;
529 timing
->hsync_start
= var
->xres
+ var
->right_margin
+ 1;
530 timing
->hsync_end
= timing
->hsync_start
+ var
->hsync_len
;
531 timing
->vblank_end
= timing
->vtotal
;
532 timing
->vsync_start
= var
->yres
+ var
->lower_margin
+ 1;
533 timing
->vsync_end
= timing
->vsync_start
+ var
->vsync_len
;
539 static void gbe_set_timing_info(struct gbe_timing_info
*timing
)
544 /* setup dot clock PLL */
546 SET_GBE_FIELD(DOTCLK
, M
, val
, timing
->pll_m
- 1);
547 SET_GBE_FIELD(DOTCLK
, N
, val
, timing
->pll_n
- 1);
548 SET_GBE_FIELD(DOTCLK
, P
, val
, timing
->pll_p
);
549 SET_GBE_FIELD(DOTCLK
, RUN
, val
, 0); /* do not start yet */
553 /* setup pixel counter */
555 SET_GBE_FIELD(VT_XYMAX
, MAXX
, val
, timing
->htotal
);
556 SET_GBE_FIELD(VT_XYMAX
, MAXY
, val
, timing
->vtotal
);
559 /* setup video timing signals */
561 SET_GBE_FIELD(VT_VSYNC
, VSYNC_ON
, val
, timing
->vsync_start
);
562 SET_GBE_FIELD(VT_VSYNC
, VSYNC_OFF
, val
, timing
->vsync_end
);
565 SET_GBE_FIELD(VT_HSYNC
, HSYNC_ON
, val
, timing
->hsync_start
);
566 SET_GBE_FIELD(VT_HSYNC
, HSYNC_OFF
, val
, timing
->hsync_end
);
569 SET_GBE_FIELD(VT_VBLANK
, VBLANK_ON
, val
, timing
->vblank_start
);
570 SET_GBE_FIELD(VT_VBLANK
, VBLANK_OFF
, val
, timing
->vblank_end
);
571 gbe
->vt_vblank
= val
;
573 SET_GBE_FIELD(VT_HBLANK
, HBLANK_ON
, val
,
574 timing
->hblank_start
- 5);
575 SET_GBE_FIELD(VT_HBLANK
, HBLANK_OFF
, val
,
576 timing
->hblank_end
- 3);
577 gbe
->vt_hblank
= val
;
579 /* setup internal timing signals */
581 SET_GBE_FIELD(VT_VCMAP
, VCMAP_ON
, val
, timing
->vblank_start
);
582 SET_GBE_FIELD(VT_VCMAP
, VCMAP_OFF
, val
, timing
->vblank_end
);
585 SET_GBE_FIELD(VT_HCMAP
, HCMAP_ON
, val
, timing
->hblank_start
);
586 SET_GBE_FIELD(VT_HCMAP
, HCMAP_OFF
, val
, timing
->hblank_end
);
590 temp
= timing
->vblank_start
- timing
->vblank_end
- 1;
594 if (flat_panel_enabled
)
595 gbefb_setup_flatpanel(timing
);
597 SET_GBE_FIELD(DID_START_XY
, DID_STARTY
, val
, (u32
) temp
);
598 if (timing
->hblank_end
>= 20)
599 SET_GBE_FIELD(DID_START_XY
, DID_STARTX
, val
,
600 timing
->hblank_end
- 20);
602 SET_GBE_FIELD(DID_START_XY
, DID_STARTX
, val
,
603 timing
->htotal
- (20 - timing
->hblank_end
));
604 gbe
->did_start_xy
= val
;
607 SET_GBE_FIELD(CRS_START_XY
, CRS_STARTY
, val
, (u32
) (temp
+ 1));
608 if (timing
->hblank_end
>= GBE_CRS_MAGIC
)
609 SET_GBE_FIELD(CRS_START_XY
, CRS_STARTX
, val
,
610 timing
->hblank_end
- GBE_CRS_MAGIC
);
612 SET_GBE_FIELD(CRS_START_XY
, CRS_STARTX
, val
,
613 timing
->htotal
- (GBE_CRS_MAGIC
-
614 timing
->hblank_end
));
615 gbe
->crs_start_xy
= val
;
618 SET_GBE_FIELD(VC_START_XY
, VC_STARTY
, val
, (u32
) temp
);
619 SET_GBE_FIELD(VC_START_XY
, VC_STARTX
, val
, timing
->hblank_end
- 4);
620 gbe
->vc_start_xy
= val
;
623 temp
= timing
->hblank_end
- GBE_PIXEN_MAGIC_ON
;
625 temp
+= timing
->htotal
; /* allow blank to wrap around */
627 SET_GBE_FIELD(VT_HPIXEN
, HPIXEN_ON
, val
, temp
);
628 SET_GBE_FIELD(VT_HPIXEN
, HPIXEN_OFF
, val
,
629 ((temp
+ timing
->width
-
630 GBE_PIXEN_MAGIC_OFF
) % timing
->htotal
));
631 gbe
->vt_hpixen
= val
;
634 SET_GBE_FIELD(VT_VPIXEN
, VPIXEN_ON
, val
, timing
->vblank_end
);
635 SET_GBE_FIELD(VT_VPIXEN
, VPIXEN_OFF
, val
, timing
->vblank_start
);
636 gbe
->vt_vpixen
= val
;
638 /* turn off sync on green */
640 SET_GBE_FIELD(VT_FLAGS
, SYNC_LOW
, val
, 1);
645 * Set the hardware according to 'par'.
648 static int gbefb_set_par(struct fb_info
*info
)
652 int wholeTilesX
, partTilesX
, maxPixelsPerTileX
;
654 int xpmax
, ypmax
; /* Monitor resolution */
655 int bytesPerPixel
; /* Bytes per pixel */
656 struct gbefb_par
*par
= (struct gbefb_par
*) info
->par
;
658 compute_gbe_timing(&info
->var
, &par
->timing
);
660 bytesPerPixel
= info
->var
.bits_per_pixel
/ 8;
661 info
->fix
.line_length
= info
->var
.xres_virtual
* bytesPerPixel
;
662 xpmax
= par
->timing
.width
;
663 ypmax
= par
->timing
.height
;
668 /* set timing info */
669 gbe_set_timing_info(&par
->timing
);
671 /* initialize DIDs */
673 switch (bytesPerPixel
) {
675 SET_GBE_FIELD(WID
, TYP
, val
, GBE_CMODE_I8
);
676 info
->fix
.visual
= FB_VISUAL_PSEUDOCOLOR
;
679 SET_GBE_FIELD(WID
, TYP
, val
, GBE_CMODE_ARGB5
);
680 info
->fix
.visual
= FB_VISUAL_TRUECOLOR
;
683 SET_GBE_FIELD(WID
, TYP
, val
, GBE_CMODE_RGB8
);
684 info
->fix
.visual
= FB_VISUAL_TRUECOLOR
;
687 SET_GBE_FIELD(WID
, BUF
, val
, GBE_BMODE_BOTH
);
689 for (i
= 0; i
< 32; i
++)
690 gbe
->mode_regs
[i
] = val
;
692 /* Initialize interrupts */
693 gbe
->vt_intr01
= 0xffffffff;
694 gbe
->vt_intr23
= 0xffffffff;
697 The GBE hardware uses a tiled memory to screen mapping. Tiles are
698 blocks of 512x128, 256x128 or 128x128 pixels, respectively for 8bit,
699 16bit and 32 bit modes (64 kB). They cover the screen with partial
700 tiles on the right and/or bottom of the screen if needed.
701 For example in 640x480 8 bit mode the mapping is:
704 <---- 512 ----><128|384 offscreen>
706 | 128 [tile 0] [tile 1]
709 4 128 [tile 2] [tile 3]
712 128 [tile 4] [tile 5]
715 v 96 [tile 6] [tile 7]
718 Tiles have the advantage that they can be allocated individually in
719 memory. However, this mapping is not linear at all, which is not
720 really convenient. In order to support linear addressing, the GBE
721 DMA hardware is fooled into thinking the screen is only one tile
722 large and but has a greater height, so that the DMA transfer covers
724 Tiles are still allocated as independent chunks of 64KB of
725 continuous physical memory and remapped so that the kernel sees the
726 framebuffer as a continuous virtual memory. The GBE tile table is
727 set up so that each tile references one of these 64k blocks:
729 GBE -> tile list framebuffer TLB <------------ CPU
730 [ tile 0 ] -> [ 64KB ] <- [ 16x 4KB page entries ] ^
731 ... ... ... linear virtual FB
732 [ tile n ] -> [ 64KB ] <- [ 16x 4KB page entries ] v
735 The GBE hardware is then told that the buffer is 512*tweaked_height,
736 with tweaked_height = real_width*real_height/pixels_per_tile.
737 Thus the GBE hardware will scan the first tile, filing the first 64k
738 covered region of the screen, and then will proceed to the next
739 tile, until the whole screen is covered.
741 Here is what would happen at 640x480 8bit:
744 ^ 11111111111111112222 11111111111111111111 ^
745 128 11111111111111112222 11111111111111111111 102 lines
746 11111111111111112222 11111111111111111111 v
747 V 11111111111111112222 11111111222222222222
748 33333333333333334444 22222222222222222222
749 33333333333333334444 22222222222222222222
750 < 512 > < 256 > 102*640+256 = 64k
752 NOTE: The only mode for which this is not working is 800x600 8bit,
753 as 800*600/512 = 937.5 which is not integer and thus causes
755 I guess this is not so important as one can use 640x480 8bit or
756 800x600 16bit anyway.
759 /* Tell gbe about the tiles table location */
760 /* tile_ptr -> [ tile 1 ] -> FB mem */
761 /* [ tile 2 ] -> FB mem */
764 SET_GBE_FIELD(FRM_CONTROL
, FRM_TILE_PTR
, val
, gbe_tiles
.dma
>> 9);
765 SET_GBE_FIELD(FRM_CONTROL
, FRM_DMA_ENABLE
, val
, 0); /* do not start */
766 SET_GBE_FIELD(FRM_CONTROL
, FRM_LINEAR
, val
, 0);
767 gbe
->frm_control
= val
;
769 maxPixelsPerTileX
= 512 / bytesPerPixel
;
773 /* Initialize the framebuffer */
775 SET_GBE_FIELD(FRM_SIZE_TILE
, FRM_WIDTH_TILE
, val
, wholeTilesX
);
776 SET_GBE_FIELD(FRM_SIZE_TILE
, FRM_RHS
, val
, partTilesX
);
778 switch (bytesPerPixel
) {
780 SET_GBE_FIELD(FRM_SIZE_TILE
, FRM_DEPTH
, val
,
784 SET_GBE_FIELD(FRM_SIZE_TILE
, FRM_DEPTH
, val
,
788 SET_GBE_FIELD(FRM_SIZE_TILE
, FRM_DEPTH
, val
,
792 gbe
->frm_size_tile
= val
;
794 /* compute tweaked height */
795 height_pix
= xpmax
* ypmax
/ maxPixelsPerTileX
;
798 SET_GBE_FIELD(FRM_SIZE_PIXEL
, FB_HEIGHT_PIX
, val
, height_pix
);
799 gbe
->frm_size_pixel
= val
;
801 /* turn off DID and overlay DMA */
802 gbe
->did_control
= 0;
803 gbe
->ovr_width_tile
= 0;
805 /* Turn off mouse cursor */
811 /* Initialize the gamma map */
813 for (i
= 0; i
< 256; i
++)
814 gbe
->gmap
[i
] = (i
<< 24) | (i
<< 16) | (i
<< 8);
816 /* Initialize the color map */
817 for (i
= 0; i
< 256; i
++)
818 gbe_cmap
[i
] = (i
<< 8) | (i
<< 16) | (i
<< 24);
825 static void gbefb_encode_fix(struct fb_fix_screeninfo
*fix
,
826 struct fb_var_screeninfo
*var
)
828 memset(fix
, 0, sizeof(struct fb_fix_screeninfo
));
829 strcpy(fix
->id
, "SGI GBE");
830 fix
->smem_start
= (unsigned long) gbe_mem
;
831 fix
->smem_len
= gbe_mem_size
;
832 fix
->type
= FB_TYPE_PACKED_PIXELS
;
834 fix
->accel
= FB_ACCEL_NONE
;
835 switch (var
->bits_per_pixel
) {
837 fix
->visual
= FB_VISUAL_PSEUDOCOLOR
;
840 fix
->visual
= FB_VISUAL_TRUECOLOR
;
846 fix
->line_length
= var
->xres_virtual
* var
->bits_per_pixel
/ 8;
847 fix
->mmio_start
= GBE_BASE
;
848 fix
->mmio_len
= sizeof(struct sgi_gbe
);
852 * Set a single color register. The values supplied are already
853 * rounded down to the hardware's capabilities (according to the
854 * entries in the var structure). Return != 0 for invalid regno.
857 static int gbefb_setcolreg(unsigned regno
, unsigned red
, unsigned green
,
858 unsigned blue
, unsigned transp
,
859 struct fb_info
*info
)
869 if (info
->var
.bits_per_pixel
<= 8) {
870 gbe_cmap
[regno
] = (red
<< 24) | (green
<< 16) | (blue
<< 8);
872 /* wait for the color map FIFO to have a free entry */
873 for (i
= 0; i
< 1000 && gbe
->cm_fifo
>= 63; i
++)
876 printk(KERN_ERR
"gbefb: cmap FIFO timeout\n");
879 gbe
->cmap
[regno
] = gbe_cmap
[regno
];
881 } else if (regno
< 16) {
882 switch (info
->var
.bits_per_pixel
) {
888 pseudo_palette
[regno
] =
889 (red
<< info
->var
.red
.offset
) |
890 (green
<< info
->var
.green
.offset
) |
891 (blue
<< info
->var
.blue
.offset
);
894 pseudo_palette
[regno
] =
895 (red
<< info
->var
.red
.offset
) |
896 (green
<< info
->var
.green
.offset
) |
897 (blue
<< info
->var
.blue
.offset
);
906 * Check video mode validity, eventually modify var to best match.
908 static int gbefb_check_var(struct fb_var_screeninfo
*var
, struct fb_info
*info
)
910 unsigned int line_length
;
911 struct gbe_timing_info timing
;
914 /* Limit bpp to 8, 16, and 32 */
915 if (var
->bits_per_pixel
<= 8)
916 var
->bits_per_pixel
= 8;
917 else if (var
->bits_per_pixel
<= 16)
918 var
->bits_per_pixel
= 16;
919 else if (var
->bits_per_pixel
<= 32)
920 var
->bits_per_pixel
= 32;
924 /* Check the mode can be mapped linearly with the tile table trick. */
925 /* This requires width x height x bytes/pixel be a multiple of 512 */
926 if ((var
->xres
* var
->yres
* var
->bits_per_pixel
) & 4095)
929 var
->grayscale
= 0; /* No grayscale for now */
931 ret
= compute_gbe_timing(var
, &timing
);
936 /* Adjust virtual resolution, if necessary */
937 if (var
->xres
> var
->xres_virtual
|| (!ywrap
&& !ypan
))
938 var
->xres_virtual
= var
->xres
;
939 if (var
->yres
> var
->yres_virtual
|| (!ywrap
&& !ypan
))
940 var
->yres_virtual
= var
->yres
;
942 if (var
->vmode
& FB_VMODE_CONUPDATE
) {
943 var
->vmode
|= FB_VMODE_YWRAP
;
944 var
->xoffset
= info
->var
.xoffset
;
945 var
->yoffset
= info
->var
.yoffset
;
948 /* No grayscale for now */
952 line_length
= var
->xres_virtual
* var
->bits_per_pixel
/ 8;
953 if (line_length
* var
->yres_virtual
> gbe_mem_size
)
954 return -ENOMEM
; /* Virtual resolution too high */
956 switch (var
->bits_per_pixel
) {
960 var
->green
.offset
= 0;
961 var
->green
.length
= 8;
962 var
->blue
.offset
= 0;
963 var
->blue
.length
= 8;
964 var
->transp
.offset
= 0;
965 var
->transp
.length
= 0;
967 case 16: /* RGB 1555 */
968 var
->red
.offset
= 10;
970 var
->green
.offset
= 5;
971 var
->green
.length
= 5;
972 var
->blue
.offset
= 0;
973 var
->blue
.length
= 5;
974 var
->transp
.offset
= 0;
975 var
->transp
.length
= 0;
977 case 32: /* RGB 8888 */
978 var
->red
.offset
= 24;
980 var
->green
.offset
= 16;
981 var
->green
.length
= 8;
982 var
->blue
.offset
= 8;
983 var
->blue
.length
= 8;
984 var
->transp
.offset
= 0;
985 var
->transp
.length
= 8;
988 var
->red
.msb_right
= 0;
989 var
->green
.msb_right
= 0;
990 var
->blue
.msb_right
= 0;
991 var
->transp
.msb_right
= 0;
993 var
->left_margin
= timing
.htotal
- timing
.hsync_end
;
994 var
->right_margin
= timing
.hsync_start
- timing
.width
;
995 var
->upper_margin
= timing
.vtotal
- timing
.vsync_end
;
996 var
->lower_margin
= timing
.vsync_start
- timing
.height
;
997 var
->hsync_len
= timing
.hsync_end
- timing
.hsync_start
;
998 var
->vsync_len
= timing
.vsync_end
- timing
.vsync_start
;
1003 static int gbefb_mmap(struct fb_info
*info
,
1004 struct vm_area_struct
*vma
)
1006 unsigned long size
= vma
->vm_end
- vma
->vm_start
;
1007 unsigned long offset
= vma
->vm_pgoff
<< PAGE_SHIFT
;
1009 unsigned long phys_addr
, phys_size
;
1013 if (vma
->vm_pgoff
> (~0UL >> PAGE_SHIFT
))
1015 if (size
> gbe_mem_size
)
1017 if (offset
> gbe_mem_size
- size
)
1020 /* remap using the fastest write-through mode on architecture */
1021 /* try not polluting the cache when possible */
1022 pgprot_val(vma
->vm_page_prot
) =
1023 pgprot_fb(pgprot_val(vma
->vm_page_prot
));
1025 /* VM_IO | VM_DONTEXPAND | VM_DONTDUMP are set by remap_pfn_range() */
1027 /* look for the starting tile */
1028 tile
= &gbe_tiles
.cpu
[offset
>> TILE_SHIFT
];
1029 addr
= vma
->vm_start
;
1030 offset
&= TILE_MASK
;
1032 /* remap each tile separately */
1034 phys_addr
= (((unsigned long) (*tile
)) << TILE_SHIFT
) + offset
;
1035 if ((offset
+ size
) < TILE_SIZE
)
1038 phys_size
= TILE_SIZE
- offset
;
1040 if (remap_pfn_range(vma
, addr
, phys_addr
>> PAGE_SHIFT
,
1041 phys_size
, vma
->vm_page_prot
))
1053 static struct fb_ops gbefb_ops
= {
1054 .owner
= THIS_MODULE
,
1055 .fb_check_var
= gbefb_check_var
,
1056 .fb_set_par
= gbefb_set_par
,
1057 .fb_setcolreg
= gbefb_setcolreg
,
1058 .fb_mmap
= gbefb_mmap
,
1059 .fb_blank
= gbefb_blank
,
1060 .fb_fillrect
= cfb_fillrect
,
1061 .fb_copyarea
= cfb_copyarea
,
1062 .fb_imageblit
= cfb_imageblit
,
1069 static ssize_t
gbefb_show_memsize(struct device
*dev
, struct device_attribute
*attr
, char *buf
)
1071 return snprintf(buf
, PAGE_SIZE
, "%u\n", gbe_mem_size
);
1074 static DEVICE_ATTR(size
, S_IRUGO
, gbefb_show_memsize
, NULL
);
1076 static ssize_t
gbefb_show_rev(struct device
*device
, struct device_attribute
*attr
, char *buf
)
1078 return snprintf(buf
, PAGE_SIZE
, "%d\n", gbe_revision
);
1081 static DEVICE_ATTR(revision
, S_IRUGO
, gbefb_show_rev
, NULL
);
1083 static void gbefb_remove_sysfs(struct device
*dev
)
1085 device_remove_file(dev
, &dev_attr_size
);
1086 device_remove_file(dev
, &dev_attr_revision
);
1089 static void gbefb_create_sysfs(struct device
*dev
)
1091 device_create_file(dev
, &dev_attr_size
);
1092 device_create_file(dev
, &dev_attr_revision
);
1099 static int gbefb_setup(char *options
)
1103 if (!options
|| !*options
)
1106 while ((this_opt
= strsep(&options
, ",")) != NULL
) {
1107 if (!strncmp(this_opt
, "monitor:", 8)) {
1108 if (!strncmp(this_opt
+ 8, "crt", 3)) {
1109 flat_panel_enabled
= 0;
1110 default_var
= &default_var_CRT
;
1111 default_mode
= &default_mode_CRT
;
1112 } else if (!strncmp(this_opt
+ 8, "1600sw", 6) ||
1113 !strncmp(this_opt
+ 8, "lcd", 3)) {
1114 flat_panel_enabled
= 1;
1115 default_var
= &default_var_LCD
;
1116 default_mode
= &default_mode_LCD
;
1118 } else if (!strncmp(this_opt
, "mem:", 4)) {
1119 gbe_mem_size
= memparse(this_opt
+ 4, &this_opt
);
1120 if (gbe_mem_size
> CONFIG_FB_GBE_MEM
* 1024 * 1024)
1121 gbe_mem_size
= CONFIG_FB_GBE_MEM
* 1024 * 1024;
1122 if (gbe_mem_size
< TILE_SIZE
)
1123 gbe_mem_size
= TILE_SIZE
;
1125 mode_option
= this_opt
;
1130 static int gbefb_probe(struct platform_device
*p_dev
)
1133 struct fb_info
*info
;
1134 struct gbefb_par
*par
;
1136 char *options
= NULL
;
1139 info
= framebuffer_alloc(sizeof(struct gbefb_par
), &p_dev
->dev
);
1144 if (fb_get_options("gbefb", &options
)) {
1146 goto out_release_framebuffer
;
1148 gbefb_setup(options
);
1151 if (!request_mem_region(GBE_BASE
, sizeof(struct sgi_gbe
), "GBE")) {
1152 printk(KERN_ERR
"gbefb: couldn't reserve mmio region\n");
1154 goto out_release_framebuffer
;
1157 gbe
= (struct sgi_gbe
*) devm_ioremap(&p_dev
->dev
, GBE_BASE
,
1158 sizeof(struct sgi_gbe
));
1160 printk(KERN_ERR
"gbefb: couldn't map mmio region\n");
1162 goto out_release_mem_region
;
1164 gbe_revision
= gbe
->ctrlstat
& 15;
1167 dma_alloc_coherent(NULL
, GBE_TLB_SIZE
* sizeof(uint16_t),
1168 &gbe_tiles
.dma
, GFP_KERNEL
);
1169 if (!gbe_tiles
.cpu
) {
1170 printk(KERN_ERR
"gbefb: couldn't allocate tiles table\n");
1172 goto out_release_mem_region
;
1176 /* memory was allocated at boot time */
1177 gbe_mem
= devm_ioremap_nocache(&p_dev
->dev
, gbe_mem_phys
,
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 fb_info(info
, "%s rev %d @ 0x%08x using %dkB memory\n",
1236 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
);
1245 dma_free_coherent(NULL
, GBE_TLB_SIZE
* sizeof(uint16_t),
1246 (void *)gbe_tiles
.cpu
, gbe_tiles
.dma
);
1247 out_release_mem_region
:
1248 release_mem_region(GBE_BASE
, sizeof(struct sgi_gbe
));
1249 out_release_framebuffer
:
1250 framebuffer_release(info
);
1255 static int gbefb_remove(struct platform_device
* p_dev
)
1257 struct fb_info
*info
= platform_get_drvdata(p_dev
);
1259 unregister_framebuffer(info
);
1262 dma_free_coherent(NULL
, gbe_mem_size
, gbe_mem
, gbe_mem_phys
);
1263 dma_free_coherent(NULL
, GBE_TLB_SIZE
* sizeof(uint16_t),
1264 (void *)gbe_tiles
.cpu
, gbe_tiles
.dma
);
1265 release_mem_region(GBE_BASE
, sizeof(struct sgi_gbe
));
1266 gbefb_remove_sysfs(&p_dev
->dev
);
1267 framebuffer_release(info
);
1272 static struct platform_driver gbefb_driver
= {
1273 .probe
= gbefb_probe
,
1274 .remove
= gbefb_remove
,
1280 static struct platform_device
*gbefb_device
;
1282 static int __init
gbefb_init(void)
1284 int ret
= platform_driver_register(&gbefb_driver
);
1286 gbefb_device
= platform_device_alloc("gbefb", 0);
1288 ret
= platform_device_add(gbefb_device
);
1293 platform_device_put(gbefb_device
);
1294 platform_driver_unregister(&gbefb_driver
);
1300 static void __exit
gbefb_exit(void)
1302 platform_device_unregister(gbefb_device
);
1303 platform_driver_unregister(&gbefb_driver
);
1306 module_init(gbefb_init
);
1307 module_exit(gbefb_exit
);
1309 MODULE_LICENSE("GPL");