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>
17 #include <linux/init.h>
18 #include <linux/interrupt.h>
19 #include <linux/kernel.h>
21 #include <linux/module.h>
27 #include <asm/addrspace.h>
29 #include <asm/byteorder.h>
31 #include <asm/tlbflush.h>
33 #include <video/gbe.h>
35 static struct sgi_gbe *gbe;
38 struct fb_var_screeninfo var;
39 struct gbe_timing_info timing;
43 #ifdef CONFIG_SGI_IP32
44 #define GBE_BASE 0x16000000 /* SGI O2 */
47 #ifdef CONFIG_X86_VISWS
48 #define GBE_BASE 0xd0000000 /* SGI Visual Workstation */
51 /* macro for fastest write-though access to the framebuffer */
53 #ifdef CONFIG_CPU_R10000
54 #define pgprot_fb(_prot) (((_prot) & (~_CACHE_MASK)) | _CACHE_UNCACHED_ACCELERATED)
56 #define pgprot_fb(_prot) (((_prot) & (~_CACHE_MASK)) | _CACHE_CACHABLE_NO_WA)
60 #define pgprot_fb(_prot) ((_prot) | _PAGE_PCD)
64 * RAM we reserve for the frame buffer. This defines the maximum screen
67 #if CONFIG_FB_GBE_MEM > 8
68 #error GBE Framebuffer cannot use more than 8MB of memory
72 #define TILE_SIZE (1 << TILE_SHIFT)
73 #define TILE_MASK (TILE_SIZE - 1)
75 static unsigned int gbe_mem_size = CONFIG_FB_GBE_MEM * 1024*1024;
77 static dma_addr_t gbe_dma_addr;
78 static unsigned long gbe_mem_phys;
85 static int gbe_revision;
87 static int ypan, ywrap;
89 static uint32_t pseudo_palette[16];
90 static uint32_t gbe_cmap[256];
91 static int gbe_turned_on; /* 0 turned off, 1 turned on */
93 static char *mode_option __initdata = NULL;
95 /* default CRT mode */
96 static struct fb_var_screeninfo default_var_CRT __initdata = {
97 /* 640x480, 60 Hz, Non-Interlaced (25.175 MHz dotclock) */
107 .green = { 0, 8, 0 },
109 .transp = { 0, 0, 0 },
115 .pixclock = 39722, /* picoseconds */
123 .vmode = FB_VMODE_NONINTERLACED,
126 /* default LCD mode */
127 static struct fb_var_screeninfo default_var_LCD __initdata = {
128 /* 1600x1024, 8 bpp */
131 .xres_virtual = 1600,
132 .yres_virtual = 1024,
138 .green = { 0, 8, 0 },
140 .transp = { 0, 0, 0 },
154 .vmode = FB_VMODE_NONINTERLACED
157 /* default modedb mode */
158 /* 640x480, 60 Hz, Non-Interlaced (25.172 MHz dotclock) */
159 static struct fb_videomode default_mode_CRT __initdata = {
171 .vmode = FB_VMODE_NONINTERLACED,
173 /* 1600x1024 SGI flatpanel 1600sw */
174 static struct fb_videomode default_mode_LCD __initdata = {
175 /* 1600x1024, 8 bpp */
185 .vmode = FB_VMODE_NONINTERLACED,
188 static struct fb_videomode *default_mode __initdata = &default_mode_CRT;
189 static struct fb_var_screeninfo *default_var __initdata = &default_var_CRT;
191 static int flat_panel_enabled = 0;
193 static void gbe_reset(void)
195 /* Turn on dotclock PLL */
196 gbe->ctrlstat = 0x300aa000;
201 * Function: gbe_turn_off
203 * Description: This should turn off the monitor and gbe. This is used
204 * when switching between the serial console and the graphics
208 static void gbe_turn_off(void)
211 unsigned int val, x, y, vpixen_off;
215 /* check if pixel counter is on */
217 if (GET_GBE_FIELD(VT_XY, FREEZE, val) == 1)
221 val = gbe->ovr_control;
222 SET_GBE_FIELD(OVR_CONTROL, OVR_DMA_ENABLE, val, 0);
223 gbe->ovr_control = val;
225 val = gbe->frm_control;
226 SET_GBE_FIELD(FRM_CONTROL, FRM_DMA_ENABLE, val, 0);
227 gbe->frm_control = val;
229 val = gbe->did_control;
230 SET_GBE_FIELD(DID_CONTROL, DID_DMA_ENABLE, val, 0);
231 gbe->did_control = val;
234 /* We have to wait through two vertical retrace periods before
235 * the pixel DMA is turned off for sure. */
236 for (i = 0; i < 10000; i++) {
237 val = gbe->frm_inhwctrl;
238 if (GET_GBE_FIELD(FRM_INHWCTRL, FRM_DMA_ENABLE, val)) {
241 val = gbe->ovr_inhwctrl;
242 if (GET_GBE_FIELD(OVR_INHWCTRL, OVR_DMA_ENABLE, val)) {
245 val = gbe->did_inhwctrl;
246 if (GET_GBE_FIELD(DID_INHWCTRL, DID_DMA_ENABLE, val)) {
254 printk(KERN_ERR "gbefb: turn off DMA timed out\n");
256 /* wait for vpixen_off */
257 val = gbe->vt_vpixen;
258 vpixen_off = GET_GBE_FIELD(VT_VPIXEN, VPIXEN_OFF, val);
260 for (i = 0; i < 100000; i++) {
262 x = GET_GBE_FIELD(VT_XY, X, val);
263 y = GET_GBE_FIELD(VT_XY, Y, val);
270 "gbefb: wait for vpixen_off timed out\n");
271 for (i = 0; i < 10000; i++) {
273 x = GET_GBE_FIELD(VT_XY, X, val);
274 y = GET_GBE_FIELD(VT_XY, Y, val);
280 printk(KERN_ERR "gbefb: wait for vpixen_off timed out\n");
282 /* turn off pixel counter */
284 SET_GBE_FIELD(VT_XY, FREEZE, val, 1);
287 for (i = 0; i < 10000; i++) {
289 if (GET_GBE_FIELD(VT_XY, FREEZE, val) != 1)
295 printk(KERN_ERR "gbefb: turn off pixel clock timed out\n");
297 /* turn off dot clock */
299 SET_GBE_FIELD(DOTCLK, RUN, val, 0);
302 for (i = 0; i < 10000; i++) {
304 if (GET_GBE_FIELD(DOTCLK, RUN, val))
310 printk(KERN_ERR "gbefb: turn off dotclock timed out\n");
312 /* reset the frame DMA FIFO */
313 val = gbe->frm_size_tile;
314 SET_GBE_FIELD(FRM_SIZE_TILE, FRM_FIFO_RESET, val, 1);
315 gbe->frm_size_tile = val;
316 SET_GBE_FIELD(FRM_SIZE_TILE, FRM_FIFO_RESET, val, 0);
317 gbe->frm_size_tile = val;
320 static void gbe_turn_on(void)
325 * Check if pixel counter is off, for unknown reason this
326 * code hangs Visual Workstations
328 if (gbe_revision < 2) {
330 if (GET_GBE_FIELD(VT_XY, FREEZE, val) == 0)
334 /* turn on dot clock */
336 SET_GBE_FIELD(DOTCLK, RUN, val, 1);
339 for (i = 0; i < 10000; i++) {
341 if (GET_GBE_FIELD(DOTCLK, RUN, val) != 1)
347 printk(KERN_ERR "gbefb: turn on dotclock timed out\n");
349 /* turn on pixel counter */
351 SET_GBE_FIELD(VT_XY, FREEZE, val, 0);
354 for (i = 0; i < 10000; i++) {
356 if (GET_GBE_FIELD(VT_XY, FREEZE, val))
362 printk(KERN_ERR "gbefb: turn on pixel clock timed out\n");
365 val = gbe->frm_control;
366 SET_GBE_FIELD(FRM_CONTROL, FRM_DMA_ENABLE, val, 1);
367 gbe->frm_control = val;
369 for (i = 0; i < 10000; i++) {
370 val = gbe->frm_inhwctrl;
371 if (GET_GBE_FIELD(FRM_INHWCTRL, FRM_DMA_ENABLE, val) != 1)
377 printk(KERN_ERR "gbefb: turn on DMA timed out\n");
382 static void gbe_loadcmap(void)
386 for (i = 0; i < 256; i++) {
387 for (j = 0; j < 1000 && gbe->cm_fifo >= 63; j++)
390 printk(KERN_ERR "gbefb: cmap FIFO timeout\n");
392 gbe->cmap[i] = gbe_cmap[i];
399 static int gbefb_blank(int blank, struct fb_info *info)
401 /* 0 unblank, 1 blank, 2 no vsync, 3 no hsync, 4 off */
403 case FB_BLANK_UNBLANK: /* unblank */
408 case FB_BLANK_NORMAL: /* blank */
420 * Setup flatpanel related registers.
422 static void gbefb_setup_flatpanel(struct gbe_timing_info *timing)
424 int fp_wid, fp_hgt, fp_vbs, fp_vbe;
427 SET_GBE_FIELD(VT_FLAGS, HDRV_INVERT, outputVal,
428 (timing->flags & FB_SYNC_HOR_HIGH_ACT) ? 0 : 1);
429 SET_GBE_FIELD(VT_FLAGS, VDRV_INVERT, outputVal,
430 (timing->flags & FB_SYNC_VERT_HIGH_ACT) ? 0 : 1);
431 gbe->vt_flags = outputVal;
433 /* Turn on the flat panel */
443 SET_GBE_FIELD(FP_DE, ON, outputVal, fp_vbs);
444 SET_GBE_FIELD(FP_DE, OFF, outputVal, fp_vbe);
445 gbe->fp_de = outputVal;
447 SET_GBE_FIELD(FP_HDRV, OFF, outputVal, fp_wid);
448 gbe->fp_hdrv = outputVal;
450 SET_GBE_FIELD(FP_VDRV, ON, outputVal, 1);
451 SET_GBE_FIELD(FP_VDRV, OFF, outputVal, fp_hgt + 1);
452 gbe->fp_vdrv = outputVal;
455 struct gbe_pll_info {
461 static struct gbe_pll_info gbe_pll_table[2] = {
466 static int compute_gbe_timing(struct fb_var_screeninfo *var,
467 struct gbe_timing_info *timing)
469 int pll_m, pll_n, pll_p, error, best_m, best_n, best_p, best_error;
471 struct gbe_pll_info *gbe_pll;
473 if (gbe_revision < 2)
474 gbe_pll = &gbe_pll_table[0];
476 gbe_pll = &gbe_pll_table[1];
478 /* Determine valid resolution and timing
479 * GBE crystal runs at 20Mhz or 27Mhz
480 * pll_m, pll_n, pll_p define the following frequencies
481 * fvco = pll_m * 20Mhz / pll_n
482 * fout = fvco / (2**pll_p) */
483 best_error = 1000000000;
484 best_n = best_m = best_p = 0;
485 for (pll_p = 0; pll_p < 4; pll_p++)
486 for (pll_m = 1; pll_m < 256; pll_m++)
487 for (pll_n = 1; pll_n < 64; pll_n++) {
488 pixclock = (1000000 / gbe_pll->clock_rate) *
489 (pll_n << pll_p) / pll_m;
491 error = var->pixclock - pixclock;
496 if (error < best_error &&
498 gbe_pll->fvco_min / gbe_pll->clock_rate &&
500 gbe_pll->fvco_max / gbe_pll->clock_rate) {
508 if (!best_n || !best_m)
509 return -EINVAL; /* Resolution to high */
511 pixclock = (1000000 / gbe_pll->clock_rate) *
512 (best_n << best_p) / best_m;
514 /* set video timing information */
516 timing->width = var->xres;
517 timing->height = var->yres;
518 timing->pll_m = best_m;
519 timing->pll_n = best_n;
520 timing->pll_p = best_p;
521 timing->cfreq = gbe_pll->clock_rate * 1000 * timing->pll_m /
522 (timing->pll_n << timing->pll_p);
523 timing->htotal = var->left_margin + var->xres +
524 var->right_margin + var->hsync_len;
525 timing->vtotal = var->upper_margin + var->yres +
526 var->lower_margin + var->vsync_len;
527 timing->fields_sec = 1000 * timing->cfreq / timing->htotal *
528 1000 / timing->vtotal;
529 timing->hblank_start = var->xres;
530 timing->vblank_start = var->yres;
531 timing->hblank_end = timing->htotal;
532 timing->hsync_start = var->xres + var->right_margin + 1;
533 timing->hsync_end = timing->hsync_start + var->hsync_len;
534 timing->vblank_end = timing->vtotal;
535 timing->vsync_start = var->yres + var->lower_margin + 1;
536 timing->vsync_end = timing->vsync_start + var->vsync_len;
542 static void gbe_set_timing_info(struct gbe_timing_info *timing)
547 /* setup dot clock PLL */
549 SET_GBE_FIELD(DOTCLK, M, val, timing->pll_m - 1);
550 SET_GBE_FIELD(DOTCLK, N, val, timing->pll_n - 1);
551 SET_GBE_FIELD(DOTCLK, P, val, timing->pll_p);
552 SET_GBE_FIELD(DOTCLK, RUN, val, 0); /* do not start yet */
556 /* setup pixel counter */
558 SET_GBE_FIELD(VT_XYMAX, MAXX, val, timing->htotal);
559 SET_GBE_FIELD(VT_XYMAX, MAXY, val, timing->vtotal);
562 /* setup video timing signals */
564 SET_GBE_FIELD(VT_VSYNC, VSYNC_ON, val, timing->vsync_start);
565 SET_GBE_FIELD(VT_VSYNC, VSYNC_OFF, val, timing->vsync_end);
568 SET_GBE_FIELD(VT_HSYNC, HSYNC_ON, val, timing->hsync_start);
569 SET_GBE_FIELD(VT_HSYNC, HSYNC_OFF, val, timing->hsync_end);
572 SET_GBE_FIELD(VT_VBLANK, VBLANK_ON, val, timing->vblank_start);
573 SET_GBE_FIELD(VT_VBLANK, VBLANK_OFF, val, timing->vblank_end);
574 gbe->vt_vblank = val;
576 SET_GBE_FIELD(VT_HBLANK, HBLANK_ON, val,
577 timing->hblank_start - 5);
578 SET_GBE_FIELD(VT_HBLANK, HBLANK_OFF, val,
579 timing->hblank_end - 3);
580 gbe->vt_hblank = val;
582 /* setup internal timing signals */
584 SET_GBE_FIELD(VT_VCMAP, VCMAP_ON, val, timing->vblank_start);
585 SET_GBE_FIELD(VT_VCMAP, VCMAP_OFF, val, timing->vblank_end);
588 SET_GBE_FIELD(VT_HCMAP, HCMAP_ON, val, timing->hblank_start);
589 SET_GBE_FIELD(VT_HCMAP, HCMAP_OFF, val, timing->hblank_end);
593 temp = timing->vblank_start - timing->vblank_end - 1;
597 if (flat_panel_enabled)
598 gbefb_setup_flatpanel(timing);
600 SET_GBE_FIELD(DID_START_XY, DID_STARTY, val, (u32) temp);
601 if (timing->hblank_end >= 20)
602 SET_GBE_FIELD(DID_START_XY, DID_STARTX, val,
603 timing->hblank_end - 20);
605 SET_GBE_FIELD(DID_START_XY, DID_STARTX, val,
606 timing->htotal - (20 - timing->hblank_end));
607 gbe->did_start_xy = val;
610 SET_GBE_FIELD(CRS_START_XY, CRS_STARTY, val, (u32) (temp + 1));
611 if (timing->hblank_end >= GBE_CRS_MAGIC)
612 SET_GBE_FIELD(CRS_START_XY, CRS_STARTX, val,
613 timing->hblank_end - GBE_CRS_MAGIC);
615 SET_GBE_FIELD(CRS_START_XY, CRS_STARTX, val,
616 timing->htotal - (GBE_CRS_MAGIC -
617 timing->hblank_end));
618 gbe->crs_start_xy = val;
621 SET_GBE_FIELD(VC_START_XY, VC_STARTY, val, (u32) temp);
622 SET_GBE_FIELD(VC_START_XY, VC_STARTX, val, timing->hblank_end - 4);
623 gbe->vc_start_xy = val;
626 temp = timing->hblank_end - GBE_PIXEN_MAGIC_ON;
628 temp += timing->htotal; /* allow blank to wrap around */
630 SET_GBE_FIELD(VT_HPIXEN, HPIXEN_ON, val, temp);
631 SET_GBE_FIELD(VT_HPIXEN, HPIXEN_OFF, val,
632 ((temp + timing->width -
633 GBE_PIXEN_MAGIC_OFF) % timing->htotal));
634 gbe->vt_hpixen = val;
637 SET_GBE_FIELD(VT_VPIXEN, VPIXEN_ON, val, timing->vblank_end);
638 SET_GBE_FIELD(VT_VPIXEN, VPIXEN_OFF, val, timing->vblank_start);
639 gbe->vt_vpixen = val;
641 /* turn off sync on green */
643 SET_GBE_FIELD(VT_FLAGS, SYNC_LOW, val, 1);
648 * Set the hardware according to 'par'.
651 static int gbefb_set_par(struct fb_info *info)
655 int wholeTilesX, partTilesX, maxPixelsPerTileX;
657 int xpmax, ypmax; /* Monitor resolution */
658 int bytesPerPixel; /* Bytes per pixel */
659 struct gbefb_par *par = (struct gbefb_par *) info->par;
661 compute_gbe_timing(&info->var, &par->timing);
663 bytesPerPixel = info->var.bits_per_pixel / 8;
664 info->fix.line_length = info->var.xres_virtual * bytesPerPixel;
665 xpmax = par->timing.width;
666 ypmax = par->timing.height;
671 /* set timing info */
672 gbe_set_timing_info(&par->timing);
674 /* initialize DIDs */
676 switch (bytesPerPixel) {
678 SET_GBE_FIELD(WID, TYP, val, GBE_CMODE_I8);
679 info->fix.visual = FB_VISUAL_PSEUDOCOLOR;
682 SET_GBE_FIELD(WID, TYP, val, GBE_CMODE_ARGB5);
683 info->fix.visual = FB_VISUAL_TRUECOLOR;
686 SET_GBE_FIELD(WID, TYP, val, GBE_CMODE_RGB8);
687 info->fix.visual = FB_VISUAL_TRUECOLOR;
690 SET_GBE_FIELD(WID, BUF, val, GBE_BMODE_BOTH);
692 for (i = 0; i < 32; i++)
693 gbe->mode_regs[i] = val;
695 /* Initialize interrupts */
696 gbe->vt_intr01 = 0xffffffff;
697 gbe->vt_intr23 = 0xffffffff;
700 The GBE hardware uses a tiled memory to screen mapping. Tiles are
701 blocks of 512x128, 256x128 or 128x128 pixels, respectively for 8bit,
702 16bit and 32 bit modes (64 kB). They cover the screen with partial
703 tiles on the right and/or bottom of the screen if needed.
704 For exemple in 640x480 8 bit mode the mapping is:
707 <---- 512 ----><128|384 offscreen>
709 | 128 [tile 0] [tile 1]
712 4 128 [tile 2] [tile 3]
715 128 [tile 4] [tile 5]
718 v 96 [tile 6] [tile 7]
721 Tiles have the advantage that they can be allocated individually in
722 memory. However, this mapping is not linear at all, which is not
723 really convienient. In order to support linear addressing, the GBE
724 DMA hardware is fooled into thinking the screen is only one tile
725 large and but has a greater height, so that the DMA transfer covers
727 Tiles are still allocated as independent chunks of 64KB of
728 continuous physical memory and remapped so that the kernel sees the
729 framebuffer as a continuous virtual memory. The GBE tile table is
730 set up so that each tile references one of these 64k blocks:
732 GBE -> tile list framebuffer TLB <------------ CPU
733 [ tile 0 ] -> [ 64KB ] <- [ 16x 4KB page entries ] ^
734 ... ... ... linear virtual FB
735 [ tile n ] -> [ 64KB ] <- [ 16x 4KB page entries ] v
738 The GBE hardware is then told that the buffer is 512*tweaked_height,
739 with tweaked_height = real_width*real_height/pixels_per_tile.
740 Thus the GBE hardware will scan the first tile, filing the first 64k
741 covered region of the screen, and then will proceed to the next
742 tile, until the whole screen is covered.
744 Here is what would happen at 640x480 8bit:
747 ^ 11111111111111112222 11111111111111111111 ^
748 128 11111111111111112222 11111111111111111111 102 lines
749 11111111111111112222 11111111111111111111 v
750 V 11111111111111112222 11111111222222222222
751 33333333333333334444 22222222222222222222
752 33333333333333334444 22222222222222222222
753 < 512 > < 256 > 102*640+256 = 64k
755 NOTE: The only mode for which this is not working is 800x600 8bit,
756 as 800*600/512 = 937.5 which is not integer and thus causes
758 I guess this is not so important as one can use 640x480 8bit or
759 800x600 16bit anyway.
762 /* Tell gbe about the tiles table location */
763 /* tile_ptr -> [ tile 1 ] -> FB mem */
764 /* [ tile 2 ] -> FB mem */
767 SET_GBE_FIELD(FRM_CONTROL, FRM_TILE_PTR, val, gbe_tiles.dma >> 9);
768 SET_GBE_FIELD(FRM_CONTROL, FRM_DMA_ENABLE, val, 0); /* do not start */
769 SET_GBE_FIELD(FRM_CONTROL, FRM_LINEAR, val, 0);
770 gbe->frm_control = val;
772 maxPixelsPerTileX = 512 / bytesPerPixel;
776 /* Initialize the framebuffer */
778 SET_GBE_FIELD(FRM_SIZE_TILE, FRM_WIDTH_TILE, val, wholeTilesX);
779 SET_GBE_FIELD(FRM_SIZE_TILE, FRM_RHS, val, partTilesX);
781 switch (bytesPerPixel) {
783 SET_GBE_FIELD(FRM_SIZE_TILE, FRM_DEPTH, val,
787 SET_GBE_FIELD(FRM_SIZE_TILE, FRM_DEPTH, val,
791 SET_GBE_FIELD(FRM_SIZE_TILE, FRM_DEPTH, val,
795 gbe->frm_size_tile = val;
797 /* compute tweaked height */
798 height_pix = xpmax * ypmax / maxPixelsPerTileX;
801 SET_GBE_FIELD(FRM_SIZE_PIXEL, FB_HEIGHT_PIX, val, height_pix);
802 gbe->frm_size_pixel = val;
804 /* turn off DID and overlay DMA */
805 gbe->did_control = 0;
806 gbe->ovr_width_tile = 0;
808 /* Turn off mouse cursor */
814 /* Initialize the gamma map */
816 for (i = 0; i < 256; i++)
817 gbe->gmap[i] = (i << 24) | (i << 16) | (i << 8);
819 /* Initialize the color map */
820 for (i = 0; i < 256; i++)
821 gbe_cmap[i] = (i << 8) | (i << 16) | (i << 24);
828 static void gbefb_encode_fix(struct fb_fix_screeninfo *fix,
829 struct fb_var_screeninfo *var)
831 memset(fix, 0, sizeof(struct fb_fix_screeninfo));
832 strcpy(fix->id, "SGI GBE");
833 fix->smem_start = (unsigned long) gbe_mem;
834 fix->smem_len = gbe_mem_size;
835 fix->type = FB_TYPE_PACKED_PIXELS;
837 fix->accel = FB_ACCEL_NONE;
838 switch (var->bits_per_pixel) {
840 fix->visual = FB_VISUAL_PSEUDOCOLOR;
843 fix->visual = FB_VISUAL_TRUECOLOR;
849 fix->line_length = var->xres_virtual * var->bits_per_pixel / 8;
850 fix->mmio_start = GBE_BASE;
851 fix->mmio_len = sizeof(struct sgi_gbe);
855 * Set a single color register. The values supplied are already
856 * rounded down to the hardware's capabilities (according to the
857 * entries in the var structure). Return != 0 for invalid regno.
860 static int gbefb_setcolreg(unsigned regno, unsigned red, unsigned green,
861 unsigned blue, unsigned transp,
862 struct fb_info *info)
872 if (info->var.bits_per_pixel <= 8) {
873 gbe_cmap[regno] = (red << 24) | (green << 16) | (blue << 8);
875 /* wait for the color map FIFO to have a free entry */
876 for (i = 0; i < 1000 && gbe->cm_fifo >= 63; i++)
879 printk(KERN_ERR "gbefb: cmap FIFO timeout\n");
882 gbe->cmap[regno] = gbe_cmap[regno];
884 } else if (regno < 16) {
885 switch (info->var.bits_per_pixel) {
891 pseudo_palette[regno] =
892 (red << info->var.red.offset) |
893 (green << info->var.green.offset) |
894 (blue << info->var.blue.offset);
897 pseudo_palette[regno] =
898 (red << info->var.red.offset) |
899 (green << info->var.green.offset) |
900 (blue << info->var.blue.offset);
909 * Check video mode validity, eventually modify var to best match.
911 static int gbefb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
913 unsigned int line_length;
914 struct gbe_timing_info timing;
917 /* Limit bpp to 8, 16, and 32 */
918 if (var->bits_per_pixel <= 8)
919 var->bits_per_pixel = 8;
920 else if (var->bits_per_pixel <= 16)
921 var->bits_per_pixel = 16;
922 else if (var->bits_per_pixel <= 32)
923 var->bits_per_pixel = 32;
927 /* Check the mode can be mapped linearly with the tile table trick. */
928 /* This requires width x height x bytes/pixel be a multiple of 512 */
929 if ((var->xres * var->yres * var->bits_per_pixel) & 4095)
932 var->grayscale = 0; /* No grayscale for now */
934 ret = compute_gbe_timing(var, &timing);
939 /* Adjust virtual resolution, if necessary */
940 if (var->xres > var->xres_virtual || (!ywrap && !ypan))
941 var->xres_virtual = var->xres;
942 if (var->yres > var->yres_virtual || (!ywrap && !ypan))
943 var->yres_virtual = var->yres;
945 if (var->vmode & FB_VMODE_CONUPDATE) {
946 var->vmode |= FB_VMODE_YWRAP;
947 var->xoffset = info->var.xoffset;
948 var->yoffset = info->var.yoffset;
951 /* No grayscale for now */
955 line_length = var->xres_virtual * var->bits_per_pixel / 8;
956 if (line_length * var->yres_virtual > gbe_mem_size)
957 return -ENOMEM; /* Virtual resolution too high */
959 switch (var->bits_per_pixel) {
963 var->green.offset = 0;
964 var->green.length = 8;
965 var->blue.offset = 0;
966 var->blue.length = 8;
967 var->transp.offset = 0;
968 var->transp.length = 0;
970 case 16: /* RGB 1555 */
971 var->red.offset = 10;
973 var->green.offset = 5;
974 var->green.length = 5;
975 var->blue.offset = 0;
976 var->blue.length = 5;
977 var->transp.offset = 0;
978 var->transp.length = 0;
980 case 32: /* RGB 8888 */
981 var->red.offset = 24;
983 var->green.offset = 16;
984 var->green.length = 8;
985 var->blue.offset = 8;
986 var->blue.length = 8;
987 var->transp.offset = 0;
988 var->transp.length = 8;
991 var->red.msb_right = 0;
992 var->green.msb_right = 0;
993 var->blue.msb_right = 0;
994 var->transp.msb_right = 0;
996 var->left_margin = timing.htotal - timing.hsync_end;
997 var->right_margin = timing.hsync_start - timing.width;
998 var->upper_margin = timing.vtotal - timing.vsync_end;
999 var->lower_margin = timing.vsync_start - timing.height;
1000 var->hsync_len = timing.hsync_end - timing.hsync_start;
1001 var->vsync_len = timing.vsync_end - timing.vsync_start;
1006 static int gbefb_mmap(struct fb_info *info,
1007 struct vm_area_struct *vma)
1009 unsigned long size = vma->vm_end - vma->vm_start;
1010 unsigned long offset = vma->vm_pgoff << PAGE_SHIFT;
1012 unsigned long phys_addr, phys_size;
1016 if (vma->vm_pgoff > (~0UL >> PAGE_SHIFT))
1018 if (offset + size > gbe_mem_size)
1021 /* remap using the fastest write-through mode on architecture */
1022 /* try not polluting the cache when possible */
1023 pgprot_val(vma->vm_page_prot) =
1024 pgprot_fb(pgprot_val(vma->vm_page_prot));
1026 vma->vm_flags |= VM_IO | VM_RESERVED;
1028 /* look for the starting tile */
1029 tile = &gbe_tiles.cpu[offset >> TILE_SHIFT];
1030 addr = vma->vm_start;
1031 offset &= TILE_MASK;
1033 /* remap each tile separately */
1035 phys_addr = (((unsigned long) (*tile)) << TILE_SHIFT) + offset;
1036 if ((offset + size) < TILE_SIZE)
1039 phys_size = TILE_SIZE - offset;
1041 if (remap_pfn_range(vma, addr, phys_addr >> PAGE_SHIFT,
1042 phys_size, vma->vm_page_prot))
1054 static struct fb_ops gbefb_ops = {
1055 .owner = THIS_MODULE,
1056 .fb_check_var = gbefb_check_var,
1057 .fb_set_par = gbefb_set_par,
1058 .fb_setcolreg = gbefb_setcolreg,
1059 .fb_mmap = gbefb_mmap,
1060 .fb_blank = gbefb_blank,
1061 .fb_fillrect = cfb_fillrect,
1062 .fb_copyarea = cfb_copyarea,
1063 .fb_imageblit = cfb_imageblit,
1070 static ssize_t gbefb_show_memsize(struct device *dev, struct device_attribute *attr, char *buf)
1072 return snprintf(buf, PAGE_SIZE, "%d\n", gbe_mem_size);
1075 static DEVICE_ATTR(size, S_IRUGO, gbefb_show_memsize, NULL);
1077 static ssize_t gbefb_show_rev(struct device *device, struct device_attribute *attr, char *buf)
1079 return snprintf(buf, PAGE_SIZE, "%d\n", gbe_revision);
1082 static DEVICE_ATTR(revision, S_IRUGO, gbefb_show_rev, NULL);
1084 static void __devexit gbefb_remove_sysfs(struct device *dev)
1086 device_remove_file(dev, &dev_attr_size);
1087 device_remove_file(dev, &dev_attr_revision);
1090 static void gbefb_create_sysfs(struct device *dev)
1092 device_create_file(dev, &dev_attr_size);
1093 device_create_file(dev, &dev_attr_revision);
1100 static int __init gbefb_setup(char *options)
1104 if (!options || !*options)
1107 while ((this_opt = strsep(&options, ",")) != NULL) {
1108 if (!strncmp(this_opt, "monitor:", 8)) {
1109 if (!strncmp(this_opt + 8, "crt", 3)) {
1110 flat_panel_enabled = 0;
1111 default_var = &default_var_CRT;
1112 default_mode = &default_mode_CRT;
1113 } else if (!strncmp(this_opt + 8, "1600sw", 6) ||
1114 !strncmp(this_opt + 8, "lcd", 3)) {
1115 flat_panel_enabled = 1;
1116 default_var = &default_var_LCD;
1117 default_mode = &default_mode_LCD;
1119 } else if (!strncmp(this_opt, "mem:", 4)) {
1120 gbe_mem_size = memparse(this_opt + 4, &this_opt);
1121 if (gbe_mem_size > CONFIG_FB_GBE_MEM * 1024 * 1024)
1122 gbe_mem_size = CONFIG_FB_GBE_MEM * 1024 * 1024;
1123 if (gbe_mem_size < TILE_SIZE)
1124 gbe_mem_size = TILE_SIZE;
1126 mode_option = this_opt;
1131 static int __init gbefb_probe(struct platform_device *p_dev)
1134 struct fb_info *info;
1135 struct gbefb_par *par;
1137 char *options = NULL;
1140 info = framebuffer_alloc(sizeof(struct gbefb_par), &p_dev->dev);
1145 if (fb_get_options("gbefb", &options))
1147 gbefb_setup(options);
1150 if (!request_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 *) ioremap(GBE_BASE, sizeof(struct sgi_gbe));
1158 printk(KERN_ERR "gbefb: couldn't map mmio region\n");
1160 goto out_release_mem_region;
1162 gbe_revision = gbe->ctrlstat & 15;
1165 dma_alloc_coherent(NULL, GBE_TLB_SIZE * sizeof(uint16_t),
1166 &gbe_tiles.dma, GFP_KERNEL);
1167 if (!gbe_tiles.cpu) {
1168 printk(KERN_ERR "gbefb: couldn't allocate tiles table\n");
1174 /* memory was allocated at boot time */
1175 gbe_mem = ioremap_nocache(gbe_mem_phys, gbe_mem_size);
1177 printk(KERN_ERR "gbefb: couldn't map framebuffer\n");
1179 goto out_tiles_free;
1184 /* try to allocate memory with the classical allocator
1185 * this has high chance to fail on low memory machines */
1186 gbe_mem = dma_alloc_coherent(NULL, gbe_mem_size, &gbe_dma_addr,
1189 printk(KERN_ERR "gbefb: couldn't allocate framebuffer memory\n");
1191 goto out_tiles_free;
1194 gbe_mem_phys = (unsigned long) gbe_dma_addr;
1198 mtrr_add(gbe_mem_phys, gbe_mem_size, MTRR_TYPE_WRCOMB, 1);
1201 /* map framebuffer memory into tiles table */
1202 for (i = 0; i < (gbe_mem_size >> TILE_SHIFT); i++)
1203 gbe_tiles.cpu[i] = (gbe_mem_phys >> TILE_SHIFT) + i;
1205 info->fbops = &gbefb_ops;
1206 info->pseudo_palette = pseudo_palette;
1207 info->flags = FBINFO_DEFAULT;
1208 info->screen_base = gbe_mem;
1209 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 printk(KERN_INFO "fb%d: %s rev %d @ 0x%08x using %dkB memory\n",
1233 info->node, info->fix.id, gbe_revision, (unsigned) GBE_BASE,
1234 gbe_mem_size >> 10);
1240 dma_free_coherent(NULL, gbe_mem_size, gbe_mem, gbe_mem_phys);
1244 dma_free_coherent(NULL, GBE_TLB_SIZE * sizeof(uint16_t),
1245 (void *)gbe_tiles.cpu, gbe_tiles.dma);
1248 out_release_mem_region:
1249 release_mem_region(GBE_BASE, sizeof(struct sgi_gbe));
1250 out_release_framebuffer:
1251 framebuffer_release(info);
1256 static int __devexit gbefb_remove(struct platform_device* p_dev)
1258 struct fb_info *info = platform_get_drvdata(p_dev);
1260 unregister_framebuffer(info);
1263 dma_free_coherent(NULL, gbe_mem_size, gbe_mem, gbe_mem_phys);
1266 dma_free_coherent(NULL, GBE_TLB_SIZE * sizeof(uint16_t),
1267 (void *)gbe_tiles.cpu, gbe_tiles.dma);
1268 release_mem_region(GBE_BASE, sizeof(struct sgi_gbe));
1270 gbefb_remove_sysfs(&p_dev->dev);
1271 framebuffer_release(info);
1276 static struct platform_driver gbefb_driver = {
1277 .probe = gbefb_probe,
1278 .remove = __devexit_p(gbefb_remove),
1284 static struct platform_device *gbefb_device;
1286 static int __init gbefb_init(void)
1288 int ret = platform_driver_register(&gbefb_driver);
1290 gbefb_device = platform_device_alloc("gbefb", 0);
1292 ret = platform_device_add(gbefb_device);
1297 platform_device_put(gbefb_device);
1298 platform_driver_unregister(&gbefb_driver);
1304 static void __exit gbefb_exit(void)
1306 platform_device_unregister(gbefb_device);
1307 platform_driver_unregister(&gbefb_driver);
1310 module_init(gbefb_init);
1311 module_exit(gbefb_exit);
1313 MODULE_LICENSE("GPL");