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

📄 sa1100fb.c

📁 S3C44B0X下的LCD (framebuffer)驱动资料与相关代码
💻 C
📖 第 1 页 / 共 5 页
字号:
/* *  linux/drivers/video/sa1100fb.c * *  Copyright (C) 1999 Eric A. Thomas *   Based on acornfb.c Copyright (C) Russell King. * * 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. * *	        StrongARM 1100 LCD Controller Frame Buffer Driver * * Please direct your questions and comments on this driver to the following * email address: * *	linux-arm-kernel@lists.arm.linux.org.uk * * Clean patches should be sent to the ARM Linux Patch System.  Please see the * following web page for more information: * *	http://www.arm.linux.org.uk/developer/patches/info.shtml * * Thank you. * * Known problems: *  - With the Neponset plugged into an Assabet, LCD powerdown *    doesn't work (LCD stays powered up).  Therefore we shouldn't *    blank the screen. *  - We don't limit the CPU clock rate nor the mode selection *    according to the available SDRAM bandwidth. * * Other notes: *	- Linear grayscale palettes and the kernel. *	  Such code does not belong in the kernel.  The kernel frame buffer *	  drivers do not expect a linear colourmap, but a colourmap based on *	  the VT100 standard mapping. * *	  If your _userspace_ requires a linear colourmap, then the setup of *	  such a colourmap belongs _in userspace_, not in the kernel.  Code *	  to set the colourmap correctly from user space has been sent to *	  David Neuer.  It's around 8 lines of C code, plus another 4 to *	  detect if we are using grayscale. * * 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: Nicolas Pitre <nico@cam.org> *	- Big cleanup for dynamic selection of machine type at run time. * * 2000/07/19: Jamey Hicks <jamey@crl.dec.com> *	- Support for Bitsy aka Compaq iPAQ H3600 added. * * 2000/08/07: Tak-Shing Chan <tchan.rd@idthk.com> *	       Jeff Sutherland <jsutherland@accelent.com> *	- 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. * * 2000/08/09: Kunihiko IMAI <imai@vasara.co.jp> *	- XP860 support added * * 2000/08/19: Mark Huang <mhuang@livetoy.com> *	- Allows standard options to be passed on the kernel command line *	  for most common passive displays. * * 2000/08/29: *	- s/save_flags_cli/local_irq_save/ *	- remove unneeded extra save_flags_cli in sa1100fb_enable_lcd_controller * * 2000/10/10: Erik Mouw <J.A.K.Mouw@its.tudelft.nl> *	- Updated LART stuff. Fixed some minor bugs. * * 2000/10/30: Murphy Chen <murphy@mail.dialogue.com.tw> *	- Pangolin support added * * 2000/10/31: Roman Jordan <jor@hoeft-wessel.de> *	- Huw Webpanel support added * * 2000/11/23: Eric Peng <ericpeng@coventive.com> *	- Freebird add * * 2001/02/07: Jamey Hicks <jamey.hicks@compaq.com>  *	       Cliff Brake <cbrake@accelent.com> *	- Added PM callback * * 2001/05/26: <rmk@arm.linux.org.uk> *	- Fix 16bpp so that (a) we use the right colours rather than some *	  totally random colour depending on what was in page 0, and (b) *	  we don't de-reference a NULL pointer. *	- remove duplicated implementation of consistent_alloc() *	- convert dma address types to dma_addr_t *	- remove unused 'montype' stuff *	- remove redundant zero inits of init_var after the initial *	  memzero. *	- remove allow_modeset (acornfb idea does not belong here) * * 2001/05/28: <rmk@arm.linux.org.uk> *	- massive cleanup - move machine dependent data into structures *	- I've left various #warnings in - if you see one, and know *	  the hardware concerned, please get in contact with me. * * 2001/05/31: <rmk@arm.linux.org.uk> *	- Fix LCCR1 HSW value, fix all machine type specifications to *	  keep values in line.  (Please check your machine type specs) * * 2001/06/10: <rmk@arm.linux.org.uk> *	- Fiddle with the LCD controller from task context only; mainly *	  so that we can run with interrupts on, and sleep. *	- Convert #warnings into #errors.  No pain, no gain. ;) * * 2001/06/14: <rmk@arm.linux.org.uk> *	- Make the palette BPS value for 12bpp come out correctly. *	- Take notice of "greyscale" on any colour depth. *	- Make truecolor visuals use the RGB channel encoding information. * * 2001/07/02: <rmk@arm.linux.org.uk> *	- Fix colourmap problems. * * 2001/07/13: <abraham@2d3d.co.za> *	- Added support for the ICP LCD-Kit01 on LART. This LCD is *	  manufactured by Prime View, model no V16C6448AB * * 2001/07/23: <rmk@arm.linux.org.uk> *	- Hand merge version from handhelds.org CVS tree.  See patch *	  notes for 595/1 for more information. *	- Drop 12bpp (it's 16bpp with different colour register mappings). *	- This hardware can not do direct colour.  Therefore we don't *	  support it. * * 2001/07/27: <rmk@arm.linux.org.uk> *	- Halve YRES on dual scan LCDs. * * 2001/08/22: <rmk@arm.linux.org.uk> *	- Add b/w iPAQ pixclock value. * * 2001/10/12: <rmk@arm.linux.org.uk> *	- Add patch 681/1 and clean up stork definitions. */#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/interrupt.h>#include <linux/slab.h>#include <linux/fb.h>#include <linux/delay.h>#include <linux/pm.h>#include <linux/init.h>#include <linux/cpufreq.h>#include <asm/hardware.h>#include <asm/io.h>#include <asm/irq.h>#include <asm/mach-types.h>#include <asm/uaccess.h>#include <asm/arch/assabet.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>/* * enable this if your panel appears to have broken */#undef CHECK_COMPAT/* * debugging? */#define DEBUG 0/* * Complain if VAR is out of range. */#define DEBUG_VAR 1#undef ASSABET_PAL_VIDEO#include "sa1100fb.h"void (*sa1100fb_blank_helper)(int blank);EXPORT_SYMBOL(sa1100fb_blank_helper);#ifdef CHECK_COMPATstatic voidsa1100fb_check_shadow(struct sa1100fb_lcd_reg *new_regs,			   struct fb_var_screeninfo *var, u_int pcd){	struct sa1100fb_lcd_reg shadow;	int different = 0;	/*	 * These machines are good machines!	 */	if (machine_is_assabet() || machine_is_h3600())		return;	/*	 * The following ones are bad, bad, bad.	 * Please make yours good!	 */	if (machine_is_pangolin()) {		DPRINTK("Configuring Pangolin LCD\n");		shadow.lccr0 =		    LCCR0_LEN + LCCR0_Color + LCCR0_LDM +		    LCCR0_BAM + LCCR0_ERM + LCCR0_Act +		    LCCR0_LtlEnd + LCCR0_DMADel(0);		shadow.lccr1 =		    LCCR1_DisWdth(var->xres) + LCCR1_HorSnchWdth(64) +		    LCCR1_BegLnDel(160) + LCCR1_EndLnDel(24);		shadow.lccr2 =		    LCCR2_DisHght(var->yres) + LCCR2_VrtSnchWdth(7) +		    LCCR2_BegFrmDel(7) + LCCR2_EndFrmDel(1);		shadow.lccr3 =		    LCCR3_PixClkDiv(pcd) + LCCR3_HorSnchH +		    LCCR3_VrtSnchH + LCCR3_PixFlEdg + LCCR3_OutEnH;		DPRINTK("pcd = %x, PixCldDiv(pcd)=%x\n",			pcd, LCCR3_PixClkDiv(pcd));	}	if (machine_is_freebird()) {		DPRINTK("Configuring  Freebird LCD\n");#if 1		shadow.lccr0 = 0x00000038;		shadow.lccr1 = 0x010108e0;		shadow.lccr2 = 0x0000053f;		shadow.lccr3 = 0x00000c20;#else		shadow.lccr0 =		    LCCR0_LEN + LCCR0_Color + LCCR0_Sngl +		    LCCR0_LDM + LCCR0_BAM + LCCR0_ERM + LCCR0_Pas +		    LCCR0_LtlEnd + LCCR0_DMADel(0);		/* Check ,Chester */		shadow.lccr1 =		    LCCR1_DisWdth(var->xres) + LCCR1_HorSnchWdth(5) +		    LCCR1_BegLnDel(61) + LCCR1_EndLnDel(9);		/* Check ,Chester */		shadow.lccr2 =		    LCCR2_DisHght(var->yres) + LCCR2_VrtSnchWdth(1) +		    LCCR2_BegFrmDel(3) + LCCR2_EndFrmDel(0);		/* Check ,Chester */		shadow.lccr3 =		    LCCR3_OutEnH + LCCR3_PixFlEdg + LCCR3_VrtSnchH +		    LCCR3_HorSnchH + LCCR3_ACBsCntOff +		    LCCR3_ACBsDiv(2) + LCCR3_PixClkDiv(pcd);#endif	}	if (machine_is_brutus()) {		DPRINTK("Configuring  Brutus LCD\n");		shadow.lccr0 =		    LCCR0_LEN + LCCR0_Color + LCCR0_Sngl + LCCR0_Pas +		    LCCR0_LtlEnd + LCCR0_LDM + LCCR0_BAM + LCCR0_ERM +		    LCCR0_DMADel(0);		shadow.lccr1 =		    LCCR1_DisWdth(var->xres) + LCCR1_HorSnchWdth(3) +		    LCCR1_BegLnDel(41) + LCCR1_EndLnDel(101);		shadow.lccr2 =		    LCCR2_DisHght(var->yres) + LCCR2_VrtSnchWdth(1) +		    LCCR2_BegFrmDel(0) + LCCR2_EndFrmDel(0);		shadow.lccr3 =		    LCCR3_OutEnH + LCCR3_PixRsEdg + LCCR3_VrtSnchH +		    LCCR3_HorSnchH + LCCR3_ACBsCntOff +		    LCCR3_ACBsDiv(2) + LCCR3_PixClkDiv(44);	}	if (machine_is_huw_webpanel()) {		DPRINTK("Configuring  HuW LCD\n");		shadow.lccr0 = LCCR0_LEN + LCCR0_Dual + LCCR0_LDM;		shadow.lccr1 = LCCR1_DisWdth(var->xres) +		    LCCR1_HorSnchWdth(3) +		    LCCR1_BegLnDel(41) + LCCR1_EndLnDel(101);		shadow.lccr2 = 239 + LCCR2_VrtSnchWdth(1);		shadow.lccr3 = 8 + LCCR3_OutEnH +		    LCCR3_PixRsEdg + LCCR3_VrtSnchH +		    LCCR3_HorSnchH + LCCR3_ACBsCntOff + LCCR3_ACBsDiv(2);	}	if (machine_is_lart()) {		DPRINTK("Configuring LART LCD\n");#if defined LART_GREY_LCD		shadow.lccr0 =		    LCCR0_LEN + LCCR0_Mono + LCCR0_Sngl + LCCR0_Pas +		    LCCR0_LtlEnd + LCCR0_LDM + LCCR0_BAM + LCCR0_ERM +		    LCCR0_DMADel(0);		shadow.lccr1 =		    LCCR1_DisWdth(var->xres) + LCCR1_HorSnchWdth(1) +		    LCCR1_BegLnDel(4) + LCCR1_EndLnDel(2);		shadow.lccr2 =		    LCCR2_DisHght(var->yres) + LCCR2_VrtSnchWdth(1) +		    LCCR2_BegFrmDel(0) + LCCR2_EndFrmDel(0);		shadow.lccr3 =		    LCCR3_PixClkDiv(34) + LCCR3_ACBsDiv(512) +		    LCCR3_ACBsCntOff + LCCR3_HorSnchH + LCCR3_VrtSnchH;#endif#if defined LART_COLOR_LCD		shadow.lccr0 =		    LCCR0_LEN + LCCR0_Color + LCCR0_Sngl + LCCR0_Act +		    LCCR0_LtlEnd + LCCR0_LDM + LCCR0_BAM + LCCR0_ERM +		    LCCR0_DMADel(0);		shadow.lccr1 =		    LCCR1_DisWdth(var->xres) + LCCR1_HorSnchWdth(2) +		    LCCR1_BegLnDel(69) + LCCR1_EndLnDel(8);		shadow.lccr2 =		    LCCR2_DisHght(var->yres) + LCCR2_VrtSnchWdth(3) +		    LCCR2_BegFrmDel(14) + LCCR2_EndFrmDel(4);		shadow.lccr3 =		    LCCR3_PixClkDiv(34) + LCCR3_ACBsDiv(512) +		    LCCR3_ACBsCntOff + LCCR3_HorSnchL + LCCR3_VrtSnchL +		    LCCR3_PixFlEdg;#endif#if defined LART_VIDEO_OUT		shadow.lccr0 =		    LCCR0_LEN + LCCR0_Color + LCCR0_Sngl + LCCR0_Act +		    LCCR0_LtlEnd + LCCR0_LDM + LCCR0_BAM + LCCR0_ERM +		    LCCR0_DMADel(0);		shadow.lccr1 =		    LCCR1_DisWdth(640) + LCCR1_HorSnchWdth(95) +		    LCCR1_BegLnDel(40) + LCCR1_EndLnDel(24);		shadow.lccr2 =		    LCCR2_DisHght(480) + LCCR2_VrtSnchWdth(2) +		    LCCR2_BegFrmDel(32) + LCCR2_EndFrmDel(11);		shadow.lccr3 =		    LCCR3_PixClkDiv(8) + LCCR3_ACBsDiv(512) +		    LCCR3_ACBsCntOff + LCCR3_HorSnchH + LCCR3_VrtSnchH +		    LCCR3_PixFlEdg + LCCR3_OutEnL;#endif	}	if (machine_is_graphicsclient()) {		DPRINTK("Configuring GraphicsClient LCD\n");		shadow.lccr0 =		    LCCR0_LEN + LCCR0_Color + LCCR0_Sngl + LCCR0_Act;		shadow.lccr1 =		    LCCR1_DisWdth(var->xres) + LCCR1_HorSnchWdth(9) +		    LCCR1_EndLnDel(54) + LCCR1_BegLnDel(54);		shadow.lccr2 =		    LCCR2_DisHght(var->yres) + LCCR2_VrtSnchWdth(9) +		    LCCR2_EndFrmDel(32) + LCCR2_BegFrmDel(24);		shadow.lccr3 =		    LCCR3_PixClkDiv(10) + LCCR3_ACBsDiv(2) +		    LCCR3_ACBsCntOff + LCCR3_HorSnchL + LCCR3_VrtSnchL;	}	if (machine_is_omnimeter()) {		DPRINTK("Configuring  OMNI LCD\n");		shadow.lccr0 = LCCR0_LEN | LCCR0_CMS | LCCR0_DPD;		shadow.lccr1 =		    LCCR1_BegLnDel(10) + LCCR1_EndLnDel(10) +		    LCCR1_HorSnchWdth(1) + LCCR1_DisWdth(var->xres);		shadow.lccr2 = LCCR2_DisHght(var->yres);		shadow.lccr3 =		    LCCR3_ACBsDiv(0xFF) + LCCR3_PixClkDiv(44);//jca (GetPCD(25) << LCD3_V_PCD);	}	if (machine_is_xp860()) {		DPRINTK("Configuring XP860 LCD\n");		shadow.lccr0 =		    LCCR0_LEN + LCCR0_Color + LCCR0_Sngl + LCCR0_Act +		    LCCR0_LtlEnd + LCCR0_LDM + LCCR0_ERM + LCCR0_DMADel(0);		shadow.lccr1 =		    LCCR1_DisWdth(var->xres) +		    LCCR1_HorSnchWdth(var->hsync_len) +		    LCCR1_BegLnDel(var->left_margin) +		    LCCR1_EndLnDel(var->right_margin);		shadow.lccr2 =		    LCCR2_DisHght(var->yres) +		    LCCR2_VrtSnchWdth(var->vsync_len) +		    LCCR2_BegFrmDel(var->upper_margin) +		    LCCR2_EndFrmDel(var->lower_margin);		shadow.lccr3 =		    LCCR3_PixClkDiv(6) + LCCR3_HorSnchL + LCCR3_VrtSnchL;	}	/*	 * Ok, since we're calculating these values, we want to know	 * if the calculation is correct.  If you see any of these	 * messages _PLEASE_ report the incident to me for diagnosis,	 * including details about what was happening when the	 * messages appeared. --rmk, 30 March 2001	 */	if (shadow.lccr0 != new_regs->lccr0) {		printk(KERN_ERR "LCCR1 mismatch: 0x%08x != 0x%08x\n",			shadow.lccr1, new_regs->lccr1);		different = 1;	}	if (shadow.lccr1 != new_regs->lccr1) {		printk(KERN_ERR "LCCR1 mismatch: 0x%08x != 0x%08x\n",			shadow.lccr1, new_regs->lccr1);		different = 1;	}	if (shadow.lccr2 != new_regs->lccr2) {		printk(KERN_ERR "LCCR2 mismatch: 0x%08x != 0x%08x\n",			shadow.lccr2, new_regs->lccr2);		different = 1;	}	if (shadow.lccr3 != new_regs->lccr3) {		printk(KERN_ERR "LCCR3 mismatch: 0x%08x != 0x%08x\n",			shadow.lccr3, new_regs->lccr3);		different = 1;	}	if (different) {		printk(KERN_ERR "var: xres=%d hslen=%d lm=%d rm=%d\n",			var->xres, var->hsync_len,			var->left_margin, var->right_margin);		printk(KERN_ERR "var: yres=%d vslen=%d um=%d bm=%d\n",			var->yres, var->vsync_len,			var->upper_margin, var->lower_margin);		printk(KERN_ERR "Please report this to Russell King "			"<rmk@arm.linux.org.uk>\n");	}	DPRINTK("olccr0 = 0x%08x\n", shadow.lccr0);	DPRINTK("olccr1 = 0x%08x\n", shadow.lccr1);	DPRINTK("olccr2 = 0x%08x\n", shadow.lccr2);	DPRINTK("olccr3 = 0x%08x\n", shadow.lccr3);}#else#define sa1100fb_check_shadow(regs,var,pcd)#endif/* * IMHO this looks wrong.  In 8BPP, length should be 8. */static struct sa1100fb_rgb rgb_8 = {	red:	{ offset: 0,  length: 4, },	green:	{ offset: 0,  length: 4, },	blue:	{ offset: 0,  length: 4, },	transp:	{ offset: 0,  length: 0, },};static struct sa1100fb_rgb def_rgb_16 = {	red:	{ offset: 11, length: 5, },	green:	{ offset: 5,  length: 6, },	blue:	{ offset: 0,  length: 5, },	transp:	{ offset: 0,  length: 0, },};#ifdef CONFIG_SA1100_ASSABET#ifndef ASSABET_PAL_VIDEO/* * The assabet uses a sharp LQ039Q2DS54 LCD module.  It is actually * takes an RGB666 signal, but we provide it with an RGB565 signal * instead (def_rgb_16). */static struct sa1100fb_mach_info lq039q2ds54_info __initdata = {	pixclock:	171521,		bpp:		16,	xres:		320,		yres:		240,	hsync_len:	5,		vsync_len:	1,	left_margin:	61,		upper_margin:	3,	right_margin:	9,		lower_margin:	0,	sync:		FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,	lccr0:		LCCR0_Color | LCCR0_Sngl | LCCR0_Act,	lccr3:		LCCR3_OutEnH | LCCR3_PixRsEdg | LCCR3_ACBsDiv(2),};#elsestatic struct sa1100fb_mach_info pal_info __initdata = {	pixclock:	67797,		bpp:		16,	xres:		640,		yres:		512,	hsync_len:	64,		vsync_len:	6,	left_margin:	125,		upper_margin:	70,

⌨️ 快捷键说明

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