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 #define GBE_BASE 0x16000000 /* SGI O2 */
44 /* macro for fastest write-though access to the framebuffer */
46 #ifdef CONFIG_CPU_R10000
47 #define pgprot_fb(_prot) (((_prot) & (~_CACHE_MASK)) | _CACHE_UNCACHED_ACCELERATED)
49 #define pgprot_fb(_prot) (((_prot) & (~_CACHE_MASK)) | _CACHE_CACHABLE_NO_WA)
54 * RAM we reserve for the frame buffer. This defines the maximum screen
57 #if CONFIG_FB_GBE_MEM > 8
58 #error GBE Framebuffer cannot use more than 8MB of memory
62 #define TILE_SIZE (1 << TILE_SHIFT)
63 #define TILE_MASK (TILE_SIZE - 1)
65 static unsigned int gbe_mem_size
= CONFIG_FB_GBE_MEM
* 1024*1024;
67 static dma_addr_t gbe_dma_addr
;
68 static unsigned long gbe_mem_phys
;
75 static int gbe_revision
;
77 static int ypan
, ywrap
;
79 static uint32_t pseudo_palette
[16];
80 static uint32_t gbe_cmap
[256];
81 static int gbe_turned_on
; /* 0 turned off, 1 turned on */
83 static char *mode_option
= NULL
;
85 /* default CRT mode */
86 static struct fb_var_screeninfo default_var_CRT
= {
87 /* 640x480, 60 Hz, Non-Interlaced (25.175 MHz dotclock) */
99 .transp
= { 0, 0, 0 },
105 .pixclock
= 39722, /* picoseconds */
113 .vmode
= FB_VMODE_NONINTERLACED
,
116 /* default LCD mode */
117 static struct fb_var_screeninfo default_var_LCD
= {
118 /* 1600x1024, 8 bpp */
121 .xres_virtual
= 1600,
122 .yres_virtual
= 1024,
128 .green
= { 0, 8, 0 },
130 .transp
= { 0, 0, 0 },
144 .vmode
= FB_VMODE_NONINTERLACED
147 /* default modedb mode */
148 /* 640x480, 60 Hz, Non-Interlaced (25.172 MHz dotclock) */
149 static struct fb_videomode default_mode_CRT
= {
161 .vmode
= FB_VMODE_NONINTERLACED
,
163 /* 1600x1024 SGI flatpanel 1600sw */
164 static struct fb_videomode default_mode_LCD
= {
165 /* 1600x1024, 8 bpp */
175 .vmode
= FB_VMODE_NONINTERLACED
,
178 static struct fb_videomode
*default_mode
= &default_mode_CRT
;
179 static struct fb_var_screeninfo
*default_var
= &default_var_CRT
;
181 static int flat_panel_enabled
= 0;
183 static void gbe_reset(void)
185 /* Turn on dotclock PLL */
186 gbe
->ctrlstat
= 0x300aa000;
191 * Function: gbe_turn_off
193 * Description: This should turn off the monitor and gbe. This is used
194 * when switching between the serial console and the graphics
198 static void gbe_turn_off(void)
201 unsigned int val
, x
, y
, vpixen_off
;
205 /* check if pixel counter is on */
207 if (GET_GBE_FIELD(VT_XY
, FREEZE
, val
) == 1)
211 val
= gbe
->ovr_control
;
212 SET_GBE_FIELD(OVR_CONTROL
, OVR_DMA_ENABLE
, val
, 0);
213 gbe
->ovr_control
= val
;
215 val
= gbe
->frm_control
;
216 SET_GBE_FIELD(FRM_CONTROL
, FRM_DMA_ENABLE
, val
, 0);
217 gbe
->frm_control
= val
;
219 val
= gbe
->did_control
;
220 SET_GBE_FIELD(DID_CONTROL
, DID_DMA_ENABLE
, val
, 0);
221 gbe
->did_control
= val
;
224 /* We have to wait through two vertical retrace periods before
225 * the pixel DMA is turned off for sure. */
226 for (i
= 0; i
< 10000; i
++) {
227 val
= gbe
->frm_inhwctrl
;
228 if (GET_GBE_FIELD(FRM_INHWCTRL
, FRM_DMA_ENABLE
, val
)) {
231 val
= gbe
->ovr_inhwctrl
;
232 if (GET_GBE_FIELD(OVR_INHWCTRL
, OVR_DMA_ENABLE
, val
)) {
235 val
= gbe
->did_inhwctrl
;
236 if (GET_GBE_FIELD(DID_INHWCTRL
, DID_DMA_ENABLE
, val
)) {
244 printk(KERN_ERR
"gbefb: turn off DMA timed out\n");
246 /* wait for vpixen_off */
247 val
= gbe
->vt_vpixen
;
248 vpixen_off
= GET_GBE_FIELD(VT_VPIXEN
, VPIXEN_OFF
, val
);
250 for (i
= 0; i
< 100000; i
++) {
252 x
= GET_GBE_FIELD(VT_XY
, X
, val
);
253 y
= GET_GBE_FIELD(VT_XY
, Y
, val
);
260 "gbefb: wait for vpixen_off timed out\n");
261 for (i
= 0; i
< 10000; i
++) {
263 x
= GET_GBE_FIELD(VT_XY
, X
, val
);
264 y
= GET_GBE_FIELD(VT_XY
, Y
, val
);
270 printk(KERN_ERR
"gbefb: wait for vpixen_off timed out\n");
272 /* turn off pixel counter */
274 SET_GBE_FIELD(VT_XY
, FREEZE
, val
, 1);
277 for (i
= 0; i
< 10000; i
++) {
279 if (GET_GBE_FIELD(VT_XY
, FREEZE
, val
) != 1)
285 printk(KERN_ERR
"gbefb: turn off pixel clock timed out\n");
287 /* turn off dot clock */
289 SET_GBE_FIELD(DOTCLK
, RUN
, val
, 0);
292 for (i
= 0; i
< 10000; i
++) {
294 if (GET_GBE_FIELD(DOTCLK
, RUN
, val
))
300 printk(KERN_ERR
"gbefb: turn off dotclock timed out\n");
302 /* reset the frame DMA FIFO */
303 val
= gbe
->frm_size_tile
;
304 SET_GBE_FIELD(FRM_SIZE_TILE
, FRM_FIFO_RESET
, val
, 1);
305 gbe
->frm_size_tile
= val
;
306 SET_GBE_FIELD(FRM_SIZE_TILE
, FRM_FIFO_RESET
, val
, 0);
307 gbe
->frm_size_tile
= val
;
310 static void gbe_turn_on(void)
315 * Check if pixel counter is off, for unknown reason this
316 * code hangs Visual Workstations
318 if (gbe_revision
< 2) {
320 if (GET_GBE_FIELD(VT_XY
, FREEZE
, val
) == 0)
324 /* turn on dot clock */
326 SET_GBE_FIELD(DOTCLK
, RUN
, val
, 1);
329 for (i
= 0; i
< 10000; i
++) {
331 if (GET_GBE_FIELD(DOTCLK
, RUN
, val
) != 1)
337 printk(KERN_ERR
"gbefb: turn on dotclock timed out\n");
339 /* turn on pixel counter */
341 SET_GBE_FIELD(VT_XY
, FREEZE
, val
, 0);
344 for (i
= 0; i
< 10000; i
++) {
346 if (GET_GBE_FIELD(VT_XY
, FREEZE
, val
))
352 printk(KERN_ERR
"gbefb: turn on pixel clock timed out\n");
355 val
= gbe
->frm_control
;
356 SET_GBE_FIELD(FRM_CONTROL
, FRM_DMA_ENABLE
, val
, 1);
357 gbe
->frm_control
= val
;
359 for (i
= 0; i
< 10000; i
++) {
360 val
= gbe
->frm_inhwctrl
;
361 if (GET_GBE_FIELD(FRM_INHWCTRL
, FRM_DMA_ENABLE
, val
) != 1)
367 printk(KERN_ERR
"gbefb: turn on DMA timed out\n");
372 static void gbe_loadcmap(void)
376 for (i
= 0; i
< 256; i
++) {
377 for (j
= 0; j
< 1000 && gbe
->cm_fifo
>= 63; j
++)
380 printk(KERN_ERR
"gbefb: cmap FIFO timeout\n");
382 gbe
->cmap
[i
] = gbe_cmap
[i
];
389 static int gbefb_blank(int blank
, struct fb_info
*info
)
391 /* 0 unblank, 1 blank, 2 no vsync, 3 no hsync, 4 off */
393 case FB_BLANK_UNBLANK
: /* unblank */
398 case FB_BLANK_NORMAL
: /* blank */
410 * Setup flatpanel related registers.
412 static void gbefb_setup_flatpanel(struct gbe_timing_info
*timing
)
414 int fp_wid
, fp_hgt
, fp_vbs
, fp_vbe
;
417 SET_GBE_FIELD(VT_FLAGS
, HDRV_INVERT
, outputVal
,
418 (timing
->flags
& FB_SYNC_HOR_HIGH_ACT
) ? 0 : 1);
419 SET_GBE_FIELD(VT_FLAGS
, VDRV_INVERT
, outputVal
,
420 (timing
->flags
& FB_SYNC_VERT_HIGH_ACT
) ? 0 : 1);
421 gbe
->vt_flags
= outputVal
;
423 /* Turn on the flat panel */
433 SET_GBE_FIELD(FP_DE
, ON
, outputVal
, fp_vbs
);
434 SET_GBE_FIELD(FP_DE
, OFF
, outputVal
, fp_vbe
);
435 gbe
->fp_de
= outputVal
;
437 SET_GBE_FIELD(FP_HDRV
, OFF
, outputVal
, fp_wid
);
438 gbe
->fp_hdrv
= outputVal
;
440 SET_GBE_FIELD(FP_VDRV
, ON
, outputVal
, 1);
441 SET_GBE_FIELD(FP_VDRV
, OFF
, outputVal
, fp_hgt
+ 1);
442 gbe
->fp_vdrv
= outputVal
;
445 struct gbe_pll_info
{
451 static struct gbe_pll_info gbe_pll_table
[2] = {
456 static int compute_gbe_timing(struct fb_var_screeninfo
*var
,
457 struct gbe_timing_info
*timing
)
459 int pll_m
, pll_n
, pll_p
, error
, best_m
, best_n
, best_p
, best_error
;
461 struct gbe_pll_info
*gbe_pll
;
463 if (gbe_revision
< 2)
464 gbe_pll
= &gbe_pll_table
[0];
466 gbe_pll
= &gbe_pll_table
[1];
468 /* Determine valid resolution and timing
469 * GBE crystal runs at 20Mhz or 27Mhz
470 * pll_m, pll_n, pll_p define the following frequencies
471 * fvco = pll_m * 20Mhz / pll_n
472 * fout = fvco / (2**pll_p) */
473 best_error
= 1000000000;
474 best_n
= best_m
= best_p
= 0;
475 for (pll_p
= 0; pll_p
< 4; pll_p
++)
476 for (pll_m
= 1; pll_m
< 256; pll_m
++)
477 for (pll_n
= 1; pll_n
< 64; pll_n
++) {
478 pixclock
= (1000000 / gbe_pll
->clock_rate
) *
479 (pll_n
<< pll_p
) / pll_m
;
481 error
= var
->pixclock
- pixclock
;
486 if (error
< best_error
&&
488 gbe_pll
->fvco_min
/ gbe_pll
->clock_rate
&&
490 gbe_pll
->fvco_max
/ gbe_pll
->clock_rate
) {
498 if (!best_n
|| !best_m
)
499 return -EINVAL
; /* Resolution to high */
501 pixclock
= (1000000 / gbe_pll
->clock_rate
) *
502 (best_n
<< best_p
) / best_m
;
504 /* set video timing information */
506 timing
->width
= var
->xres
;
507 timing
->height
= var
->yres
;
508 timing
->pll_m
= best_m
;
509 timing
->pll_n
= best_n
;
510 timing
->pll_p
= best_p
;
511 timing
->cfreq
= gbe_pll
->clock_rate
* 1000 * timing
->pll_m
/
512 (timing
->pll_n
<< timing
->pll_p
);
513 timing
->htotal
= var
->left_margin
+ var
->xres
+
514 var
->right_margin
+ var
->hsync_len
;
515 timing
->vtotal
= var
->upper_margin
+ var
->yres
+
516 var
->lower_margin
+ var
->vsync_len
;
517 timing
->fields_sec
= 1000 * timing
->cfreq
/ timing
->htotal
*
518 1000 / timing
->vtotal
;
519 timing
->hblank_start
= var
->xres
;
520 timing
->vblank_start
= var
->yres
;
521 timing
->hblank_end
= timing
->htotal
;
522 timing
->hsync_start
= var
->xres
+ var
->right_margin
+ 1;
523 timing
->hsync_end
= timing
->hsync_start
+ var
->hsync_len
;
524 timing
->vblank_end
= timing
->vtotal
;
525 timing
->vsync_start
= var
->yres
+ var
->lower_margin
+ 1;
526 timing
->vsync_end
= timing
->vsync_start
+ var
->vsync_len
;
532 static void gbe_set_timing_info(struct gbe_timing_info
*timing
)
537 /* setup dot clock PLL */
539 SET_GBE_FIELD(DOTCLK
, M
, val
, timing
->pll_m
- 1);
540 SET_GBE_FIELD(DOTCLK
, N
, val
, timing
->pll_n
- 1);
541 SET_GBE_FIELD(DOTCLK
, P
, val
, timing
->pll_p
);
542 SET_GBE_FIELD(DOTCLK
, RUN
, val
, 0); /* do not start yet */
546 /* setup pixel counter */
548 SET_GBE_FIELD(VT_XYMAX
, MAXX
, val
, timing
->htotal
);
549 SET_GBE_FIELD(VT_XYMAX
, MAXY
, val
, timing
->vtotal
);
552 /* setup video timing signals */
554 SET_GBE_FIELD(VT_VSYNC
, VSYNC_ON
, val
, timing
->vsync_start
);
555 SET_GBE_FIELD(VT_VSYNC
, VSYNC_OFF
, val
, timing
->vsync_end
);
558 SET_GBE_FIELD(VT_HSYNC
, HSYNC_ON
, val
, timing
->hsync_start
);
559 SET_GBE_FIELD(VT_HSYNC
, HSYNC_OFF
, val
, timing
->hsync_end
);
562 SET_GBE_FIELD(VT_VBLANK
, VBLANK_ON
, val
, timing
->vblank_start
);
563 SET_GBE_FIELD(VT_VBLANK
, VBLANK_OFF
, val
, timing
->vblank_end
);
564 gbe
->vt_vblank
= val
;
566 SET_GBE_FIELD(VT_HBLANK
, HBLANK_ON
, val
,
567 timing
->hblank_start
- 5);
568 SET_GBE_FIELD(VT_HBLANK
, HBLANK_OFF
, val
,
569 timing
->hblank_end
- 3);
570 gbe
->vt_hblank
= val
;
572 /* setup internal timing signals */
574 SET_GBE_FIELD(VT_VCMAP
, VCMAP_ON
, val
, timing
->vblank_start
);
575 SET_GBE_FIELD(VT_VCMAP
, VCMAP_OFF
, val
, timing
->vblank_end
);
578 SET_GBE_FIELD(VT_HCMAP
, HCMAP_ON
, val
, timing
->hblank_start
);
579 SET_GBE_FIELD(VT_HCMAP
, HCMAP_OFF
, val
, timing
->hblank_end
);
583 temp
= timing
->vblank_start
- timing
->vblank_end
- 1;
587 if (flat_panel_enabled
)
588 gbefb_setup_flatpanel(timing
);
590 SET_GBE_FIELD(DID_START_XY
, DID_STARTY
, val
, (u32
) temp
);
591 if (timing
->hblank_end
>= 20)
592 SET_GBE_FIELD(DID_START_XY
, DID_STARTX
, val
,
593 timing
->hblank_end
- 20);
595 SET_GBE_FIELD(DID_START_XY
, DID_STARTX
, val
,
596 timing
->htotal
- (20 - timing
->hblank_end
));
597 gbe
->did_start_xy
= val
;
600 SET_GBE_FIELD(CRS_START_XY
, CRS_STARTY
, val
, (u32
) (temp
+ 1));
601 if (timing
->hblank_end
>= GBE_CRS_MAGIC
)
602 SET_GBE_FIELD(CRS_START_XY
, CRS_STARTX
, val
,
603 timing
->hblank_end
- GBE_CRS_MAGIC
);
605 SET_GBE_FIELD(CRS_START_XY
, CRS_STARTX
, val
,
606 timing
->htotal
- (GBE_CRS_MAGIC
-
607 timing
->hblank_end
));
608 gbe
->crs_start_xy
= val
;
611 SET_GBE_FIELD(VC_START_XY
, VC_STARTY
, val
, (u32
) temp
);
612 SET_GBE_FIELD(VC_START_XY
, VC_STARTX
, val
, timing
->hblank_end
- 4);
613 gbe
->vc_start_xy
= val
;
616 temp
= timing
->hblank_end
- GBE_PIXEN_MAGIC_ON
;
618 temp
+= timing
->htotal
; /* allow blank to wrap around */
620 SET_GBE_FIELD(VT_HPIXEN
, HPIXEN_ON
, val
, temp
);
621 SET_GBE_FIELD(VT_HPIXEN
, HPIXEN_OFF
, val
,
622 ((temp
+ timing
->width
-
623 GBE_PIXEN_MAGIC_OFF
) % timing
->htotal
));
624 gbe
->vt_hpixen
= val
;
627 SET_GBE_FIELD(VT_VPIXEN
, VPIXEN_ON
, val
, timing
->vblank_end
);
628 SET_GBE_FIELD(VT_VPIXEN
, VPIXEN_OFF
, val
, timing
->vblank_start
);
629 gbe
->vt_vpixen
= val
;
631 /* turn off sync on green */
633 SET_GBE_FIELD(VT_FLAGS
, SYNC_LOW
, val
, 1);
638 * Set the hardware according to 'par'.
641 static int gbefb_set_par(struct fb_info
*info
)
645 int wholeTilesX
, partTilesX
, maxPixelsPerTileX
;
647 int xpmax
, ypmax
; /* Monitor resolution */
648 int bytesPerPixel
; /* Bytes per pixel */
649 struct gbefb_par
*par
= (struct gbefb_par
*) info
->par
;
651 compute_gbe_timing(&info
->var
, &par
->timing
);
653 bytesPerPixel
= info
->var
.bits_per_pixel
/ 8;
654 info
->fix
.line_length
= info
->var
.xres_virtual
* bytesPerPixel
;
655 xpmax
= par
->timing
.width
;
656 ypmax
= par
->timing
.height
;
661 /* set timing info */
662 gbe_set_timing_info(&par
->timing
);
664 /* initialize DIDs */
666 switch (bytesPerPixel
) {
668 SET_GBE_FIELD(WID
, TYP
, val
, GBE_CMODE_I8
);
669 info
->fix
.visual
= FB_VISUAL_PSEUDOCOLOR
;
672 SET_GBE_FIELD(WID
, TYP
, val
, GBE_CMODE_ARGB5
);
673 info
->fix
.visual
= FB_VISUAL_TRUECOLOR
;
676 SET_GBE_FIELD(WID
, TYP
, val
, GBE_CMODE_RGB8
);
677 info
->fix
.visual
= FB_VISUAL_TRUECOLOR
;
680 SET_GBE_FIELD(WID
, BUF
, val
, GBE_BMODE_BOTH
);
682 for (i
= 0; i
< 32; i
++)
683 gbe
->mode_regs
[i
] = val
;
685 /* Initialize interrupts */
686 gbe
->vt_intr01
= 0xffffffff;
687 gbe
->vt_intr23
= 0xffffffff;
690 The GBE hardware uses a tiled memory to screen mapping. Tiles are
691 blocks of 512x128, 256x128 or 128x128 pixels, respectively for 8bit,
692 16bit and 32 bit modes (64 kB). They cover the screen with partial
693 tiles on the right and/or bottom of the screen if needed.
694 For example in 640x480 8 bit mode the mapping is:
697 <---- 512 ----><128|384 offscreen>
699 | 128 [tile 0] [tile 1]
702 4 128 [tile 2] [tile 3]
705 128 [tile 4] [tile 5]
708 v 96 [tile 6] [tile 7]
711 Tiles have the advantage that they can be allocated individually in
712 memory. However, this mapping is not linear at all, which is not
713 really convenient. In order to support linear addressing, the GBE
714 DMA hardware is fooled into thinking the screen is only one tile
715 large and but has a greater height, so that the DMA transfer covers
717 Tiles are still allocated as independent chunks of 64KB of
718 continuous physical memory and remapped so that the kernel sees the
719 framebuffer as a continuous virtual memory. The GBE tile table is
720 set up so that each tile references one of these 64k blocks:
722 GBE -> tile list framebuffer TLB <------------ CPU
723 [ tile 0 ] -> [ 64KB ] <- [ 16x 4KB page entries ] ^
724 ... ... ... linear virtual FB
725 [ tile n ] -> [ 64KB ] <- [ 16x 4KB page entries ] v
728 The GBE hardware is then told that the buffer is 512*tweaked_height,
729 with tweaked_height = real_width*real_height/pixels_per_tile.
730 Thus the GBE hardware will scan the first tile, filing the first 64k
731 covered region of the screen, and then will proceed to the next
732 tile, until the whole screen is covered.
734 Here is what would happen at 640x480 8bit:
737 ^ 11111111111111112222 11111111111111111111 ^
738 128 11111111111111112222 11111111111111111111 102 lines
739 11111111111111112222 11111111111111111111 v
740 V 11111111111111112222 11111111222222222222
741 33333333333333334444 22222222222222222222
742 33333333333333334444 22222222222222222222
743 < 512 > < 256 > 102*640+256 = 64k
745 NOTE: The only mode for which this is not working is 800x600 8bit,
746 as 800*600/512 = 937.5 which is not integer and thus causes
748 I guess this is not so important as one can use 640x480 8bit or
749 800x600 16bit anyway.
752 /* Tell gbe about the tiles table location */
753 /* tile_ptr -> [ tile 1 ] -> FB mem */
754 /* [ tile 2 ] -> FB mem */
757 SET_GBE_FIELD(FRM_CONTROL
, FRM_TILE_PTR
, val
, gbe_tiles
.dma
>> 9);
758 SET_GBE_FIELD(FRM_CONTROL
, FRM_DMA_ENABLE
, val
, 0); /* do not start */
759 SET_GBE_FIELD(FRM_CONTROL
, FRM_LINEAR
, val
, 0);
760 gbe
->frm_control
= val
;
762 maxPixelsPerTileX
= 512 / bytesPerPixel
;
766 /* Initialize the framebuffer */
768 SET_GBE_FIELD(FRM_SIZE_TILE
, FRM_WIDTH_TILE
, val
, wholeTilesX
);
769 SET_GBE_FIELD(FRM_SIZE_TILE
, FRM_RHS
, val
, partTilesX
);
771 switch (bytesPerPixel
) {
773 SET_GBE_FIELD(FRM_SIZE_TILE
, FRM_DEPTH
, val
,
777 SET_GBE_FIELD(FRM_SIZE_TILE
, FRM_DEPTH
, val
,
781 SET_GBE_FIELD(FRM_SIZE_TILE
, FRM_DEPTH
, val
,
785 gbe
->frm_size_tile
= val
;
787 /* compute tweaked height */
788 height_pix
= xpmax
* ypmax
/ maxPixelsPerTileX
;
791 SET_GBE_FIELD(FRM_SIZE_PIXEL
, FB_HEIGHT_PIX
, val
, height_pix
);
792 gbe
->frm_size_pixel
= val
;
794 /* turn off DID and overlay DMA */
795 gbe
->did_control
= 0;
796 gbe
->ovr_width_tile
= 0;
798 /* Turn off mouse cursor */
804 /* Initialize the gamma map */
806 for (i
= 0; i
< 256; i
++)
807 gbe
->gmap
[i
] = (i
<< 24) | (i
<< 16) | (i
<< 8);
809 /* Initialize the color map */
810 for (i
= 0; i
< 256; i
++)
811 gbe_cmap
[i
] = (i
<< 8) | (i
<< 16) | (i
<< 24);
818 static void gbefb_encode_fix(struct fb_fix_screeninfo
*fix
,
819 struct fb_var_screeninfo
*var
)
821 memset(fix
, 0, sizeof(struct fb_fix_screeninfo
));
822 strcpy(fix
->id
, "SGI GBE");
823 fix
->smem_start
= (unsigned long) gbe_mem
;
824 fix
->smem_len
= gbe_mem_size
;
825 fix
->type
= FB_TYPE_PACKED_PIXELS
;
827 fix
->accel
= FB_ACCEL_NONE
;
828 switch (var
->bits_per_pixel
) {
830 fix
->visual
= FB_VISUAL_PSEUDOCOLOR
;
833 fix
->visual
= FB_VISUAL_TRUECOLOR
;
839 fix
->line_length
= var
->xres_virtual
* var
->bits_per_pixel
/ 8;
840 fix
->mmio_start
= GBE_BASE
;
841 fix
->mmio_len
= sizeof(struct sgi_gbe
);
845 * Set a single color register. The values supplied are already
846 * rounded down to the hardware's capabilities (according to the
847 * entries in the var structure). Return != 0 for invalid regno.
850 static int gbefb_setcolreg(unsigned regno
, unsigned red
, unsigned green
,
851 unsigned blue
, unsigned transp
,
852 struct fb_info
*info
)
862 if (info
->var
.bits_per_pixel
<= 8) {
863 gbe_cmap
[regno
] = (red
<< 24) | (green
<< 16) | (blue
<< 8);
865 /* wait for the color map FIFO to have a free entry */
866 for (i
= 0; i
< 1000 && gbe
->cm_fifo
>= 63; i
++)
869 printk(KERN_ERR
"gbefb: cmap FIFO timeout\n");
872 gbe
->cmap
[regno
] = gbe_cmap
[regno
];
874 } else if (regno
< 16) {
875 switch (info
->var
.bits_per_pixel
) {
881 pseudo_palette
[regno
] =
882 (red
<< info
->var
.red
.offset
) |
883 (green
<< info
->var
.green
.offset
) |
884 (blue
<< info
->var
.blue
.offset
);
887 pseudo_palette
[regno
] =
888 (red
<< info
->var
.red
.offset
) |
889 (green
<< info
->var
.green
.offset
) |
890 (blue
<< info
->var
.blue
.offset
);
899 * Check video mode validity, eventually modify var to best match.
901 static int gbefb_check_var(struct fb_var_screeninfo
*var
, struct fb_info
*info
)
903 unsigned int line_length
;
904 struct gbe_timing_info timing
;
907 /* Limit bpp to 8, 16, and 32 */
908 if (var
->bits_per_pixel
<= 8)
909 var
->bits_per_pixel
= 8;
910 else if (var
->bits_per_pixel
<= 16)
911 var
->bits_per_pixel
= 16;
912 else if (var
->bits_per_pixel
<= 32)
913 var
->bits_per_pixel
= 32;
917 /* Check the mode can be mapped linearly with the tile table trick. */
918 /* This requires width x height x bytes/pixel be a multiple of 512 */
919 if ((var
->xres
* var
->yres
* var
->bits_per_pixel
) & 4095)
922 var
->grayscale
= 0; /* No grayscale for now */
924 ret
= compute_gbe_timing(var
, &timing
);
929 /* Adjust virtual resolution, if necessary */
930 if (var
->xres
> var
->xres_virtual
|| (!ywrap
&& !ypan
))
931 var
->xres_virtual
= var
->xres
;
932 if (var
->yres
> var
->yres_virtual
|| (!ywrap
&& !ypan
))
933 var
->yres_virtual
= var
->yres
;
935 if (var
->vmode
& FB_VMODE_CONUPDATE
) {
936 var
->vmode
|= FB_VMODE_YWRAP
;
937 var
->xoffset
= info
->var
.xoffset
;
938 var
->yoffset
= info
->var
.yoffset
;
941 /* No grayscale for now */
945 line_length
= var
->xres_virtual
* var
->bits_per_pixel
/ 8;
946 if (line_length
* var
->yres_virtual
> gbe_mem_size
)
947 return -ENOMEM
; /* Virtual resolution too high */
949 switch (var
->bits_per_pixel
) {
953 var
->green
.offset
= 0;
954 var
->green
.length
= 8;
955 var
->blue
.offset
= 0;
956 var
->blue
.length
= 8;
957 var
->transp
.offset
= 0;
958 var
->transp
.length
= 0;
960 case 16: /* RGB 1555 */
961 var
->red
.offset
= 10;
963 var
->green
.offset
= 5;
964 var
->green
.length
= 5;
965 var
->blue
.offset
= 0;
966 var
->blue
.length
= 5;
967 var
->transp
.offset
= 0;
968 var
->transp
.length
= 0;
970 case 32: /* RGB 8888 */
971 var
->red
.offset
= 24;
973 var
->green
.offset
= 16;
974 var
->green
.length
= 8;
975 var
->blue
.offset
= 8;
976 var
->blue
.length
= 8;
977 var
->transp
.offset
= 0;
978 var
->transp
.length
= 8;
981 var
->red
.msb_right
= 0;
982 var
->green
.msb_right
= 0;
983 var
->blue
.msb_right
= 0;
984 var
->transp
.msb_right
= 0;
986 var
->left_margin
= timing
.htotal
- timing
.hsync_end
;
987 var
->right_margin
= timing
.hsync_start
- timing
.width
;
988 var
->upper_margin
= timing
.vtotal
- timing
.vsync_end
;
989 var
->lower_margin
= timing
.vsync_start
- timing
.height
;
990 var
->hsync_len
= timing
.hsync_end
- timing
.hsync_start
;
991 var
->vsync_len
= timing
.vsync_end
- timing
.vsync_start
;
996 static int gbefb_mmap(struct fb_info
*info
,
997 struct vm_area_struct
*vma
)
999 unsigned long size
= vma
->vm_end
- vma
->vm_start
;
1000 unsigned long offset
= vma
->vm_pgoff
<< PAGE_SHIFT
;
1002 unsigned long phys_addr
, phys_size
;
1006 if (vma
->vm_pgoff
> (~0UL >> PAGE_SHIFT
))
1008 if (size
> gbe_mem_size
)
1010 if (offset
> gbe_mem_size
- size
)
1013 /* remap using the fastest write-through mode on architecture */
1014 /* try not polluting the cache when possible */
1016 pgprot_val(vma
->vm_page_prot
) =
1017 pgprot_fb(pgprot_val(vma
->vm_page_prot
));
1019 /* VM_IO | VM_DONTEXPAND | VM_DONTDUMP are set by remap_pfn_range() */
1021 /* look for the starting tile */
1022 tile
= &gbe_tiles
.cpu
[offset
>> TILE_SHIFT
];
1023 addr
= vma
->vm_start
;
1024 offset
&= TILE_MASK
;
1026 /* remap each tile separately */
1028 phys_addr
= (((unsigned long) (*tile
)) << TILE_SHIFT
) + offset
;
1029 if ((offset
+ size
) < TILE_SIZE
)
1032 phys_size
= TILE_SIZE
- offset
;
1034 if (remap_pfn_range(vma
, addr
, phys_addr
>> PAGE_SHIFT
,
1035 phys_size
, vma
->vm_page_prot
))
1047 static const struct fb_ops gbefb_ops
= {
1048 .owner
= THIS_MODULE
,
1049 .fb_check_var
= gbefb_check_var
,
1050 .fb_set_par
= gbefb_set_par
,
1051 .fb_setcolreg
= gbefb_setcolreg
,
1052 .fb_mmap
= gbefb_mmap
,
1053 .fb_blank
= gbefb_blank
,
1054 .fb_fillrect
= cfb_fillrect
,
1055 .fb_copyarea
= cfb_copyarea
,
1056 .fb_imageblit
= cfb_imageblit
,
1063 static ssize_t
gbefb_show_memsize(struct device
*dev
, struct device_attribute
*attr
, char *buf
)
1065 return snprintf(buf
, PAGE_SIZE
, "%u\n", gbe_mem_size
);
1068 static DEVICE_ATTR(size
, S_IRUGO
, gbefb_show_memsize
, NULL
);
1070 static ssize_t
gbefb_show_rev(struct device
*device
, struct device_attribute
*attr
, char *buf
)
1072 return snprintf(buf
, PAGE_SIZE
, "%d\n", gbe_revision
);
1075 static DEVICE_ATTR(revision
, S_IRUGO
, gbefb_show_rev
, NULL
);
1077 static void gbefb_remove_sysfs(struct device
*dev
)
1079 device_remove_file(dev
, &dev_attr_size
);
1080 device_remove_file(dev
, &dev_attr_revision
);
1083 static void gbefb_create_sysfs(struct device
*dev
)
1085 device_create_file(dev
, &dev_attr_size
);
1086 device_create_file(dev
, &dev_attr_revision
);
1093 static int gbefb_setup(char *options
)
1097 if (!options
|| !*options
)
1100 while ((this_opt
= strsep(&options
, ",")) != NULL
) {
1101 if (!strncmp(this_opt
, "monitor:", 8)) {
1102 if (!strncmp(this_opt
+ 8, "crt", 3)) {
1103 flat_panel_enabled
= 0;
1104 default_var
= &default_var_CRT
;
1105 default_mode
= &default_mode_CRT
;
1106 } else if (!strncmp(this_opt
+ 8, "1600sw", 6) ||
1107 !strncmp(this_opt
+ 8, "lcd", 3)) {
1108 flat_panel_enabled
= 1;
1109 default_var
= &default_var_LCD
;
1110 default_mode
= &default_mode_LCD
;
1112 } else if (!strncmp(this_opt
, "mem:", 4)) {
1113 gbe_mem_size
= memparse(this_opt
+ 4, &this_opt
);
1114 if (gbe_mem_size
> CONFIG_FB_GBE_MEM
* 1024 * 1024)
1115 gbe_mem_size
= CONFIG_FB_GBE_MEM
* 1024 * 1024;
1116 if (gbe_mem_size
< TILE_SIZE
)
1117 gbe_mem_size
= TILE_SIZE
;
1119 mode_option
= this_opt
;
1124 static int gbefb_probe(struct platform_device
*p_dev
)
1127 struct fb_info
*info
;
1128 struct gbefb_par
*par
;
1130 char *options
= NULL
;
1133 info
= framebuffer_alloc(sizeof(struct gbefb_par
), &p_dev
->dev
);
1138 if (fb_get_options("gbefb", &options
)) {
1140 goto out_release_framebuffer
;
1142 gbefb_setup(options
);
1145 if (!request_mem_region(GBE_BASE
, sizeof(struct sgi_gbe
), "GBE")) {
1146 printk(KERN_ERR
"gbefb: couldn't reserve mmio region\n");
1148 goto out_release_framebuffer
;
1151 gbe
= (struct sgi_gbe
*) devm_ioremap(&p_dev
->dev
, GBE_BASE
,
1152 sizeof(struct sgi_gbe
));
1154 printk(KERN_ERR
"gbefb: couldn't map mmio region\n");
1156 goto out_release_mem_region
;
1158 gbe_revision
= gbe
->ctrlstat
& 15;
1160 gbe_tiles
.cpu
= dmam_alloc_coherent(&p_dev
->dev
,
1161 GBE_TLB_SIZE
* sizeof(uint16_t),
1162 &gbe_tiles
.dma
, GFP_KERNEL
);
1163 if (!gbe_tiles
.cpu
) {
1164 printk(KERN_ERR
"gbefb: couldn't allocate tiles table\n");
1166 goto out_release_mem_region
;
1170 /* memory was allocated at boot time */
1171 gbe_mem
= devm_ioremap_wc(&p_dev
->dev
, gbe_mem_phys
,
1174 printk(KERN_ERR
"gbefb: couldn't map framebuffer\n");
1176 goto out_release_mem_region
;
1181 /* try to allocate memory with the classical allocator
1182 * this has high chance to fail on low memory machines */
1183 gbe_mem
= dmam_alloc_attrs(&p_dev
->dev
, gbe_mem_size
,
1184 &gbe_dma_addr
, GFP_KERNEL
,
1185 DMA_ATTR_WRITE_COMBINE
);
1187 printk(KERN_ERR
"gbefb: couldn't allocate framebuffer memory\n");
1189 goto out_release_mem_region
;
1192 gbe_mem_phys
= (unsigned long) gbe_dma_addr
;
1196 par
->wc_cookie
= arch_phys_wc_add(gbe_mem_phys
, gbe_mem_size
);
1198 /* map framebuffer memory into tiles table */
1199 for (i
= 0; i
< (gbe_mem_size
>> TILE_SHIFT
); i
++)
1200 gbe_tiles
.cpu
[i
] = (gbe_mem_phys
>> TILE_SHIFT
) + i
;
1202 info
->fbops
= &gbefb_ops
;
1203 info
->pseudo_palette
= pseudo_palette
;
1204 info
->flags
= FBINFO_DEFAULT
;
1205 info
->screen_base
= gbe_mem
;
1206 fb_alloc_cmap(&info
->cmap
, 256, 0);
1211 /* turn on default video mode */
1212 if (fb_find_mode(&par
->var
, info
, mode_option
, NULL
, 0,
1213 default_mode
, 8) == 0)
1214 par
->var
= *default_var
;
1215 info
->var
= par
->var
;
1216 gbefb_check_var(&par
->var
, info
);
1217 gbefb_encode_fix(&info
->fix
, &info
->var
);
1219 if (register_framebuffer(info
) < 0) {
1220 printk(KERN_ERR
"gbefb: couldn't register framebuffer\n");
1225 platform_set_drvdata(p_dev
, info
);
1226 gbefb_create_sysfs(&p_dev
->dev
);
1228 fb_info(info
, "%s rev %d @ 0x%08x using %dkB memory\n",
1229 info
->fix
.id
, gbe_revision
, (unsigned)GBE_BASE
,
1230 gbe_mem_size
>> 10);
1235 arch_phys_wc_del(par
->wc_cookie
);
1236 out_release_mem_region
:
1237 release_mem_region(GBE_BASE
, sizeof(struct sgi_gbe
));
1238 out_release_framebuffer
:
1239 framebuffer_release(info
);
1244 static int gbefb_remove(struct platform_device
* p_dev
)
1246 struct fb_info
*info
= platform_get_drvdata(p_dev
);
1247 struct gbefb_par
*par
= info
->par
;
1249 unregister_framebuffer(info
);
1251 arch_phys_wc_del(par
->wc_cookie
);
1252 release_mem_region(GBE_BASE
, sizeof(struct sgi_gbe
));
1253 gbefb_remove_sysfs(&p_dev
->dev
);
1254 framebuffer_release(info
);
1259 static struct platform_driver gbefb_driver
= {
1260 .probe
= gbefb_probe
,
1261 .remove
= gbefb_remove
,
1267 static struct platform_device
*gbefb_device
;
1269 static int __init
gbefb_init(void)
1271 int ret
= platform_driver_register(&gbefb_driver
);
1273 gbefb_device
= platform_device_alloc("gbefb", 0);
1275 ret
= platform_device_add(gbefb_device
);
1280 platform_device_put(gbefb_device
);
1281 platform_driver_unregister(&gbefb_driver
);
1287 static void __exit
gbefb_exit(void)
1289 platform_device_unregister(gbefb_device
);
1290 platform_driver_unregister(&gbefb_driver
);
1293 module_init(gbefb_init
);
1294 module_exit(gbefb_exit
);
1296 MODULE_LICENSE("GPL");