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

📄 sa1100fb.c

📁 Linux内核源代码 为压缩文件 是<<Linux内核>>一书中的源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
/* * linux/drivers/video/sa1100fb.c -- StrongARM 1100 LCD Controller Frame Buffer Device * *  Copyright (C) 1999 Eric A. Thomas *   * 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. * *//* *   Code Status: * 1999/04/01: * 	Driver appears to be working for Brutus 320x200x8bpp mode.  Other * 	resolutions are working, but only the 8bpp mode is supported. * 	Changes need to be made to the palette encode and decode routines * 	to support 4 and 16 bpp modes.   * 	Driver is not designed to be a module.  The FrameBuffer is statically * 	allocated since dynamic allocation of a 300k buffer cannot be  * 	guaranteed.  *  * 1999/06/17: * 	FrameBuffer memory is now allocated at run-time when the * 	driver is initialized.     * * 2000/04/10: * 	Big cleanup for dynamic selection of machine type at run time. * 		Nicolas Pitre <nico@cam.org> *  * 2000/07/19: * 	Support for Bitsy aka Compaq iPAQ H3600 added. * 		Jamey Hicks <jamey@crl.dec.com> *  * 2000/08/07: * 	Resolved an issue caused by a change made to the Assabet's PLD  * 	earlier this year which broke the framebuffer driver for newer  * 	Phase 4 Assabets.  Some other parameters were changed to optimize for * 	the Sharp display. * 		Tak-Shing Chan <tchan.rd@idthk.com> * 		Jeff Sutherland <jsutherland@accelent.com> *  * 2000/08/09: * 	XP860 support added * 		Kunihiko IMAI <imai@vasara.co.jp> * * 2000/08/19: * 	Allows standard options to be passed on the kernel command line * 	for most common passive displays. * 		Mark Huang <mhuang@livetoy.com> * * 2000/08/29: *	s/save_flags_cli/local_irq_save/ *      remove unneeded extra save_flags_cli in *       sa1100fb_enable_lcd_controller */#include <linux/config.h>#include <linux/module.h>#include <linux/kernel.h>#include <linux/sched.h>#include <linux/errno.h>#include <linux/string.h>#include <linux/ctype.h>#include <linux/mm.h>#include <linux/tty.h>#include <linux/malloc.h>#include <linux/init.h>#include <linux/fb.h>#include <linux/delay.h>#include <linux/wrapper.h>#include <asm/hardware.h>#include <asm/io.h>#include <asm/irq.h>#include <asm/mach-types.h>#include <asm/uaccess.h>#include <asm/proc/pgtable.h>#include <video/fbcon.h>#include <video/fbcon-mfb.h>#include <video/fbcon-cfb4.h>#include <video/fbcon-cfb8.h>#include <video/fbcon-cfb16.h>/* *  Debug macros  *///#define DEBUG #ifdef DEBUG#  define DPRINTK(fmt, args...)	printk("%s: " fmt, __FUNCTION__ , ## args)#else#  define DPRINTK(fmt, args...)#endif/* Memory size macros for determining required FrameBuffer size */#define MAX_PALETTE_NUM_ENTRIES		256#define MAX_PALETTE_MEM_SIZE		(MAX_PALETTE_NUM_ENTRIES * 2)#define MAX_PIXEL_MEM_SIZE \	((current_par.max_xres * current_par.max_yres * current_par.max_bpp)/8)#define MAX_FRAMEBUFFER_MEM_SIZE \	(MAX_PIXEL_MEM_SIZE + MAX_PALETTE_MEM_SIZE + 32)#define ALLOCATED_FB_MEM_SIZE \	(PAGE_ALIGN(MAX_FRAMEBUFFER_MEM_SIZE + PAGE_SIZE * 2))#define SA1100_PALETTE_MEM_SIZE(bpp)	(((bpp)==8?256:16)*2)#define SA1100_PALETTE_MODE_VAL(bpp)    (((bpp) & 0x018) << 9)/* Minimum X and Y resolutions */#define MIN_XRES	64#define MIN_YRES	64/* Possible controller_state modes */#define LCD_MODE_DISABLED		0    // Controller is disabled and Disable Done received#define LCD_MODE_DISABLE_BEFORE_ENABLE	1    // Re-enable after Disable Done IRQ is received#define LCD_MODE_ENABLED		2    // Controller is enabled#define SA1100_NAME	"SA1100"#define NR_MONTYPES	1static inline voidsa1100fb_assabet_set_truecolor(u_int is_true_color){#ifdef CONFIG_SA1100_ASSABET#if 1	// phase 4 or newer Assabet's        if (is_true_color)		BCR_set(BCR_LCD_12RGB);	else		BCR_clear(BCR_LCD_12RGB);#else	// older Assabet's        if (is_true_color)		BCR_clear(BCR_LCD_12RGB);	else		BCR_set(BCR_LCD_12RGB);#endif#endif}static u_char *VideoMemRegion;static u_char *VideoMemRegion_phys;/* Local LCD controller parameters *//* These can be reduced by making better use of fb_var_screeninfo parameters.  *//* Several duplicates exist in the two structures. */struct sa1100fb_par {	u_char		*p_screen_base;	u_char		*v_screen_base;	u_short		*p_palette_base;	u_short		*v_palette_base;	unsigned long	screen_size;	unsigned int	palette_size;	unsigned int	max_xres;	unsigned int	max_yres;	unsigned int	xres;	unsigned int	yres;	unsigned int	xres_virtual;	unsigned int	yres_virtual;	unsigned int	max_bpp;	unsigned int	bits_per_pixel;	  signed int	montype;	unsigned int	currcon;	unsigned int	visual;	unsigned int	allow_modeset : 1;	unsigned int	active_lcd : 1;	unsigned int	inv_4bpp : 1;	volatile u_char	controller_state;};/* Shadows for LCD controller registers */struct sa1100fb_lcd_reg {	Address	dbar1;	Address dbar2;	Word	lccr0;	Word	lccr1;	Word	lccr2;	Word	lccr3;};/* Fake monspecs to fill in fbinfo structure */static struct fb_monspecs monspecs __initdata = {	 30000, 70000, 50, 65, 0 	/* Generic */};static struct display global_disp;	/* Initial (default) Display Settings */static struct fb_info fb_info;static struct sa1100fb_par current_par;static struct fb_var_screeninfo __initdata init_var = {};static struct sa1100fb_lcd_reg lcd_shadow;static int  sa1100fb_get_fix(struct fb_fix_screeninfo *fix, int con, struct fb_info *info);static int  sa1100fb_get_var(struct fb_var_screeninfo *var, int con, struct fb_info *info);static int  sa1100fb_set_var(struct fb_var_screeninfo *var, int con, struct fb_info *info);static int  sa1100fb_get_cmap(struct fb_cmap *cmap, int kspc, int con, struct fb_info *info);static int  sa1100fb_set_cmap(struct fb_cmap *cmap, int kspc, int con, struct fb_info *info); static int  sa1100fb_switch(int con, struct fb_info *info);static void sa1100fb_blank(int blank, struct fb_info *info);static int  sa1100fb_map_video_memory(void);static int  sa1100fb_activate_var(struct fb_var_screeninfo *var);static void sa1100fb_enable_lcd_controller(void);static void sa1100fb_disable_lcd_controller(void);static struct fb_ops sa1100fb_ops = {	owner:		THIS_MODULE,	fb_get_fix:	sa1100fb_get_fix,	fb_get_var:	sa1100fb_get_var,	fb_set_var:	sa1100fb_set_var,	fb_get_cmap:	sa1100fb_get_cmap,	fb_set_cmap:	sa1100fb_set_cmap,};/* * sa1100fb_palette_write: *    Write palette data to the LCD frame buffer's palette area */static inline voidsa1100fb_palette_write(u_int regno, u_short pal){	current_par.v_palette_base[regno] = (regno ? pal : pal | 	                                     SA1100_PALETTE_MODE_VAL(current_par.bits_per_pixel));}static inline u_shortsa1100fb_palette_encode(u_int regno, u_int red, u_int green, u_int blue, u_int trans){	u_int pal;	if(current_par.bits_per_pixel == 4){		/*		 * RGB -> luminance is defined to be		 * Y =  0.299 * R + 0.587 * G + 0.114 * B		 */		pal = (19595 * red + 38470 * green + 7471 * blue) >> 28;		if( current_par.inv_4bpp )			pal = 15 - pal;	}	else{		pal   = ((red   >>  4) & 0xf00);		pal  |= ((green >>  8) & 0x0f0);		pal  |= ((blue  >> 12) & 0x00f);	}	return pal;}	    static inline u_shortsa1100fb_palette_read(u_int regno){	return (current_par.v_palette_base[regno] & 0x0FFF);}static voidsa1100fb_palette_decode(u_int regno, u_int *red, u_int *green, u_int *blue, u_int *trans){	u_short pal;	pal = sa1100fb_palette_read(regno);	if( current_par.bits_per_pixel == 4){		if( current_par.inv_4bpp )			pal = 15 - pal;		pal &= 0x000f;		pal |= pal << 4;		pal |= pal << 8;		*blue = *green = *red = pal;	}	else{		*blue   = (pal & 0x000f) << 12;		*green  = (pal & 0x00f0) << 8;		*red    = (pal & 0x0f00) << 4;	}        *trans  = 0;}static intsa1100fb_getcolreg(u_int regno, u_int *red, u_int *green, u_int *blue, u_int *trans, struct fb_info *info){	if (regno >= current_par.palette_size)		return 1;		sa1100fb_palette_decode(regno, red, green, blue, trans);	return 0;}static intsa1100fb_setcolreg(u_int regno, u_int red, u_int green, u_int blue, u_int trans, struct fb_info *info){	u_short pal;	if (regno >= current_par.palette_size)		return 1;	pal = sa1100fb_palette_encode(regno, red, green, blue, trans);	sa1100fb_palette_write(regno, pal);	return 0;}static intsa1100fb_get_cmap(struct fb_cmap *cmap, int kspc, int con,		 struct fb_info *info){	int err = 0;        DPRINTK("current_par.visual=%d\n", current_par.visual);	if (con == current_par.currcon)		err = fb_get_cmap(cmap, kspc, sa1100fb_getcolreg, info);	else if (fb_display[con].cmap.len)		fb_copy_cmap(&fb_display[con].cmap, cmap, kspc ? 0 : 2);	else		fb_copy_cmap(fb_default_cmap(current_par.palette_size),			     cmap, kspc ? 0 : 2);	return err;}static intsa1100fb_set_cmap(struct fb_cmap *cmap, int kspc, int con,		  struct fb_info *info){	int err = 0;        DPRINTK("current_par.visual=%d\n", current_par.visual);	if (!fb_display[con].cmap.len)		err = fb_alloc_cmap(&fb_display[con].cmap,				    current_par.palette_size, 0);	if (!err) {		if (con == current_par.currcon)			err = fb_set_cmap(cmap, kspc, sa1100fb_setcolreg,					  info);		fb_copy_cmap(cmap, &fb_display[con].cmap, kspc ? 0 : 1);	}	return err;}static void inlinesa1100fb_get_par(struct sa1100fb_par *par){	*par = current_par;}/* * sa1100fb_encode_var(): * 	Modify var structure using values in par */static int sa1100fb_encode_var(struct fb_var_screeninfo *var,                    struct sa1100fb_par *par){        // Don't know if really want to zero var on entry.        // Look at set_var to see.  If so, may need to add extra params to par     //	memset(var, 0, sizeof(struct fb_var_screeninfo)); 	var->xres = par->xres;	var->yres = par->yres;	var->xres_virtual = par->xres_virtual;	var->yres_virtual = par->yres_virtual;	var->bits_per_pixel = par->bits_per_pixel;        DPRINTK("var->bits_per_pixel=%d\n", var->bits_per_pixel);	switch(var->bits_per_pixel) {	case 2:	case 4:	case 8:		var->red.length	   = 4;		var->green         = var->red;		var->blue          = var->red;		var->transp.length = 0;		break;	case 12:          // This case should differ for Active/Passive mode  	case 16:                if (machine_is_bitsy()) {                        var->red.length    = 4;                        var->blue.length   = 4;                        var->green.length  = 4;                        var->transp.length = 0;                        var->red.offset    = 12;                        var->green.offset  = 7;                        var->blue.offset   = 1;                        var->transp.offset = 0;                } else {                        var->red.length    = 5;                        var->blue.length   = 5;                        var->green.length  = 6;                        var->transp.length = 0;                        var->red.offset    = 11;                        var->green.offset  = 5;                        var->blue.offset   = 0;                        var->transp.offset = 0;                }                break;	}	return 0;} /* *  sa1100fb_decode_var(): *    Get the video params out of 'var'. If a value doesn't fit, round it up, *    if it's too big, return -EINVAL. * *    Suggestion: Round up in the following order: bits_per_pixel, xres, *    yres, xres_virtual, yres_virtual, xoffset, yoffset, grayscale, *    bitfields, horizontal timing, vertical timing. */static intsa1100fb_decode_var(struct fb_var_screeninfo *var,                     struct sa1100fb_par *par){	u_long palette_mem_phys;	u_long palette_mem_size;	*par = current_par;	if ((par->xres = var->xres) < MIN_XRES)		par->xres = MIN_XRES; 	if ((par->yres = var->yres) < MIN_YRES)		par->yres = MIN_YRES;	if (par->xres > current_par.max_xres)		par->xres = current_par.max_xres;	if (par->yres > current_par.max_yres)		par->yres = current_par.max_yres; 	par->xres_virtual = 		var->xres_virtual < par->xres ? par->xres : var->xres_virtual;        par->yres_virtual = 		var->yres_virtual < par->yres ? par->yres : var->yres_virtual;        par->bits_per_pixel = var->bits_per_pixel;        DPRINTK("par->bits_per_pixel=%d\n", par->bits_per_pixel);	switch (par->bits_per_pixel) {#ifdef FBCON_HAS_CFB4        case 4:		par->visual = FB_VISUAL_PSEUDOCOLOR;		par->palette_size = 16;                 break;#endif#ifdef FBCON_HAS_CFB8	case 8:		par->visual = FB_VISUAL_PSEUDOCOLOR;		par->palette_size = 256; 		break;#endif#ifdef FBCON_HAS_CFB16	case 16:  /* RGB 565 */		par->visual = FB_VISUAL_TRUECOLOR;

⌨️ 快捷键说明

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