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

📄 imsttfb.c

📁 S3C44B0X下的LCD (framebuffer)驱动资料与相关代码
💻 C
📖 第 1 页 / 共 4 页
字号:
/* *  drivers/video/imsttfb.c -- frame buffer device for IMS TwinTurbo * *  This file is derived from the powermac console "imstt" driver: *  Copyright (C) 1997 Sigurdur Asgeirsson *  With additional hacking by Jeffrey Kuskin (jsk@mojave.stanford.edu) *  Modified by Danilo Beuche 1998 *  Some register values added by Damien Doligez, INRIA Rocquencourt *  Various cleanups by Paul Mundt (lethal@chaoticdreams.org) * *  This file was written by Ryan Nielsen (ran@krazynet.com) *  Most of the frame buffer device stuff was copied from atyfb.c * *  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/module.h>#include <linux/kernel.h>#include <linux/errno.h>#include <linux/string.h>#include <linux/mm.h>#include <linux/tty.h>#include <linux/slab.h>#include <linux/vmalloc.h>#include <linux/delay.h>#include <linux/interrupt.h>#include <linux/fb.h>#include <linux/console.h>#include <linux/selection.h>#include <linux/init.h>#include <linux/pci.h>#include <asm/io.h>#include <asm/uaccess.h>#if defined(CONFIG_PPC)#include <linux/nvram.h>#include <asm/prom.h>#include <asm/pci-bridge.h>#include <video/macmodes.h>#endif#include <video/fbcon.h>#include <video/fbcon-cfb8.h>#include <video/fbcon-cfb16.h>#include <video/fbcon-cfb24.h>#include <video/fbcon-cfb32.h>#ifndef __powerpc__#define eieio()		/* Enforce In-order Execution of I/O */#endif/* TwinTurbo (Cosmo) registers */enum {	S1SA	=  0, /* 0x00 */	S2SA	=  1, /* 0x04 */	SP	=  2, /* 0x08 */	DSA	=  3, /* 0x0C */	CNT	=  4, /* 0x10 */	DP_OCTL	=  5, /* 0x14 */	CLR	=  6, /* 0x18 */	BI	=  8, /* 0x20 */	MBC	=  9, /* 0x24 */	BLTCTL	= 10, /* 0x28 */	/* Scan Timing Generator Registers */	HES	= 12, /* 0x30 */	HEB	= 13, /* 0x34 */	HSB	= 14, /* 0x38 */	HT	= 15, /* 0x3C */	VES	= 16, /* 0x40 */	VEB	= 17, /* 0x44 */	VSB	= 18, /* 0x48 */	VT	= 19, /* 0x4C */	HCIV	= 20, /* 0x50 */	VCIV	= 21, /* 0x54 */	TCDR	= 22, /* 0x58 */	VIL	= 23, /* 0x5C */	STGCTL	= 24, /* 0x60 */	/* Screen Refresh Generator Registers */	SSR	= 25, /* 0x64 */	HRIR	= 26, /* 0x68 */	SPR	= 27, /* 0x6C */	CMR	= 28, /* 0x70 */	SRGCTL	= 29, /* 0x74 */	/* RAM Refresh Generator Registers */	RRCIV	= 30, /* 0x78 */	RRSC	= 31, /* 0x7C */	RRCR	= 34, /* 0x88 */	/* System Registers */	GIOE	= 32, /* 0x80 */	GIO	= 33, /* 0x84 */	SCR	= 35, /* 0x8C */	SSTATUS	= 36, /* 0x90 */	PRC	= 37, /* 0x94 */#if 0		/* PCI Registers */	DVID	= 0x00000000L,	SC	= 0x00000004L,	CCR	= 0x00000008L,	OG	= 0x0000000CL,	BARM	= 0x00000010L,	BARER	= 0x00000030L,#endif};/* IBM 624 RAMDAC Direct Registers */enum {	PADDRW	= 0x00,	PDATA	= 0x04,	PPMASK	= 0x08,	PADDRR	= 0x0c,	PIDXLO	= 0x10,		PIDXHI	= 0x14,		PIDXDATA= 0x18,	PIDXCTL	= 0x1c};/* IBM 624 RAMDAC Indirect Registers */enum {	CLKCTL		= 0x02,	/* (0x01) Miscellaneous Clock Control */	SYNCCTL		= 0x03,	/* (0x00) Sync Control */	HSYNCPOS	= 0x04,	/* (0x00) Horizontal Sync Position */	PWRMNGMT	= 0x05,	/* (0x00) Power Management */	DACOP		= 0x06,	/* (0x02) DAC Operation */	PALETCTL	= 0x07,	/* (0x00) Palette Control */	SYSCLKCTL	= 0x08,	/* (0x01) System Clock Control */	PIXFMT		= 0x0a,	/* () Pixel Format  [bpp >> 3 + 2] */	BPP8		= 0x0b,	/* () 8 Bits/Pixel Control */	BPP16		= 0x0c, /* () 16 Bits/Pixel Control  [bit 1=1 for 565] */	BPP24		= 0x0d,	/* () 24 Bits/Pixel Control */	BPP32		= 0x0e,	/* () 32 Bits/Pixel Control */	PIXCTL1		= 0x10, /* (0x05) Pixel PLL Control 1 */	PIXCTL2		= 0x11,	/* (0x00) Pixel PLL Control 2 */	SYSCLKN		= 0x15,	/* () System Clock N (System PLL Reference Divider) */	SYSCLKM		= 0x16,	/* () System Clock M (System PLL VCO Divider) */	SYSCLKP		= 0x17,	/* () System Clock P */	SYSCLKC		= 0x18,	/* () System Clock C */	/*	 * Dot clock rate is 20MHz * (m + 1) / ((n + 1) * (p ? 2 * p : 1)	 * c is charge pump bias which depends on the VCO frequency  	 */	PIXM0		= 0x20,	/* () Pixel M 0 */	PIXN0		= 0x21,	/* () Pixel N 0 */	PIXP0		= 0x22,	/* () Pixel P 0 */	PIXC0		= 0x23,	/* () Pixel C 0 */	CURSCTL		= 0x30,	/* (0x00) Cursor Control */	CURSXLO		= 0x31,	/* () Cursor X position, low 8 bits */	CURSXHI		= 0x32,	/* () Cursor X position, high 8 bits */	CURSYLO		= 0x33,	/* () Cursor Y position, low 8 bits */	CURSYHI		= 0x34,	/* () Cursor Y position, high 8 bits */	CURSHOTX	= 0x35,	/* () Cursor Hot Spot X */	CURSHOTY	= 0x36,	/* () Cursor Hot Spot Y */	CURSACCTL	= 0x37,	/* () Advanced Cursor Control Enable */	CURSACATTR	= 0x38,	/* () Advanced Cursor Attribute */	CURS1R		= 0x40,	/* () Cursor 1 Red */	CURS1G		= 0x41,	/* () Cursor 1 Green */	CURS1B		= 0x42,	/* () Cursor 1 Blue */	CURS2R		= 0x43,	/* () Cursor 2 Red */	CURS2G		= 0x44,	/* () Cursor 2 Green */	CURS2B		= 0x45,	/* () Cursor 2 Blue */	CURS3R		= 0x46,	/* () Cursor 3 Red */	CURS3G		= 0x47,	/* () Cursor 3 Green */	CURS3B		= 0x48,	/* () Cursor 3 Blue */	BORDR		= 0x60,	/* () Border Color Red */	BORDG		= 0x61,	/* () Border Color Green */	BORDB		= 0x62,	/* () Border Color Blue */	MISCTL1		= 0x70,	/* (0x00) Miscellaneous Control 1 */	MISCTL2		= 0x71,	/* (0x00) Miscellaneous Control 2 */	MISCTL3		= 0x72,	/* (0x00) Miscellaneous Control 3 */	KEYCTL		= 0x78	/* (0x00) Key Control/DB Operation */};/* TI TVP 3030 RAMDAC Direct Registers */enum {	TVPADDRW = 0x00,	/* 0  Palette/Cursor RAM Write Address/Index */	TVPPDATA = 0x04,	/* 1  Palette Data RAM Data */	TVPPMASK = 0x08,	/* 2  Pixel Read-Mask */	TVPPADRR = 0x0c,	/* 3  Palette/Cursor RAM Read Address */	TVPCADRW = 0x10,	/* 4  Cursor/Overscan Color Write Address */	TVPCDATA = 0x14,	/* 5  Cursor/Overscan Color Data */				/* 6  reserved */	TVPCADRR = 0x1c,	/* 7  Cursor/Overscan Color Read Address */				/* 8  reserved */	TVPDCCTL = 0x24,	/* 9  Direct Cursor Control */	TVPIDATA = 0x28,	/* 10 Index Data */	TVPCRDAT = 0x2c,	/* 11 Cursor RAM Data */	TVPCXPOL = 0x30,	/* 12 Cursor-Position X LSB */	TVPCXPOH = 0x34,	/* 13 Cursor-Position X MSB */	TVPCYPOL = 0x38,	/* 14 Cursor-Position Y LSB */	TVPCYPOH = 0x3c,	/* 15 Cursor-Position Y MSB */};/* TI TVP 3030 RAMDAC Indirect Registers */enum {	TVPIRREV = 0x01,	/* Silicon Revision [RO] */	TVPIRICC = 0x06,	/* Indirect Cursor Control 	(0x00) */	TVPIRBRC = 0x07,	/* Byte Router Control 	(0xe4) */	TVPIRLAC = 0x0f,	/* Latch Control 		(0x06) */	TVPIRTCC = 0x18,	/* True Color Control  	(0x80) */	TVPIRMXC = 0x19,	/* Multiplex Control		(0x98) */	TVPIRCLS = 0x1a,	/* Clock Selection		(0x07) */	TVPIRPPG = 0x1c,	/* Palette Page		(0x00) */	TVPIRGEC = 0x1d,	/* General Control 		(0x00) */	TVPIRMIC = 0x1e,	/* Miscellaneous Control	(0x00) */	TVPIRPLA = 0x2c,	/* PLL Address */	TVPIRPPD = 0x2d,	/* Pixel Clock PLL Data */	TVPIRMPD = 0x2e,	/* Memory Clock PLL Data */	TVPIRLPD = 0x2f,	/* Loop Clock PLL Data */	TVPIRCKL = 0x30,	/* Color-Key Overlay Low */	TVPIRCKH = 0x31,	/* Color-Key Overlay High */	TVPIRCRL = 0x32,	/* Color-Key Red Low */	TVPIRCRH = 0x33,	/* Color-Key Red High */	TVPIRCGL = 0x34,	/* Color-Key Green Low */	TVPIRCGH = 0x35,	/* Color-Key Green High */	TVPIRCBL = 0x36,	/* Color-Key Blue Low */	TVPIRCBH = 0x37,	/* Color-Key Blue High */	TVPIRCKC = 0x38,	/* Color-Key Control 		(0x00) */	TVPIRMLC = 0x39,	/* MCLK/Loop Clock Control	(0x18) */	TVPIRSEN = 0x3a,	/* Sense Test			(0x00) */	TVPIRTMD = 0x3b,	/* Test Mode Data */	TVPIRRML = 0x3c,	/* CRC Remainder LSB [RO] */	TVPIRRMM = 0x3d,	/* CRC Remainder MSB [RO] */	TVPIRRMS = 0x3e,	/* CRC  Bit Select [WO] */	TVPIRDID = 0x3f,	/* Device ID [RO] 		(0x30) */	TVPIRRES = 0xff		/* Software Reset [WO] */};struct initvalues {	__u8 addr, value;};static struct initvalues ibm_initregs[] __initdata = {	{ CLKCTL,	0x21 },	{ SYNCCTL,	0x00 },	{ HSYNCPOS,	0x00 },	{ PWRMNGMT,	0x00 },	{ DACOP,	0x02 },	{ PALETCTL,	0x00 },	{ SYSCLKCTL,	0x01 },	/*	 * Note that colors in X are correct only if all video data is	 * passed through the palette in the DAC.  That is, "indirect	 * color" must be configured.  This is the case for the IBM DAC	 * used in the 2MB and 4MB cards, at least.	 */	{ BPP8,		0x00 },	{ BPP16,	0x01 },	{ BPP24,	0x00 },	{ BPP32,	0x00 },	{ PIXCTL1,	0x05 },	{ PIXCTL2,	0x00 },	{ SYSCLKN,	0x08 },	{ SYSCLKM,	0x4f },	{ SYSCLKP,	0x00 },	{ SYSCLKC,	0x00 },	{ CURSCTL,	0x00 },	{ CURSACCTL,	0x01 },	{ CURSACATTR,	0xa8 },	{ CURS1R,	0xff },	{ CURS1G,	0xff },	{ CURS1B,	0xff },	{ CURS2R,	0xff },	{ CURS2G,	0xff },	{ CURS2B,	0xff },	{ CURS3R,	0xff },	{ CURS3G,	0xff },	{ CURS3B,	0xff },	{ BORDR,	0xff },	{ BORDG,	0xff },	{ BORDB,	0xff },	{ MISCTL1,	0x01 },	{ MISCTL2,	0x45 },	{ MISCTL3,	0x00 },	{ KEYCTL,	0x00 }};static struct initvalues tvp_initregs[] __initdata = {	{ TVPIRICC,	0x00 },	{ TVPIRBRC,	0xe4 },	{ TVPIRLAC,	0x06 },	{ TVPIRTCC,	0x80 },	{ TVPIRMXC,	0x4d },	{ TVPIRCLS,	0x05 },	{ TVPIRPPG,	0x00 },	{ TVPIRGEC,	0x00 },	{ TVPIRMIC,	0x08 },	{ TVPIRCKL,	0xff },	{ TVPIRCKH,	0xff },	{ TVPIRCRL,	0xff },	{ TVPIRCRH,	0xff },	{ TVPIRCGL,	0xff },	{ TVPIRCGH,	0xff },	{ TVPIRCBL,	0xff },	{ TVPIRCBH,	0xff },	{ TVPIRCKC,	0x00 },	{ TVPIRPLA,	0x00 },	{ TVPIRPPD,	0xc0 },	{ TVPIRPPD,	0xd5 },	{ TVPIRPPD,	0xea },	{ TVPIRPLA,	0x00 },	{ TVPIRMPD,	0xb9 },	{ TVPIRMPD,	0x3a },	{ TVPIRMPD,	0xb1 },	{ TVPIRPLA,	0x00 },	{ TVPIRLPD,	0xc1 },	{ TVPIRLPD,	0x3d },	{ TVPIRLPD,	0xf3 },};struct imstt_regvals {	__u32 pitch;	__u16 hes, heb, hsb, ht, ves, veb, vsb, vt, vil;	__u8 pclk_m, pclk_n, pclk_p;	/* Values of the tvp which change depending on colormode x resolution */	__u8 mlc[3];	/* Memory Loop Config 0x39 */	__u8 lckl_p[3];	/* P value of LCKL PLL */};struct imstt_cursor {	struct timer_list timer;	int enable;	int on;	int vbl_cnt;	int blink_rate;	__u16 x, y, width, height;};struct fb_info_imstt {	struct fb_info info;	struct fb_fix_screeninfo fix;	struct display disp;	struct display_switch dispsw;	union {#ifdef FBCON_HAS_CFB16		__u16 cfb16[16];#endif#ifdef FBCON_HAS_CFB24		__u32 cfb24[16];#endif#ifdef FBCON_HAS_CFB32		__u32 cfb32[16];#endif	} fbcon_cmap;	struct {		__u8 red, green, blue;	} palette[256];	struct imstt_regvals init;	struct imstt_cursor cursor;	unsigned long frame_buffer_phys;	unsigned long board_size;	__u8 *frame_buffer;	unsigned long dc_regs_phys;	__u32 *dc_regs;	unsigned long cmap_regs_phys;	__u8 *cmap_regs;	__u32 total_vram;	__u32 ramdac;};enum {	IBM = 0,	TVP = 1};#define INIT_BPP		8#define INIT_XRES		640#define INIT_YRES		480#define CURSOR_BLINK_RATE	20#define CURSOR_DRAW_DELAY	2static int currcon = 0;static int inverse = 0;static char fontname[40] __initdata = { 0 };static char curblink __initdata = 1;static char noaccel __initdata = 0;#if defined(CONFIG_PPC)static signed char init_vmode __initdata = VMODE_NVRAM;static signed char init_cmode __initdata = CMODE_NVRAM;#endifstatic struct imstt_regvals tvp_reg_init_2 = {	512,	0x0002, 0x0006, 0x0026, 0x0028, 0x0003, 0x0016, 0x0196, 0x0197, 0x0196,	0xec, 0x2a, 0xf3,	{ 0x3c, 0x3b, 0x39 }, { 0xf3, 0xf3, 0xf3 }};static struct imstt_regvals tvp_reg_init_6 = {	640,	0x0004, 0x0009, 0x0031, 0x0036, 0x0003, 0x002a, 0x020a, 0x020d, 0x020a,	0xef, 0x2e, 0xb2,	{ 0x39, 0x39, 0x38 }, { 0xf3, 0xf3, 0xf3 }};static struct imstt_regvals tvp_reg_init_12 = {	800,	0x0005, 0x000e, 0x0040, 0x0042, 0x0003, 0x018, 0x270, 0x271, 0x270,	0xf6, 0x2e, 0xf2,	{ 0x3a, 0x39, 0x38 }, { 0xf3, 0xf3, 0xf3 }};static struct imstt_regvals tvp_reg_init_13 = {	832,	0x0004, 0x0011, 0x0045, 0x0048, 0x0003, 0x002a, 0x029a, 0x029b, 0x0000,	0xfe, 0x3e, 0xf1,	{ 0x39, 0x38, 0x38 }, { 0xf3, 0xf3, 0xf2 }};static struct imstt_regvals tvp_reg_init_17 = {	1024,	0x0006, 0x0210, 0x0250, 0x0053, 0x1003, 0x0021, 0x0321, 0x0324, 0x0000,	0xfc, 0x3a, 0xf1,	{ 0x39, 0x38, 0x38 }, { 0xf3, 0xf3, 0xf2 }};static struct imstt_regvals tvp_reg_init_18 = {	1152,  	0x0009, 0x0011, 0x059, 0x5b, 0x0003, 0x0031, 0x0397, 0x039a, 0x0000, 	0xfd, 0x3a, 0xf1,	{ 0x39, 0x38, 0x38 }, { 0xf3, 0xf3, 0xf2 }};static struct imstt_regvals tvp_reg_init_19 = {	1280,	0x0009, 0x0016, 0x0066, 0x0069, 0x0003, 0x0027, 0x03e7, 0x03e8, 0x03e7,	0xf7, 0x36, 0xf0,	{ 0x38, 0x38, 0x38 }, { 0xf3, 0xf2, 0xf1 }};static struct imstt_regvals tvp_reg_init_20 = {	1280,	0x0009, 0x0018, 0x0068, 0x006a, 0x0003, 0x0029, 0x0429, 0x042a, 0x0000,	0xf0, 0x2d, 0xf0,	{ 0x38, 0x38, 0x38 }, { 0xf3, 0xf2, 0xf1 }};/* * PCI driver prototypes */static int imsttfb_probe(struct pci_dev *pdev, const struct pci_device_id *ent);static void imsttfb_remove(struct pci_dev *pdev);static __u32getclkMHz (struct fb_info_imstt *p){	__u32 clk_m, clk_n, clk_p;	clk_m = p->init.pclk_m;	clk_n = p->init.pclk_n;	clk_p = p->init.pclk_p;	return 20 * (clk_m + 1) / ((clk_n + 1) * (clk_p ? 2 * clk_p : 1));}static voidsetclkMHz (struct fb_info_imstt *p, __u32 MHz){	__u32 clk_m, clk_n, clk_p, x, stage, spilled;	clk_m = clk_n = clk_p = 0;	stage = spilled = 0;	for (;;) {		switch (stage) {			case 0:				clk_m++;				break;			case 1:				clk_n++;				break;		}		x = 20 * (clk_m + 1) / ((clk_n + 1) * (clk_p ? 2 * clk_p : 1));		if (x == MHz)			break;		if (x > MHz) {			spilled = 1;			stage = 1;		} else if (spilled && x < MHz) {			stage = 0;		}	}	p->init.pclk_m = clk_m;	p->init.pclk_n = clk_n;	p->init.pclk_p = clk_p;}static struct imstt_regvals *compute_imstt_regvals_ibm (struct fb_info_imstt *p, int xres, int yres){	struct imstt_regvals *init = &p->init;	__u32 MHz, hes, heb, veb, htp, vtp;	switch (xres) {		case 640:			hes = 0x0008; heb = 0x0012; veb = 0x002a; htp = 10; vtp = 2;			MHz = 30 /* .25 */ ;			break;		case 832:			hes = 0x0005; heb = 0x0020; veb = 0x0028; htp = 8; vtp = 3;			MHz = 57 /* .27_ */ ;			break;		case 1024:			hes = 0x000a; heb = 0x001c; veb = 0x0020; htp = 8; vtp = 3;			MHz = 80;

⌨️ 快捷键说明

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