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>
26 #include <asm/addrspace.h>
28 #include <asm/byteorder.h>
29 #include <asm/tlbflush.h>
31 #include <video/gbe.h>
33 static struct sgi_gbe
*gbe
;
36 struct fb_var_screeninfo var
;
37 struct gbe_timing_info timing
;
42 #ifdef CONFIG_SGI_IP32
43 #define GBE_BASE 0x16000000 /* SGI O2 */
46 /* macro for fastest write-though access to the framebuffer */
48 #ifdef CONFIG_CPU_R10000
49 #define pgprot_fb(_prot) (((_prot) & (~_CACHE_MASK)) | _CACHE_UNCACHED_ACCELERATED)
51 #define pgprot_fb(_prot) (((_prot) & (~_CACHE_MASK)) | _CACHE_CACHABLE_NO_WA)
55 #define pgprot_fb(_prot) (((_prot) & ~_PAGE_CACHE_MASK) | \
56 cachemode2protval(_PAGE_CACHE_MODE_UC_MINUS))
60 * RAM we reserve for the frame buffer. This defines the maximum screen
63 #if CONFIG_FB_GBE_MEM > 8
64 #error GBE Framebuffer cannot use more than 8MB of memory
68 #define TILE_SIZE (1 << TILE_SHIFT)
69 #define TILE_MASK (TILE_SIZE - 1)
71 static unsigned int gbe_mem_size
= CONFIG_FB_GBE_MEM
* 1024*1024;
73 static dma_addr_t gbe_dma_addr
;
74 static unsigned long gbe_mem_phys
;
81 static int gbe_revision
;
83 static int ypan
, ywrap
;
85 static uint32_t pseudo_palette
[16];
86 static uint32_t gbe_cmap
[256];
87 static int gbe_turned_on
; /* 0 turned off, 1 turned on */
89 static char *mode_option
= NULL
;
91 /* default CRT mode */
92 static struct fb_var_screeninfo default_var_CRT
= {
93 /* 640x480, 60 Hz, Non-Interlaced (25.175 MHz dotclock) */
103 .green
= { 0, 8, 0 },
105 .transp
= { 0, 0, 0 },
111 .pixclock
= 39722, /* picoseconds */
119 .vmode
= FB_VMODE_NONINTERLACED
,
122 /* default LCD mode */
123 static struct fb_var_screeninfo default_var_LCD
= {
124 /* 1600x1024, 8 bpp */
127 .xres_virtual
= 1600,
128 .yres_virtual
= 1024,
134 .green
= { 0, 8, 0 },
136 .transp
= { 0, 0, 0 },
150 .vmode
= FB_VMODE_NONINTERLACED
153 /* default modedb mode */
154 /* 640x480, 60 Hz, Non-Interlaced (25.172 MHz dotclock) */
155 static struct fb_videomode default_mode_CRT
= {
167 .vmode
= FB_VMODE_NONINTERLACED
,
169 /* 1600x1024 SGI flatpanel 1600sw */
170 static struct fb_videomode default_mode_LCD
= {
171 /* 1600x1024, 8 bpp */
181 .vmode
= FB_VMODE_NONINTERLACED
,
184 static struct fb_videomode
*default_mode
= &default_mode_CRT
;
185 static struct fb_var_screeninfo
*default_var
= &default_var_CRT
;
187 static int flat_panel_enabled
= 0;
189 static void gbe_reset(void)
191 /* Turn on dotclock PLL */
192 gbe
->ctrlstat
= 0x300aa000;
197 * Function: gbe_turn_off
199 * Description: This should turn off the monitor and gbe. This is used
200 * when switching between the serial console and the graphics
204 static void gbe_turn_off(void)
207 unsigned int val
, x
, y
, vpixen_off
;
211 /* check if pixel counter is on */
213 if (GET_GBE_FIELD(VT_XY
, FREEZE
, val
) == 1)
217 val
= gbe
->ovr_control
;
218 SET_GBE_FIELD(OVR_CONTROL
, OVR_DMA_ENABLE
, val
, 0);
219 gbe
->ovr_control
= val
;
221 val
= gbe
->frm_control
;
222 SET_GBE_FIELD(FRM_CONTROL
, FRM_DMA_ENABLE
, val
, 0);
223 gbe
->frm_control
= val
;
225 val
= gbe
->did_control
;
226 SET_GBE_FIELD(DID_CONTROL
, DID_DMA_ENABLE
, val
, 0);
227 gbe
->did_control
= val
;
230 /* We have to wait through two vertical retrace periods before
231 * the pixel DMA is turned off for sure. */
232 for (i
= 0; i
< 10000; i
++) {
233 val
= gbe
->frm_inhwctrl
;
234 if (GET_GBE_FIELD(FRM_INHWCTRL
, FRM_DMA_ENABLE
, val
)) {
237 val
= gbe
->ovr_inhwctrl
;
238 if (GET_GBE_FIELD(OVR_INHWCTRL
, OVR_DMA_ENABLE
, val
)) {
241 val
= gbe
->did_inhwctrl
;
242 if (GET_GBE_FIELD(DID_INHWCTRL
, DID_DMA_ENABLE
, val
)) {
250 printk(KERN_ERR
"gbefb: turn off DMA timed out\n");
252 /* wait for vpixen_off */
253 val
= gbe
->vt_vpixen
;
254 vpixen_off
= GET_GBE_FIELD(VT_VPIXEN
, VPIXEN_OFF
, val
);
256 for (i
= 0; i
< 100000; i
++) {
258 x
= GET_GBE_FIELD(VT_XY
, X
, val
);
259 y
= GET_GBE_FIELD(VT_XY
, Y
, val
);
266 "gbefb: wait for vpixen_off timed out\n");
267 for (i
= 0; i
< 10000; i
++) {
269 x
= GET_GBE_FIELD(VT_XY
, X
, val
);
270 y
= GET_GBE_FIELD(VT_XY
, Y
, val
);
276 printk(KERN_ERR
"gbefb: wait for vpixen_off timed out\n");
278 /* turn off pixel counter */
280 SET_GBE_FIELD(VT_XY
, FREEZE
, val
, 1);
283 for (i
= 0; i
< 10000; i
++) {
285 if (GET_GBE_FIELD(VT_XY
, FREEZE
, val
) != 1)
291 printk(KERN_ERR
"gbefb: turn off pixel clock timed out\n");
293 /* turn off dot clock */
295 SET_GBE_FIELD(DOTCLK
, RUN
, val
, 0);
298 for (i
= 0; i
< 10000; i
++) {
300 if (GET_GBE_FIELD(DOTCLK
, RUN
, val
))
306 printk(KERN_ERR
"gbefb: turn off dotclock timed out\n");
308 /* reset the frame DMA FIFO */
309 val
= gbe
->frm_size_tile
;
310 SET_GBE_FIELD(FRM_SIZE_TILE
, FRM_FIFO_RESET
, val
, 1);
311 gbe
->frm_size_tile
= val
;
312 SET_GBE_FIELD(FRM_SIZE_TILE
, FRM_FIFO_RESET
, val
, 0);
313 gbe
->frm_size_tile
= val
;
316 static void gbe_turn_on(void)
321 * Check if pixel counter is off, for unknown reason this
322 * code hangs Visual Workstations
324 if (gbe_revision
< 2) {
326 if (GET_GBE_FIELD(VT_XY
, FREEZE
, val
) == 0)
330 /* turn on dot clock */
332 SET_GBE_FIELD(DOTCLK
, RUN
, val
, 1);
335 for (i
= 0; i
< 10000; i
++) {
337 if (GET_GBE_FIELD(DOTCLK
, RUN
, val
) != 1)
343 printk(KERN_ERR
"gbefb: turn on dotclock timed out\n");
345 /* turn on pixel counter */
347 SET_GBE_FIELD(VT_XY
, FREEZE
, val
, 0);
350 for (i
= 0; i
< 10000; i
++) {
352 if (GET_GBE_FIELD(VT_XY
, FREEZE
, val
))
358 printk(KERN_ERR
"gbefb: turn on pixel clock timed out\n");
361 val
= gbe
->frm_control
;
362 SET_GBE_FIELD(FRM_CONTROL
, FRM_DMA_ENABLE
, val
, 1);
363 gbe
->frm_control
= val
;
365 for (i
= 0; i
< 10000; i
++) {
366 val
= gbe
->frm_inhwctrl
;
367 if (GET_GBE_FIELD(FRM_INHWCTRL
, FRM_DMA_ENABLE
, val
) != 1)
373 printk(KERN_ERR
"gbefb: turn on DMA timed out\n");
378 static void gbe_loadcmap(void)
382 for (i
= 0; i
< 256; i
++) {
383 for (j
= 0; j
< 1000 && gbe
->cm_fifo
>= 63; j
++)
386 printk(KERN_ERR
"gbefb: cmap FIFO timeout\n");
388 gbe
->cmap
[i
] = gbe_cmap
[i
];
395 static int gbefb_blank(int blank
, struct fb_info
*info
)
397 /* 0 unblank, 1 blank, 2 no vsync, 3 no hsync, 4 off */
399 case FB_BLANK_UNBLANK
: /* unblank */
404 case FB_BLANK_NORMAL
: /* blank */
416 * Setup flatpanel related registers.
418 static void gbefb_setup_flatpanel(struct gbe_timing_info
*timing
)
420 int fp_wid
, fp_hgt
, fp_vbs
, fp_vbe
;
423 SET_GBE_FIELD(VT_FLAGS
, HDRV_INVERT
, outputVal
,
424 (timing
->flags
& FB_SYNC_HOR_HIGH_ACT
) ? 0 : 1);
425 SET_GBE_FIELD(VT_FLAGS
, VDRV_INVERT
, outputVal
,
426 (timing
->flags
& FB_SYNC_VERT_HIGH_ACT
) ? 0 : 1);
427 gbe
->vt_flags
= outputVal
;
429 /* Turn on the flat panel */
439 SET_GBE_FIELD(FP_DE
, ON
, outputVal
, fp_vbs
);
440 SET_GBE_FIELD(FP_DE
, OFF
, outputVal
, fp_vbe
);
441 gbe
->fp_de
= outputVal
;
443 SET_GBE_FIELD(FP_HDRV
, OFF
, outputVal
, fp_wid
);
444 gbe
->fp_hdrv
= outputVal
;
446 SET_GBE_FIELD(FP_VDRV
, ON
, outputVal
, 1);
447 SET_GBE_FIELD(FP_VDRV
, OFF
, outputVal
, fp_hgt
+ 1);
448 gbe
->fp_vdrv
= outputVal
;
451 struct gbe_pll_info
{
457 static struct gbe_pll_info gbe_pll_table
[2] = {
462 static int compute_gbe_timing(struct fb_var_screeninfo
*var
,
463 struct gbe_timing_info
*timing
)
465 int pll_m
, pll_n
, pll_p
, error
, best_m
, best_n
, best_p
, best_error
;
467 struct gbe_pll_info
*gbe_pll
;
469 if (gbe_revision
< 2)
470 gbe_pll
= &gbe_pll_table
[0];
472 gbe_pll
= &gbe_pll_table
[1];
474 /* Determine valid resolution and timing
475 * GBE crystal runs at 20Mhz or 27Mhz
476 * pll_m, pll_n, pll_p define the following frequencies
477 * fvco = pll_m * 20Mhz / pll_n
478 * fout = fvco / (2**pll_p) */
479 best_error
= 1000000000;
480 best_n
= best_m
= best_p
= 0;
481 for (pll_p
= 0; pll_p
< 4; pll_p
++)
482 for (pll_m
= 1; pll_m
< 256; pll_m
++)
483 for (pll_n
= 1; pll_n
< 64; pll_n
++) {
484 pixclock
= (1000000 / gbe_pll
->clock_rate
) *
485 (pll_n
<< pll_p
) / pll_m
;
487 error
= var
->pixclock
- pixclock
;
492 if (error
< best_error
&&
494 gbe_pll
->fvco_min
/ gbe_pll
->clock_rate
&&
496 gbe_pll
->fvco_max
/ gbe_pll
->clock_rate
) {
504 if (!best_n
|| !best_m
)
505 return -EINVAL
; /* Resolution to high */
507 pixclock
= (1000000 / gbe_pll
->clock_rate
) *
508 (best_n
<< best_p
) / best_m
;
510 /* set video timing information */
512 timing
->width
= var
->xres
;
513 timing
->height
= var
->yres
;
514 timing
->pll_m
= best_m
;
515 timing
->pll_n
= best_n
;
516 timing
->pll_p
= best_p
;
517 timing
->cfreq
= gbe_pll
->clock_rate
* 1000 * timing
->pll_m
/
518 (timing
->pll_n
<< timing
->pll_p
);
519 timing
->htotal
= var
->left_margin
+ var
->xres
+
520 var
->right_margin
+ var
->hsync_len
;
521 timing
->vtotal
= var
->upper_margin
+ var
->yres
+
522 var
->lower_margin
+ var
->vsync_len
;
523 timing
->fields_sec
= 1000 * timing
->cfreq
/ timing
->htotal
*
524 1000 / timing
->vtotal
;
525 timing
->hblank_start
= var
->xres
;
526 timing
->vblank_start
= var
->yres
;
527 timing
->hblank_end
= timing
->htotal
;
528 timing
->hsync_start
= var
->xres
+ var
->right_margin
+ 1;
529 timing
->hsync_end
= timing
->hsync_start
+ var
->hsync_len
;
530 timing
->vblank_end
= timing
->vtotal
;
531 timing
->vsync_start
= var
->yres
+ var
->lower_margin
+ 1;
532 timing
->vsync_end
= timing
->vsync_start
+ var
->vsync_len
;
538 static void gbe_set_timing_info(struct gbe_timing_info
*timing
)
543 /* setup dot clock PLL */
545 SET_GBE_FIELD(DOTCLK
, M
, val
, timing
->pll_m
- 1);
546 SET_GBE_FIELD(DOTCLK
, N
, val
, timing
->pll_n
- 1);
547 SET_GBE_FIELD(DOTCLK
, P
, val
, timing
->pll_p
);
548 SET_GBE_FIELD(DOTCLK
, RUN
, val
, 0); /* do not start yet */
552 /* setup pixel counter */
554 SET_GBE_FIELD(VT_XYMAX
, MAXX
, val
, timing
->htotal
);
555 SET_GBE_FIELD(VT_XYMAX
, MAXY
, val
, timing
->vtotal
);
558 /* setup video timing signals */
560 SET_GBE_FIELD(VT_VSYNC
, VSYNC_ON
, val
, timing
->vsync_start
);
561 SET_GBE_FIELD(VT_VSYNC
, VSYNC_OFF
, val
, timing
->vsync_end
);
564 SET_GBE_FIELD(VT_HSYNC
, HSYNC_ON
, val
, timing
->hsync_start
);
565 SET_GBE_FIELD(VT_HSYNC
, HSYNC_OFF
, val
, timing
->hsync_end
);
568 SET_GBE_FIELD(VT_VBLANK
, VBLANK_ON
, val
, timing
->vblank_start
);
569 SET_GBE_FIELD(VT_VBLANK
, VBLANK_OFF
, val
, timing
->vblank_end
);
570 gbe
->vt_vblank
= val
;
572 SET_GBE_FIELD(VT_HBLANK
, HBLANK_ON
, val
,
573 timing
->hblank_start
- 5);
574 SET_GBE_FIELD(VT_HBLANK
, HBLANK_OFF
, val
,
575 timing
->hblank_end
- 3);
576 gbe
->vt_hblank
= val
;
578 /* setup internal timing signals */
580 SET_GBE_FIELD(VT_VCMAP
, VCMAP_ON
, val
, timing
->vblank_start
);
581 SET_GBE_FIELD(VT_VCMAP
, VCMAP_OFF
, val
, timing
->vblank_end
);
584 SET_GBE_FIELD(VT_HCMAP
, HCMAP_ON
, val
, timing
->hblank_start
);
585 SET_GBE_FIELD(VT_HCMAP
, HCMAP_OFF
, val
, timing
->hblank_end
);
589 temp
= timing
->vblank_start
- timing
->vblank_end
- 1;
593 if (flat_panel_enabled
)
594 gbefb_setup_flatpanel(timing
);
596 SET_GBE_FIELD(DID_START_XY
, DID_STARTY
, val
, (u32
) temp
);
597 if (timing
->hblank_end
>= 20)
598 SET_GBE_FIELD(DID_START_XY
, DID_STARTX
, val
,
599 timing
->hblank_end
- 20);
601 SET_GBE_FIELD(DID_START_XY
, DID_STARTX
, val
,
602 timing
->htotal
- (20 - timing
->hblank_end
));
603 gbe
->did_start_xy
= val
;
606 SET_GBE_FIELD(CRS_START_XY
, CRS_STARTY
, val
, (u32
) (temp
+ 1));
607 if (timing
->hblank_end
>= GBE_CRS_MAGIC
)
608 SET_GBE_FIELD(CRS_START_XY
, CRS_STARTX
, val
,
609 timing
->hblank_end
- GBE_CRS_MAGIC
);
611 SET_GBE_FIELD(CRS_START_XY
, CRS_STARTX
, val
,
612 timing
->htotal
- (GBE_CRS_MAGIC
-
613 timing
->hblank_end
));
614 gbe
->crs_start_xy
= val
;
617 SET_GBE_FIELD(VC_START_XY
, VC_STARTY
, val
, (u32
) temp
);
618 SET_GBE_FIELD(VC_START_XY
, VC_STARTX
, val
, timing
->hblank_end
- 4);
619 gbe
->vc_start_xy
= val
;
622 temp
= timing
->hblank_end
- GBE_PIXEN_MAGIC_ON
;
624 temp
+= timing
->htotal
; /* allow blank to wrap around */
626 SET_GBE_FIELD(VT_HPIXEN
, HPIXEN_ON
, val
, temp
);
627 SET_GBE_FIELD(VT_HPIXEN
, HPIXEN_OFF
, val
,
628 ((temp
+ timing
->width
-
629 GBE_PIXEN_MAGIC_OFF
) % timing
->htotal
));
630 gbe
->vt_hpixen
= val
;
633 SET_GBE_FIELD(VT_VPIXEN
, VPIXEN_ON
, val
, timing
->vblank_end
);
634 SET_GBE_FIELD(VT_VPIXEN
, VPIXEN_OFF
, val
, timing
->vblank_start
);
635 gbe
->vt_vpixen
= val
;
637 /* turn off sync on green */
639 SET_GBE_FIELD(VT_FLAGS
, SYNC_LOW
, val
, 1);
644 * Set the hardware according to 'par'.
647 static int gbefb_set_par(struct fb_info
*info
)
651 int wholeTilesX
, partTilesX
, maxPixelsPerTileX
;
653 int xpmax
, ypmax
; /* Monitor resolution */
654 int bytesPerPixel
; /* Bytes per pixel */
655 struct gbefb_par
*par
= (struct gbefb_par
*) info
->par
;
657 compute_gbe_timing(&info
->var
, &par
->timing
);
659 bytesPerPixel
= info
->var
.bits_per_pixel
/ 8;
660 info
->fix
.line_length
= info
->var
.xres_virtual
* bytesPerPixel
;
661 xpmax
= par
->timing
.width
;
662 ypmax
= par
->timing
.height
;
667 /* set timing info */
668 gbe_set_timing_info(&par
->timing
);
670 /* initialize DIDs */
672 switch (bytesPerPixel
) {
674 SET_GBE_FIELD(WID
, TYP
, val
, GBE_CMODE_I8
);
675 info
->fix
.visual
= FB_VISUAL_PSEUDOCOLOR
;
678 SET_GBE_FIELD(WID
, TYP
, val
, GBE_CMODE_ARGB5
);
679 info
->fix
.visual
= FB_VISUAL_TRUECOLOR
;
682 SET_GBE_FIELD(WID
, TYP
, val
, GBE_CMODE_RGB8
);
683 info
->fix
.visual
= FB_VISUAL_TRUECOLOR
;
686 SET_GBE_FIELD(WID
, BUF
, val
, GBE_BMODE_BOTH
);
688 for (i
= 0; i
< 32; i
++)
689 gbe
->mode_regs
[i
] = val
;
691 /* Initialize interrupts */
692 gbe
->vt_intr01
= 0xffffffff;
693 gbe
->vt_intr23
= 0xffffffff;
696 The GBE hardware uses a tiled memory to screen mapping. Tiles are
697 blocks of 512x128, 256x128 or 128x128 pixels, respectively for 8bit,
698 16bit and 32 bit modes (64 kB). They cover the screen with partial
699 tiles on the right and/or bottom of the screen if needed.
700 For example in 640x480 8 bit mode the mapping is:
703 <---- 512 ----><128|384 offscreen>
705 | 128 [tile 0] [tile 1]
708 4 128 [tile 2] [tile 3]
711 128 [tile 4] [tile 5]
714 v 96 [tile 6] [tile 7]
717 Tiles have the advantage that they can be allocated individually in
718 memory. However, this mapping is not linear at all, which is not
719 really convenient. In order to support linear addressing, the GBE
720 DMA hardware is fooled into thinking the screen is only one tile
721 large and but has a greater height, so that the DMA transfer covers
723 Tiles are still allocated as independent chunks of 64KB of
724 continuous physical memory and remapped so that the kernel sees the
725 framebuffer as a continuous virtual memory. The GBE tile table is
726 set up so that each tile references one of these 64k blocks:
728 GBE -> tile list framebuffer TLB <------------ CPU
729 [ tile 0 ] -> [ 64KB ] <- [ 16x 4KB page entries ] ^
730 ... ... ... linear virtual FB
731 [ tile n ] -> [ 64KB ] <- [ 16x 4KB page entries ] v
734 The GBE hardware is then told that the buffer is 512*tweaked_height,
735 with tweaked_height = real_width*real_height/pixels_per_tile.
736 Thus the GBE hardware will scan the first tile, filing the first 64k
737 covered region of the screen, and then will proceed to the next
738 tile, until the whole screen is covered.
740 Here is what would happen at 640x480 8bit:
743 ^ 11111111111111112222 11111111111111111111 ^
744 128 11111111111111112222 11111111111111111111 102 lines
745 11111111111111112222 11111111111111111111 v
746 V 11111111111111112222 11111111222222222222
747 33333333333333334444 22222222222222222222
748 33333333333333334444 22222222222222222222
749 < 512 > < 256 > 102*640+256 = 64k
751 NOTE: The only mode for which this is not working is 800x600 8bit,
752 as 800*600/512 = 937.5 which is not integer and thus causes
754 I guess this is not so important as one can use 640x480 8bit or
755 800x600 16bit anyway.
758 /* Tell gbe about the tiles table location */
759 /* tile_ptr -> [ tile 1 ] -> FB mem */
760 /* [ tile 2 ] -> FB mem */
763 SET_GBE_FIELD(FRM_CONTROL
, FRM_TILE_PTR
, val
, gbe_tiles
.dma
>> 9);
764 SET_GBE_FIELD(FRM_CONTROL
, FRM_DMA_ENABLE
, val
, 0); /* do not start */
765 SET_GBE_FIELD(FRM_CONTROL
, FRM_LINEAR
, val
, 0);
766 gbe
->frm_control
= val
;
768 maxPixelsPerTileX
= 512 / bytesPerPixel
;
772 /* Initialize the framebuffer */
774 SET_GBE_FIELD(FRM_SIZE_TILE
, FRM_WIDTH_TILE
, val
, wholeTilesX
);
775 SET_GBE_FIELD(FRM_SIZE_TILE
, FRM_RHS
, val
, partTilesX
);
777 switch (bytesPerPixel
) {
779 SET_GBE_FIELD(FRM_SIZE_TILE
, FRM_DEPTH
, val
,
783 SET_GBE_FIELD(FRM_SIZE_TILE
, FRM_DEPTH
, val
,
787 SET_GBE_FIELD(FRM_SIZE_TILE
, FRM_DEPTH
, val
,
791 gbe
->frm_size_tile
= val
;
793 /* compute tweaked height */
794 height_pix
= xpmax
* ypmax
/ maxPixelsPerTileX
;
797 SET_GBE_FIELD(FRM_SIZE_PIXEL
, FB_HEIGHT_PIX
, val
, height_pix
);
798 gbe
->frm_size_pixel
= val
;
800 /* turn off DID and overlay DMA */
801 gbe
->did_control
= 0;
802 gbe
->ovr_width_tile
= 0;
804 /* Turn off mouse cursor */
810 /* Initialize the gamma map */
812 for (i
= 0; i
< 256; i
++)
813 gbe
->gmap
[i
] = (i
<< 24) | (i
<< 16) | (i
<< 8);
815 /* Initialize the color map */
816 for (i
= 0; i
< 256; i
++)
817 gbe_cmap
[i
] = (i
<< 8) | (i
<< 16) | (i
<< 24);
824 static void gbefb_encode_fix(struct fb_fix_screeninfo
*fix
,
825 struct fb_var_screeninfo
*var
)
827 memset(fix
, 0, sizeof(struct fb_fix_screeninfo
));
828 strcpy(fix
->id
, "SGI GBE");
829 fix
->smem_start
= (unsigned long) gbe_mem
;
830 fix
->smem_len
= gbe_mem_size
;
831 fix
->type
= FB_TYPE_PACKED_PIXELS
;
833 fix
->accel
= FB_ACCEL_NONE
;
834 switch (var
->bits_per_pixel
) {
836 fix
->visual
= FB_VISUAL_PSEUDOCOLOR
;
839 fix
->visual
= FB_VISUAL_TRUECOLOR
;
845 fix
->line_length
= var
->xres_virtual
* var
->bits_per_pixel
/ 8;
846 fix
->mmio_start
= GBE_BASE
;
847 fix
->mmio_len
= sizeof(struct sgi_gbe
);
851 * Set a single color register. The values supplied are already
852 * rounded down to the hardware's capabilities (according to the
853 * entries in the var structure). Return != 0 for invalid regno.
856 static int gbefb_setcolreg(unsigned regno
, unsigned red
, unsigned green
,
857 unsigned blue
, unsigned transp
,
858 struct fb_info
*info
)
868 if (info
->var
.bits_per_pixel
<= 8) {
869 gbe_cmap
[regno
] = (red
<< 24) | (green
<< 16) | (blue
<< 8);
871 /* wait for the color map FIFO to have a free entry */
872 for (i
= 0; i
< 1000 && gbe
->cm_fifo
>= 63; i
++)
875 printk(KERN_ERR
"gbefb: cmap FIFO timeout\n");
878 gbe
->cmap
[regno
] = gbe_cmap
[regno
];
880 } else if (regno
< 16) {
881 switch (info
->var
.bits_per_pixel
) {
887 pseudo_palette
[regno
] =
888 (red
<< info
->var
.red
.offset
) |
889 (green
<< info
->var
.green
.offset
) |
890 (blue
<< info
->var
.blue
.offset
);
893 pseudo_palette
[regno
] =
894 (red
<< info
->var
.red
.offset
) |
895 (green
<< info
->var
.green
.offset
) |
896 (blue
<< info
->var
.blue
.offset
);
905 * Check video mode validity, eventually modify var to best match.
907 static int gbefb_check_var(struct fb_var_screeninfo
*var
, struct fb_info
*info
)
909 unsigned int line_length
;
910 struct gbe_timing_info timing
;
913 /* Limit bpp to 8, 16, and 32 */
914 if (var
->bits_per_pixel
<= 8)
915 var
->bits_per_pixel
= 8;
916 else if (var
->bits_per_pixel
<= 16)
917 var
->bits_per_pixel
= 16;
918 else if (var
->bits_per_pixel
<= 32)
919 var
->bits_per_pixel
= 32;
923 /* Check the mode can be mapped linearly with the tile table trick. */
924 /* This requires width x height x bytes/pixel be a multiple of 512 */
925 if ((var
->xres
* var
->yres
* var
->bits_per_pixel
) & 4095)
928 var
->grayscale
= 0; /* No grayscale for now */
930 ret
= compute_gbe_timing(var
, &timing
);
935 /* Adjust virtual resolution, if necessary */
936 if (var
->xres
> var
->xres_virtual
|| (!ywrap
&& !ypan
))
937 var
->xres_virtual
= var
->xres
;
938 if (var
->yres
> var
->yres_virtual
|| (!ywrap
&& !ypan
))
939 var
->yres_virtual
= var
->yres
;
941 if (var
->vmode
& FB_VMODE_CONUPDATE
) {
942 var
->vmode
|= FB_VMODE_YWRAP
;
943 var
->xoffset
= info
->var
.xoffset
;
944 var
->yoffset
= info
->var
.yoffset
;
947 /* No grayscale for now */
951 line_length
= var
->xres_virtual
* var
->bits_per_pixel
/ 8;
952 if (line_length
* var
->yres_virtual
> gbe_mem_size
)
953 return -ENOMEM
; /* Virtual resolution too high */
955 switch (var
->bits_per_pixel
) {
959 var
->green
.offset
= 0;
960 var
->green
.length
= 8;
961 var
->blue
.offset
= 0;
962 var
->blue
.length
= 8;
963 var
->transp
.offset
= 0;
964 var
->transp
.length
= 0;
966 case 16: /* RGB 1555 */
967 var
->red
.offset
= 10;
969 var
->green
.offset
= 5;
970 var
->green
.length
= 5;
971 var
->blue
.offset
= 0;
972 var
->blue
.length
= 5;
973 var
->transp
.offset
= 0;
974 var
->transp
.length
= 0;
976 case 32: /* RGB 8888 */
977 var
->red
.offset
= 24;
979 var
->green
.offset
= 16;
980 var
->green
.length
= 8;
981 var
->blue
.offset
= 8;
982 var
->blue
.length
= 8;
983 var
->transp
.offset
= 0;
984 var
->transp
.length
= 8;
987 var
->red
.msb_right
= 0;
988 var
->green
.msb_right
= 0;
989 var
->blue
.msb_right
= 0;
990 var
->transp
.msb_right
= 0;
992 var
->left_margin
= timing
.htotal
- timing
.hsync_end
;
993 var
->right_margin
= timing
.hsync_start
- timing
.width
;
994 var
->upper_margin
= timing
.vtotal
- timing
.vsync_end
;
995 var
->lower_margin
= timing
.vsync_start
- timing
.height
;
996 var
->hsync_len
= timing
.hsync_end
- timing
.hsync_start
;
997 var
->vsync_len
= timing
.vsync_end
- timing
.vsync_start
;
1002 static int gbefb_mmap(struct fb_info
*info
,
1003 struct vm_area_struct
*vma
)
1005 unsigned long size
= vma
->vm_end
- vma
->vm_start
;
1006 unsigned long offset
= vma
->vm_pgoff
<< PAGE_SHIFT
;
1008 unsigned long phys_addr
, phys_size
;
1012 if (vma
->vm_pgoff
> (~0UL >> PAGE_SHIFT
))
1014 if (size
> gbe_mem_size
)
1016 if (offset
> gbe_mem_size
- size
)
1019 /* remap using the fastest write-through mode on architecture */
1020 /* try not polluting the cache when possible */
1021 pgprot_val(vma
->vm_page_prot
) =
1022 pgprot_fb(pgprot_val(vma
->vm_page_prot
));
1024 /* VM_IO | VM_DONTEXPAND | VM_DONTDUMP are set by remap_pfn_range() */
1026 /* look for the starting tile */
1027 tile
= &gbe_tiles
.cpu
[offset
>> TILE_SHIFT
];
1028 addr
= vma
->vm_start
;
1029 offset
&= TILE_MASK
;
1031 /* remap each tile separately */
1033 phys_addr
= (((unsigned long) (*tile
)) << TILE_SHIFT
) + offset
;
1034 if ((offset
+ size
) < TILE_SIZE
)
1037 phys_size
= TILE_SIZE
- offset
;
1039 if (remap_pfn_range(vma
, addr
, phys_addr
>> PAGE_SHIFT
,
1040 phys_size
, vma
->vm_page_prot
))
1052 static struct fb_ops gbefb_ops
= {
1053 .owner
= THIS_MODULE
,
1054 .fb_check_var
= gbefb_check_var
,
1055 .fb_set_par
= gbefb_set_par
,
1056 .fb_setcolreg
= gbefb_setcolreg
,
1057 .fb_mmap
= gbefb_mmap
,
1058 .fb_blank
= gbefb_blank
,
1059 .fb_fillrect
= cfb_fillrect
,
1060 .fb_copyarea
= cfb_copyarea
,
1061 .fb_imageblit
= cfb_imageblit
,
1068 static ssize_t
gbefb_show_memsize(struct device
*dev
, struct device_attribute
*attr
, char *buf
)
1070 return snprintf(buf
, PAGE_SIZE
, "%u\n", gbe_mem_size
);
1073 static DEVICE_ATTR(size
, S_IRUGO
, gbefb_show_memsize
, NULL
);
1075 static ssize_t
gbefb_show_rev(struct device
*device
, struct device_attribute
*attr
, char *buf
)
1077 return snprintf(buf
, PAGE_SIZE
, "%d\n", gbe_revision
);
1080 static DEVICE_ATTR(revision
, S_IRUGO
, gbefb_show_rev
, NULL
);
1082 static void gbefb_remove_sysfs(struct device
*dev
)
1084 device_remove_file(dev
, &dev_attr_size
);
1085 device_remove_file(dev
, &dev_attr_revision
);
1088 static void gbefb_create_sysfs(struct device
*dev
)
1090 device_create_file(dev
, &dev_attr_size
);
1091 device_create_file(dev
, &dev_attr_revision
);
1098 static int gbefb_setup(char *options
)
1102 if (!options
|| !*options
)
1105 while ((this_opt
= strsep(&options
, ",")) != NULL
) {
1106 if (!strncmp(this_opt
, "monitor:", 8)) {
1107 if (!strncmp(this_opt
+ 8, "crt", 3)) {
1108 flat_panel_enabled
= 0;
1109 default_var
= &default_var_CRT
;
1110 default_mode
= &default_mode_CRT
;
1111 } else if (!strncmp(this_opt
+ 8, "1600sw", 6) ||
1112 !strncmp(this_opt
+ 8, "lcd", 3)) {
1113 flat_panel_enabled
= 1;
1114 default_var
= &default_var_LCD
;
1115 default_mode
= &default_mode_LCD
;
1117 } else if (!strncmp(this_opt
, "mem:", 4)) {
1118 gbe_mem_size
= memparse(this_opt
+ 4, &this_opt
);
1119 if (gbe_mem_size
> CONFIG_FB_GBE_MEM
* 1024 * 1024)
1120 gbe_mem_size
= CONFIG_FB_GBE_MEM
* 1024 * 1024;
1121 if (gbe_mem_size
< TILE_SIZE
)
1122 gbe_mem_size
= TILE_SIZE
;
1124 mode_option
= this_opt
;
1129 static int gbefb_probe(struct platform_device
*p_dev
)
1132 struct fb_info
*info
;
1133 struct gbefb_par
*par
;
1135 char *options
= NULL
;
1138 info
= framebuffer_alloc(sizeof(struct gbefb_par
), &p_dev
->dev
);
1143 if (fb_get_options("gbefb", &options
)) {
1145 goto out_release_framebuffer
;
1147 gbefb_setup(options
);
1150 if (!request_mem_region(GBE_BASE
, sizeof(struct sgi_gbe
), "GBE")) {
1151 printk(KERN_ERR
"gbefb: couldn't reserve mmio region\n");
1153 goto out_release_framebuffer
;
1156 gbe
= (struct sgi_gbe
*) devm_ioremap(&p_dev
->dev
, GBE_BASE
,
1157 sizeof(struct sgi_gbe
));
1159 printk(KERN_ERR
"gbefb: couldn't map mmio region\n");
1161 goto out_release_mem_region
;
1163 gbe_revision
= gbe
->ctrlstat
& 15;
1166 dma_alloc_coherent(NULL
, GBE_TLB_SIZE
* sizeof(uint16_t),
1167 &gbe_tiles
.dma
, GFP_KERNEL
);
1168 if (!gbe_tiles
.cpu
) {
1169 printk(KERN_ERR
"gbefb: couldn't allocate tiles table\n");
1171 goto out_release_mem_region
;
1175 /* memory was allocated at boot time */
1176 gbe_mem
= devm_ioremap_wc(&p_dev
->dev
, gbe_mem_phys
,
1179 printk(KERN_ERR
"gbefb: couldn't map framebuffer\n");
1181 goto out_tiles_free
;
1186 /* try to allocate memory with the classical allocator
1187 * this has high chance to fail on low memory machines */
1188 gbe_mem
= dma_alloc_wc(NULL
, gbe_mem_size
, &gbe_dma_addr
,
1191 printk(KERN_ERR
"gbefb: couldn't allocate framebuffer memory\n");
1193 goto out_tiles_free
;
1196 gbe_mem_phys
= (unsigned long) gbe_dma_addr
;
1200 par
->wc_cookie
= arch_phys_wc_add(gbe_mem_phys
, gbe_mem_size
);
1202 /* map framebuffer memory into tiles table */
1203 for (i
= 0; i
< (gbe_mem_size
>> TILE_SHIFT
); i
++)
1204 gbe_tiles
.cpu
[i
] = (gbe_mem_phys
>> TILE_SHIFT
) + i
;
1206 info
->fbops
= &gbefb_ops
;
1207 info
->pseudo_palette
= pseudo_palette
;
1208 info
->flags
= FBINFO_DEFAULT
;
1209 info
->screen_base
= gbe_mem
;
1210 fb_alloc_cmap(&info
->cmap
, 256, 0);
1215 /* turn on default video mode */
1216 if (fb_find_mode(&par
->var
, info
, mode_option
, NULL
, 0,
1217 default_mode
, 8) == 0)
1218 par
->var
= *default_var
;
1219 info
->var
= par
->var
;
1220 gbefb_check_var(&par
->var
, info
);
1221 gbefb_encode_fix(&info
->fix
, &info
->var
);
1223 if (register_framebuffer(info
) < 0) {
1224 printk(KERN_ERR
"gbefb: couldn't register framebuffer\n");
1229 platform_set_drvdata(p_dev
, info
);
1230 gbefb_create_sysfs(&p_dev
->dev
);
1232 fb_info(info
, "%s rev %d @ 0x%08x using %dkB memory\n",
1233 info
->fix
.id
, gbe_revision
, (unsigned)GBE_BASE
,
1234 gbe_mem_size
>> 10);
1239 arch_phys_wc_del(par
->wc_cookie
);
1241 dma_free_wc(NULL
, gbe_mem_size
, gbe_mem
, gbe_mem_phys
);
1243 dma_free_coherent(NULL
, GBE_TLB_SIZE
* sizeof(uint16_t),
1244 (void *)gbe_tiles
.cpu
, gbe_tiles
.dma
);
1245 out_release_mem_region
:
1246 release_mem_region(GBE_BASE
, sizeof(struct sgi_gbe
));
1247 out_release_framebuffer
:
1248 framebuffer_release(info
);
1253 static int gbefb_remove(struct platform_device
* p_dev
)
1255 struct fb_info
*info
= platform_get_drvdata(p_dev
);
1256 struct gbefb_par
*par
= info
->par
;
1258 unregister_framebuffer(info
);
1260 arch_phys_wc_del(par
->wc_cookie
);
1262 dma_free_wc(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");