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

📄 ep93xxfb.c

📁 linux下ep9315的LCD驱动程序源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
/****************************************************************************** * *  File:	linux/drivers/video/ep93xxfb.c * *  Purpose: Support CRT output on a EP9312/EP9315 evaluation board. * *  Build:	Define CONFIG_FB, CONFIG_FB_EP93XX *		which will bring in: *			CONFIG_FONT_8x8 *			CONFIG_FONT_8x16 *			CONFIG_FONT_ACORN_8x8 * *		When building as console, define CONFIG_VT, CONFIG_VT_CONSOLE *		and make sure CONFIG_CMDLINE does NOT have "console=" set. *		CONFIG_EP93XX_KBD_SPI or CONFIG_EP93XX_KBD_SCANNED should also *		be specified. * *  History:	010529	Norman Farquhar at LynuxWorks. * *		Initial version supports: *		- crt only *		- fixed frequency monitor timings: 640x480 *		- single default video mode supported: 640x480x8 *		- no module support because this is core logic *		- never will be SMP * *		Derived from:	arm-linux-2.4.0-test11-rmk1 *				linux/drivers/video/sa1100fb.c *				Version 2000/08/29 *				Copyright (C) 1999 Eric A. Thomas *				See file for many other contributors. * * (c) Copyright 2001 LynuxWorks, Inc., San Jose, CA.  All rights reserved. * * 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. * *============================================================================= *	Overview of Frame Buffer driver *============================================================================= * *	The frame buffer driver supports the core logic display controller *	of the ep93xx family machines.  These machines are embedded systems *	and this driver provides for a few video modes with small code *	footprint.  Both CRT and LCD may be supported in the future. * *	Generic fb driver model (skeletonfb.c, fbgen.c) is a bit whacked *	so this driver has been converted back to simpler older style. *	See below for list of complaints about generic fb model! * * *	Linux color models supported: * *		CFB8 is 8 bit packed pixel format using 256 color LUT *		Believed to be similar to Microsoft Windows: *			16 colors VGA standard *			16 grays *			224 color loadable palette *		Note: Linux Logo uses 6x6x6=216 color space * *	Linux color models NOT supported: * *		CFB4 is 4 bit packed pixel format using 16 color LUT *			16 colors VGA standard *		CFB16 is 16 bit flexible format (ep93xx uses R5:G6:B5) *		CFB24 is 24 bit truecolor R8:G8:B8 *		CFB32 is 32 bit truecolor alpha:R8:G8:B8 * *	Reminder about setting up /dev device nodes: * *		console	c 5,1		to virtual console driver *					so that Linux bootup is visible *					when fb is console. * *		fb	link /dev/fb0	used by applications * *		fb0	c 29,0		to fbmem device * *		tty	link /dev/console	recommended by BinZ for *		tty0	link /dev/console	older Linux applications * * *============================================================================= *	Hardware Details *============================================================================= * *	1.  Display controller uses system memory, not a dedicated frame buffer *	RAM.  This means that display controller bandwidth to RAM steals from *	CPU bandwidth to RAM. * *		So if bandwidth to memory is about 80MB/s assuming that *		all accesses are 16 byte blocks taking 10 clocks on 50MHz *		system bus.  Then 640x480x8 60Hz is about 19MB/s, or *		1/4 of bus bandwidth which should not impact us badly. * *	2.  Dual hw palettes are a way to avoid sparkle and allow updating at *	anytime, not just during blank period.  Pending hw palette switch *	takes place once per frame during blank. * *	So we keep the master palette copy in memory and update the active hw *	palette by updating the inactive hw palette and then switching. * *	The only complication is writing palette while switch is pending. *	We assume LUTSTAT is updated synchronously with bus clock so that *	writes to LUT complete to either RAM0 or RAM1, even if request to *	switch RAMs comes in asynchronously, in the middle of write to LUT. * *	3.  Some timing registers must be unlocked before access. * *============================================================================= *	Send to www.complaints.linux.com *============================================================================= * *	Generic fb model is too messy IMHO and here is my list of *	problems with it. * *	1.  Note ALL fbgen.c functions really take fb_info_gen, instead of *	fb_info parameters, by casting info instead of changing prototype. * *	2.  Messy stuff in doing encode/decode var. * *	3.  The info structure holds the controlling variables for video. *	But data is passed around and variables tweaked inside routines *	in which you would not expect it. * *	4.  It is not clear that all variables of a structure get inited *	properly because it is not done in one spot. * *	5.  In the driver model fbskeleton.c, initially, both the 'var' and *	'fix' data are derived from 'par'.  This seems backward, and I think *	reflects Linux genesis on a PC with a BIOS which has already set the *	initial video mode. * *	6.  For some reason, there is a local copy of 'par' which is the true *	current mode (Why not use the 'par' field in info??). * *	7.  Consistency checks are device specific, but fb implementation *	is messy:  high level video mode requests are pushed down to low *	level data 'par' and then pulled back out again to high level *	with a consistent, possibly changed mode, changed 'var' * *		decode_var	really checks var consistency and *				translates var to par * *		encode_var	translates par to var *				(one driver just passes back current var *				 which assumes that par set from var) * *****************************************************************************/#include <linux/config.h>#include <linux/module.h>#include <linux/kernel.h>#include <linux/sched.h>#include <linux/errno.h>#include <linux/delay.h>#include <linux/string.h>#include <linux/ctype.h>#include <linux/mm.h>#include <linux/tty.h>#include <linux/slab.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>//TBD some of these may not be needed until full implementation#include <video/fbcon.h>#include <video/fbcon-mfb.h>#include <video/fbcon-cfb4.h>#include <video/fbcon-cfb8.h>#include <video/fbcon-cfb16.h>#include "ep93xxfb.h"#define RasterSetLocked(registername,value) \    {                                       \        outl( 0xAA, REALITI_SWLOCK );       \        outl( value, registername);         \    }/* *  Debug macros */#ifdef DEBUG#  define DPRINTK(fmt, args...)	printk("%s: " fmt, __FUNCTION__ , ## args)#else#  define DPRINTK(fmt, args...)#endif// Max palette entries over all video modes#define MAX_PALETTE_NUM_ENTRIES		256// Max X resolution and Y resolution depend on whether LCD is supported,// and the monitor type.#define MAX_CRT_XRES	640#define MAX_CRT_YRES	480// Max bpp is fixed for low resolutions, but fundamentally depends on the// memory bandwidth which the system can allocate to the raster engine,// and so depends on application.////	TBD can create an array which determines max bpp based on passed//	TBD in resolutions.//#ifdef CONFIG_FB_EP93XX_8BPP#define MAX_BPP		8#elif defined(CONFIG_FB_EP93XX_16BPP_565)#define MAX_BPP		16#else#define MAX_BPP		32#endif// Framebuffer max mem size in bytes over all video modes// Note: mypar not valid yet so need hard numbers here.#define FB_MAX_MEM_SIZE ((MAX_CRT_XRES * MAX_CRT_YRES * MAX_BPP)/8)// Framebuffer mapped mem size in bytes//	This will be an integral number of pages.#define FB_MAPPED_MEM_SIZE (PAGE_ALIGN(FB_MAX_MEM_SIZE + PAGE_SIZE))/* Minimum X and Y resolutions *///TBD how realistic is this for CRT??//#define MIN_XRES	64//#define MIN_YRES	64#define EP93XX_NAME	"EP93XX"#define NR_MONTYPES	1/* 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 ep93xxfb_par{	dma_addr_t	p_screen_base;	unsigned char	*v_screen_base;	unsigned long	screen_size;	unsigned int	palette_size;	unsigned int	xres;	unsigned int	yres;	unsigned int	bits_per_pixel;	int		montype;	unsigned int	currcon;	unsigned int	visual;	u16		palette[16];	// Funky 16 table lookup used by					// "optional" Parameter.};//TBD Linux fbmon.c tries to check monitor support for requested mode.//TBD But 2.4.0 test11 has removed this code from the build./* Fake monspecs to fill in fbinfo structure *///TBD strict VGA monitor has 60,60 instead of 50,65static struct fb_monspecs __initdata monspecs = {	 30000, 70000, 50, 65, 0 	/* Generic, not fixed frequency */};static char default_font_storage[40];static char *default_font = "Acorn8x8";#if defined (CONFIG_FB_LCD_EP93XX)#define DEFAULT_MODE 1#elif defined (CONFIG_FB_CX25871)#define DEFAULT_MODE 3#elif defined (CONFIG_FB_CRT_EP93XX)#define DEFAULT_MODE 0#else#error What Display Setting was that!!!#endifstatic int mode = DEFAULT_MODE;#ifdef CONFIG_FB_CX25871_OVERSCAN#define DEFAULT_OVERSCAN 1#else#define DEFAULT_OVERSCAN 0#endifstatic int overscan = DEFAULT_OVERSCAN;typedef struct _DisplayTimingValues{	const char	*Name;	unsigned long	DisplayID;	int		(* RasterConfigure)(struct _DisplayTimingValues *pTimingValues);	unsigned short	Refresh;	unsigned long	VDiv;	unsigned short	HRes;	unsigned short	HFrontPorch;	unsigned short	HBackPorch;	unsigned short	HSyncWidth;	unsigned short	HTotalClocks;	unsigned short	VRes;	unsigned short	VFrontPorch;	unsigned short	VBackPorch;	unsigned short	VSyncWidth;	unsigned short	VTotalClocks;} DisplayTimingValues;typedef int (* fRasterConfigure)(DisplayTimingValues *);typedef enum{	CRT_GENERIC,	Philips_LB064V02A1,	CX25871,	Sharp} DisplayType;#define TIMING_VALUES(NAME, DISPID, FUNC, REFRESH, VDIV,                \                   HRES, HFP, HBP, HSYNC, VRES, VFP, VBP, VSYNC)        \{                                                                       \	Name:NAME,                                                      \	DISPID, FUNC, REFRESH, VDIV,                                    \	HRES, HFP, HBP, HSYNC, (HRES + HFP + HBP + HSYNC),              \	VRES, VFP, VBP, VSYNC, (VRES + VFP + VBP + VSYNC)               \}static void InitializeCX25871For640x480NTSC(void);static int Conexant_CX25871(DisplayTimingValues *pTimingValues);static int PhilipsLCD(DisplayTimingValues *pTimingValues);DisplayTimingValues static TimingValues[]={	//	// 640x480 Progressive Scan	//	TIMING_VALUES("CRT_GENERIC", CRT_GENERIC,		      (fRasterConfigure)0,		      60, 0x0000c108, 640, 16, 48, 96, 480, 11, 31, 2),	//	// 640x480 Progressive Scan Philips LB064V02A1 on EDB9312 Board.	//	TIMING_VALUES("Philips LB064V02A1", Philips_LB064V02A1,		      PhilipsLCD,		      68, 0x0000c107, 640, 16, 48, 96, 480, 11, 31, 2),	//	// Sharp LQ64D343 LCD Panel	//	TIMING_VALUES("Sharp LQ64d343", CRT_GENERIC,		      (fRasterConfigure)0,		      60, 0x0000c205, 640, 32, 32, 96, 480, 34, 34, 4),	//	// 640x480 NTSC Support for Conexant CX25871	//	TIMING_VALUES("Conexant CX25871", CX25871,		      Conexant_CX25871,		      60, 0x0000c317, 640, 0, 0, 0, 480, 0, 0, 0),};#define NUM_TIMING_VALUES (sizeof(TimingValues)/sizeof(DisplayTimingValues))unsigned int master_palette[256];	/* master copy of palette data *///TBD Before fbcon started, the driver calls set_var with con=-1//TBD which initializes global_disp and puts ptr to it in info.//TBD Later on display console array keeps track of display settings.static struct display global_disp;	/* Initial Display Settings */static struct fb_info fb_info;		// initialized in init_fbinfo()static struct ep93xxfb_par mypar;static int ep93xxfb_get_fix(struct fb_fix_screeninfo *fix,			    int con, struct fb_info *info);static int ep93xxfb_get_var(struct fb_var_screeninfo *var,			    int con, struct fb_info *info);static int ep93xxfb_set_var(struct fb_var_screeninfo *var,			    int con, struct fb_info *info);static int ep93xxfb_get_cmap(struct fb_cmap *cmap, int kspc,			     int con, struct fb_info *info);static int ep93xxfb_set_cmap(struct fb_cmap *cmap, int kspc,			     int con, struct fb_info *info);static int ep93xxfb_ioctl(struct inode *inode, struct file *file,			  unsigned int cmd, unsigned long arg, int con,			  struct fb_info *info);static int  ep93xxfb_switch(int con, struct fb_info *info);static void ep93xxfb_blank(int blank, struct fb_info *info);static int  MapFramebuffer(void);static int  ConfigureRaster(struct fb_var_screeninfo *var,			    DisplayTimingValues *pTimingValues);static struct fb_ops ep93xxfb_ops = {	owner:		THIS_MODULE,	fb_get_fix:	ep93xxfb_get_fix,	fb_get_var:	ep93xxfb_get_var,	fb_set_var:	ep93xxfb_set_var,	fb_get_cmap:	ep93xxfb_get_cmap,	fb_set_cmap:	ep93xxfb_set_cmap,	fb_ioctl:	ep93xxfb_ioctl,};//-----------------------------------------------------------------------------//	Local functions//-----------------------------------------------------------------------------/* * ep93xxfb_palette_write: *	Encode palette data to 24bit palette format. *	Write palette data to the master palette and inactive hw palette *	switch palettes.  And handle asynchronous palette switches. */static inline voidep93xxfb_palette_write(u_int regno, u_int red, u_int green,		       u_int blue, u_int trans){	unsigned int cont, i, pal;	// Only supports color LUT, not gray LUT	//	//	TBD if not in 4 or 8bpp, then does LUT logic operate?	//	TBD or do we need to do nothing here?	// LCD:	TBD RGB mapping may match spec p193.	//	// CRT: LUT RGB mapping is really R/G/B from high to low bits	//	because really determined by wiring to video DAC.	//	(disregard spec p 193 showing color LUT B/G/R order)	//	Here are the details:	//	//	Shift mode 1 directs LUT bits 7-2 onto P5-P0,	//	LUT bits 15-10 onto P11-P6, and LUT bits 23-16	//	onto P17-P12.	//	//	Board wired P17-12 to video DAC Red inputs,	//	P11-P6 wired to video DAC Green inputs, and	//	P5-P0 wired to video DAC Blue inputs.	//	pal = ((red & 0xFF00) << 8) | (green & 0xFF00) | ((blue & 0xFF00) >> 8);	master_palette[regno] = pal;	// Two cases here:	// 1.  	If LUT switch is pending, then write inactive LUT and when	//	switch happens, this new palette entry will be active.	// 	Race condition here between LUT switch and this write is okay	// 	since we fix it below.	//	// 2.	If LUT switch is not pending, then write here is incomplete	//	and whole palette will be written below.

⌨️ 快捷键说明

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