⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 gbefb.c

📁 Linux Kernel 2.6.9 for OMAP1710
💻 C
📖 第 1 页 / 共 3 页
字号:
/* *  SGI GBE frame buffer driver * *  Copyright (C) 1999 Silicon Graphics, Inc. - Jeffrey Newquist *  Copyright (C) 2002 Vivien Chappelier <vivien.chappelier@linux-mips.org> * *  This file is subject to the terms and conditions of the GNU General Public *  License. See the file COPYING in the main directory of this archive for *  more details. */#include <linux/config.h>#include <linux/delay.h>#include <linux/device.h>#include <linux/dma-mapping.h>#include <linux/errno.h>#include <linux/fb.h>#include <linux/init.h>#include <linux/interrupt.h>#include <linux/kernel.h>#include <linux/mm.h>#include <linux/module.h>#ifdef CONFIG_X86#include <asm/mtrr.h>#endif#ifdef CONFIG_MIPS#include <asm/addrspace.h>#endif#include <asm/byteorder.h>#include <asm/io.h>#include <asm/tlbflush.h>#include <video/gbe.h>static struct sgi_gbe *gbe;struct gbefb_par {	struct fb_var_screeninfo var;	struct gbe_timing_info timing;	int valid;};#ifdef CONFIG_SGI_IP32#define GBE_BASE	0x16000000 /* SGI O2 */#endif#ifdef CONFIG_X86_VISWS#define GBE_BASE	0xd0000000 /* SGI Visual Workstation */#endif/* macro for fastest write-though access to the framebuffer */#ifdef CONFIG_MIPS#ifdef CONFIG_CPU_R10000#define pgprot_fb(_prot) (((_prot) & (~_CACHE_MASK)) | _CACHE_UNCACHED_ACCELERATED)#else#define pgprot_fb(_prot) (((_prot) & (~_CACHE_MASK)) | _CACHE_CACHABLE_NO_WA)#endif#endif#ifdef CONFIG_X86#define pgprot_fb(_prot) ((_prot) | _PAGE_PCD)#endif/* *  RAM we reserve for the frame buffer. This defines the maximum screen *  size */#if CONFIG_FB_GBE_MEM > 8#error GBE Framebuffer cannot use more than 8MB of memory#endif#define TILE_SHIFT 16#define TILE_SIZE (1 << TILE_SHIFT)#define TILE_MASK (TILE_SIZE - 1)static unsigned int gbe_mem_size = CONFIG_FB_GBE_MEM * 1024*1024;static void *gbe_mem;static dma_addr_t gbe_dma_addr;unsigned long gbe_mem_phys;static struct {	uint16_t *cpu;	dma_addr_t dma;} gbe_tiles;static int gbe_revision;static struct fb_info fb_info;static int ypan, ywrap;static uint32_t pseudo_palette[256];static char *mode_option __initdata = NULL;/* default CRT mode */static struct fb_var_screeninfo default_var_CRT __initdata = {	/* 640x480, 60 Hz, Non-Interlaced (25.175 MHz dotclock) */	.xres		= 640,	.yres		= 480,	.xres_virtual	= 640,	.yres_virtual	= 480,	.xoffset	= 0,	.yoffset	= 0,	.bits_per_pixel	= 8,	.grayscale	= 0,	.red		= { 0, 8, 0 },	.green		= { 0, 8, 0 },	.blue		= { 0, 8, 0 },	.transp		= { 0, 0, 0 },	.nonstd		= 0,	.activate	= 0,	.height		= -1,	.width		= -1,	.accel_flags	= 0,	.pixclock	= 39722,	/* picoseconds */	.left_margin	= 48,	.right_margin	= 16,	.upper_margin	= 33,	.lower_margin	= 10,	.hsync_len	= 96,	.vsync_len	= 2,	.sync		= 0,	.vmode		= FB_VMODE_NONINTERLACED,};/* default LCD mode */static struct fb_var_screeninfo default_var_LCD __initdata = {	/* 1600x1024, 8 bpp */	.xres		= 1600,	.yres		= 1024,	.xres_virtual	= 1600,	.yres_virtual	= 1024,	.xoffset	= 0,	.yoffset	= 0,	.bits_per_pixel	= 8,	.grayscale	= 0,	.red		= { 0, 8, 0 },	.green		= { 0, 8, 0 },	.blue		= { 0, 8, 0 },	.transp		= { 0, 0, 0 },	.nonstd		= 0,	.activate	= 0,	.height		= -1,	.width		= -1,	.accel_flags	= 0,	.pixclock	= 9353,	.left_margin	= 20,	.right_margin	= 30,	.upper_margin	= 37,	.lower_margin	= 3,	.hsync_len	= 20,	.vsync_len	= 3,	.sync		= 0,	.vmode		= FB_VMODE_NONINTERLACED};/* default modedb mode *//* 640x480, 60 Hz, Non-Interlaced (25.172 MHz dotclock) */static struct fb_videomode default_mode_CRT __initdata = {	.refresh	= 60,	.xres		= 640,	.yres		= 480,	.pixclock	= 39722,	.left_margin	= 48,	.right_margin	= 16,	.upper_margin	= 33,	.lower_margin	= 10,	.hsync_len	= 96,	.vsync_len	= 2,	.sync		= 0,	.vmode		= FB_VMODE_NONINTERLACED,};/* 1600x1024 SGI flatpanel 1600sw */static struct fb_videomode default_mode_LCD __initdata = {	/* 1600x1024, 8 bpp */	.xres		= 1600,	.yres		= 1024,	.pixclock	= 9353,	.left_margin	= 20,	.right_margin	= 30,	.upper_margin	= 37,	.lower_margin	= 3,	.hsync_len	= 20,	.vsync_len	= 3,	.vmode		= FB_VMODE_NONINTERLACED,};struct fb_videomode *default_mode = &default_mode_CRT;struct fb_var_screeninfo *default_var = &default_var_CRT;static int flat_panel_enabled = 0;static struct gbefb_par par_current;static void gbe_reset(void){	/* Turn on dotclock PLL */	gbe->ctrlstat = 0x300aa000;}/* * Function:	gbe_turn_off * Parameters:	(None) * Description:	This should turn off the monitor and gbe.  This is used *              when switching between the serial console and the graphics *              console. */void gbe_turn_off(void){	int i;	unsigned int val, x, y, vpixen_off;	/* check if pixel counter is on */	val = gbe->vt_xy;	if (GET_GBE_FIELD(VT_XY, FREEZE, val) == 1)		return;	/* turn off DMA */	val = gbe->ovr_control;	SET_GBE_FIELD(OVR_CONTROL, OVR_DMA_ENABLE, val, 0);	gbe->ovr_control = val;	udelay(1000);	val = gbe->frm_control;	SET_GBE_FIELD(FRM_CONTROL, FRM_DMA_ENABLE, val, 0);	gbe->frm_control = val;	udelay(1000);	val = gbe->did_control;	SET_GBE_FIELD(DID_CONTROL, DID_DMA_ENABLE, val, 0);	gbe->did_control = val;	udelay(1000);	/* We have to wait through two vertical retrace periods before	 * the pixel DMA is turned off for sure. */	for (i = 0; i < 10000; i++) {		val = gbe->frm_inhwctrl;		if (GET_GBE_FIELD(FRM_INHWCTRL, FRM_DMA_ENABLE, val)) {			udelay(10);		} else {			val = gbe->ovr_inhwctrl;			if (GET_GBE_FIELD(OVR_INHWCTRL, OVR_DMA_ENABLE, val)) {				udelay(10);			} else {				val = gbe->did_inhwctrl;				if (GET_GBE_FIELD(DID_INHWCTRL, DID_DMA_ENABLE, val)) {					udelay(10);				} else					break;			}		}	}	if (i == 10000)		printk(KERN_ERR "gbefb: turn off DMA timed out\n");	/* wait for vpixen_off */	val = gbe->vt_vpixen;	vpixen_off = GET_GBE_FIELD(VT_VPIXEN, VPIXEN_OFF, val);	for (i = 0; i < 100000; i++) {		val = gbe->vt_xy;		x = GET_GBE_FIELD(VT_XY, X, val);		y = GET_GBE_FIELD(VT_XY, Y, val);		if (y < vpixen_off)			break;		udelay(1);	}	if (i == 100000)		printk(KERN_ERR		       "gbefb: wait for vpixen_off timed out\n");	for (i = 0; i < 10000; i++) {		val = gbe->vt_xy;		x = GET_GBE_FIELD(VT_XY, X, val);		y = GET_GBE_FIELD(VT_XY, Y, val);		if (y > vpixen_off)			break;		udelay(1);	}	if (i == 10000)		printk(KERN_ERR "gbefb: wait for vpixen_off timed out\n");	/* turn off pixel counter */	val = 0;	SET_GBE_FIELD(VT_XY, FREEZE, val, 1);	gbe->vt_xy = val;	udelay(10000);	for (i = 0; i < 10000; i++) {		val = gbe->vt_xy;		if (GET_GBE_FIELD(VT_XY, FREEZE, val) != 1)			udelay(10);		else			break;	}	if (i == 10000)		printk(KERN_ERR "gbefb: turn off pixel clock timed out\n");	/* turn off dot clock */	val = gbe->dotclock;	SET_GBE_FIELD(DOTCLK, RUN, val, 0);	gbe->dotclock = val;	udelay(10000);	for (i = 0; i < 10000; i++) {		val = gbe->dotclock;		if (GET_GBE_FIELD(DOTCLK, RUN, val))			udelay(10);		else			break;	}	if (i == 10000)		printk(KERN_ERR "gbefb: turn off dotclock timed out\n");	/* reset the frame DMA FIFO */	val = gbe->frm_size_tile;	SET_GBE_FIELD(FRM_SIZE_TILE, FRM_FIFO_RESET, val, 1);	gbe->frm_size_tile = val;	SET_GBE_FIELD(FRM_SIZE_TILE, FRM_FIFO_RESET, val, 0);	gbe->frm_size_tile = val;}static void gbe_turn_on(void){	unsigned int val, i;	/*	 * Check if pixel counter is off, for unknown reason this	 * code hangs Visual Workstations	 */	if (gbe_revision < 2) {		val = gbe->vt_xy;		if (GET_GBE_FIELD(VT_XY, FREEZE, val) == 0)			return;	}	/* turn on dot clock */	val = gbe->dotclock;	SET_GBE_FIELD(DOTCLK, RUN, val, 1);	gbe->dotclock = val;	udelay(10000);	for (i = 0; i < 10000; i++) {		val = gbe->dotclock;		if (GET_GBE_FIELD(DOTCLK, RUN, val) != 1)			udelay(10);		else			break;	}	if (i == 10000)		printk(KERN_ERR "gbefb: turn on dotclock timed out\n");	/* turn on pixel counter */	val = 0;	SET_GBE_FIELD(VT_XY, FREEZE, val, 0);	gbe->vt_xy = val;	udelay(10000);	for (i = 0; i < 10000; i++) {		val = gbe->vt_xy;		if (GET_GBE_FIELD(VT_XY, FREEZE, val))			udelay(10);		else			break;	}	if (i == 10000)		printk(KERN_ERR "gbefb: turn on pixel clock timed out\n");	/* turn on DMA */	val = gbe->frm_control;	SET_GBE_FIELD(FRM_CONTROL, FRM_DMA_ENABLE, val, 1);	gbe->frm_control = val;	udelay(1000);	for (i = 0; i < 10000; i++) {		val = gbe->frm_inhwctrl;		if (GET_GBE_FIELD(FRM_INHWCTRL, FRM_DMA_ENABLE, val) != 1)			udelay(10);		else			break;	}	if (i == 10000)		printk(KERN_ERR "gbefb: turn on DMA timed out\n");}/* *  Blank the display. */static int gbefb_blank(int blank, struct fb_info *info){	/* 0 unblank, 1 blank, 2 no vsync, 3 no hsync, 4 off */	switch (blank) {	case 0:		/* unblank */		gbe_turn_on();		break;	case 1:		/* blank */		gbe_turn_off();		break;	default:		/* Nothing */		break;	}	return 0;}/* *  Setup flatpanel related registers. */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -