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

📄 leofb.c

📁 S3C44B0X下的LCD (framebuffer)驱动资料与相关代码
💻 C
📖 第 1 页 / 共 2 页
字号:
/* $Id: leofb.c,v 1.14 2001/10/16 05:44:44 davem Exp $ * leofb.c: Leo (ZX) 24/8bit frame buffer driver * * Copyright (C) 1996-1999 Jakub Jelinek (jj@ultra.linux.cz) * Copyright (C) 1997 Michal Rehacek (Michal.Rehacek@st.mff.cuni.cz) */#include <linux/module.h>#include <linux/sched.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/init.h>#include <linux/selection.h>#include <video/sbusfb.h>#include <asm/io.h>#define LEO_OFF_LC_SS0_KRN	0x00200000UL#define LEO_OFF_LC_SS0_USR	0x00201000UL#define LEO_OFF_LC_SS1_KRN	0x01200000UL#define LEO_OFF_LC_SS1_USR	0x01201000UL#define LEO_OFF_LD_SS0		0x00400000UL#define LEO_OFF_LD_SS1		0x01400000UL#define LEO_OFF_LD_GBL		0x00401000UL#define LEO_OFF_LX_KRN		0x00600000UL#define LEO_OFF_LX_CURSOR	0x00601000UL#define LEO_OFF_SS0		0x00800000UL#define LEO_OFF_SS1		0x01800000UL#define LEO_OFF_UNK		0x00602000UL#define LEO_OFF_UNK2		0x00000000UL#define LEO_CUR_ENABLE		0x00000080#define LEO_CUR_UPDATE		0x00000030#define LEO_CUR_PROGRESS	0x00000006#define LEO_CUR_UPDATECMAP	0x00000003#define LEO_CUR_TYPE_MASK	0x00000000#define LEO_CUR_TYPE_IMAGE	0x00000020#define LEO_CUR_TYPE_CMAP	0x00000050struct leo_cursor {	u8		xxx0[16];	volatile u32	cur_type;	volatile u32	cur_misc;	volatile u32	cur_cursxy;	volatile u32	cur_data;};#define LEO_KRN_TYPE_CLUT0	0x00001000#define LEO_KRN_TYPE_CLUT1	0x00001001#define LEO_KRN_TYPE_CLUT2	0x00001002#define LEO_KRN_TYPE_WID	0x00001003#define LEO_KRN_TYPE_UNK	0x00001006#define LEO_KRN_TYPE_VIDEO	0x00002003#define LEO_KRN_TYPE_CLUTDATA	0x00004000#define LEO_KRN_CSR_ENABLE	0x00000008#define LEO_KRN_CSR_PROGRESS	0x00000004#define LEO_KRN_CSR_UNK		0x00000002#define LEO_KRN_CSR_UNK2	0x00000001struct leo_lx_krn {	volatile u32	krn_type;	volatile u32	krn_csr;	volatile u32	krn_value;};struct leo_lc_ss0_krn {	volatile u32 	misc;	u8		xxx0[0x800-4];	volatile u32	rev;};struct leo_lc_ss0_usr {	volatile u32	csr;	volatile u32	addrspace;	volatile u32 	fontmsk;	volatile u32	fontt;	volatile u32	extent;	volatile u32	src;	u32		dst;	volatile u32	copy;	volatile u32	fill;};struct leo_lc_ss1_krn {	u8	unknown;};struct leo_lc_ss1_usr {	u8	unknown;};struct leo_ld {	u8		xxx0[0xe00];	volatile u32	csr;	volatile u32	wid;	volatile u32	wmask;	volatile u32	widclip;	volatile u32	vclipmin;	volatile u32	vclipmax;	volatile u32	pickmin;	/* SS1 only */	volatile u32	pickmax;	/* SS1 only */	volatile u32	fg;	volatile u32	bg;	volatile u32	src;		/* Copy/Scroll (SS0 only) */	volatile u32	dst;		/* Copy/Scroll/Fill (SS0 only) */	volatile u32	extent;		/* Copy/Scroll/Fill size (SS0 only) */	u32		xxx1[3];	volatile u32	setsem;		/* SS1 only */	volatile u32	clrsem;		/* SS1 only */	volatile u32	clrpick;	/* SS1 only */	volatile u32	clrdat;		/* SS1 only */	volatile u32	alpha;		/* SS1 only */	u8		xxx2[0x2c];	volatile u32	winbg;	volatile u32	planemask;	volatile u32	rop;	volatile u32	z;	volatile u32	dczf;		/* SS1 only */	volatile u32	dczb;		/* SS1 only */	volatile u32	dcs;		/* SS1 only */	volatile u32	dczs;		/* SS1 only */	volatile u32	pickfb;		/* SS1 only */	volatile u32	pickbb;		/* SS1 only */	volatile u32	dcfc;		/* SS1 only */	volatile u32	forcecol;	/* SS1 only */	volatile u32	door[8];	/* SS1 only */	volatile u32	pick[5];	/* SS1 only */};#define LEO_SS1_MISC_ENABLE	0x00000001#define LEO_SS1_MISC_STEREO	0x00000002struct leo_ld_ss1 {	u8		xxx0[0xef4];	volatile u32	ss1_misc;};struct leo_ld_gbl {	u8	unknown;};static struct sbus_mmap_map leo_mmap_map[] = {	{ LEO_SS0_MAP,		LEO_OFF_SS0,		0x800000	},	{ LEO_LC_SS0_USR_MAP,	LEO_OFF_LC_SS0_USR,	0x1000		},	{ LEO_LD_SS0_MAP,	LEO_OFF_LD_SS0,		0x1000		},	{ LEO_LX_CURSOR_MAP,	LEO_OFF_LX_CURSOR,	0x1000		},	{ LEO_SS1_MAP,		LEO_OFF_SS1,		0x800000	},	{ LEO_LC_SS1_USR_MAP,	LEO_OFF_LC_SS1_USR,	0x1000		},	{ LEO_LD_SS1_MAP,	LEO_OFF_LD_SS1,		0x1000		},	{ LEO_UNK_MAP,		LEO_OFF_UNK,		0x1000		},	{ LEO_LX_KRN_MAP,	LEO_OFF_LX_KRN,		0x1000		},	{ LEO_LC_SS0_KRN_MAP,	LEO_OFF_LC_SS0_KRN,	0x1000		},	{ LEO_LC_SS1_KRN_MAP,	LEO_OFF_LC_SS1_KRN,	0x1000		},	{ LEO_LD_GBL_MAP,	LEO_OFF_LD_GBL,		0x1000		},	{ LEO_UNK2_MAP,		LEO_OFF_UNK2,		0x100000	},	{ 0,			0,			0	  	}};static void leo_setup(struct display *p){	p->next_line = 8192;	p->next_plane = 0;}static void leo_clear(struct vc_data *conp, struct display *p, int sy, int sx,		      int height, int width){	struct fb_info_sbusfb *fb = (struct fb_info_sbusfb *)p->fb_info;	register struct leo_lc_ss0_usr *us = fb->s.leo.lc_ss0_usr;	register struct leo_ld *ss = (struct leo_ld *) fb->s.leo.ld_ss0;	unsigned long flags;	int x, y, w, h;	int i;	spin_lock_irqsave(&fb->lock, flags);	do {		i = sbus_readl(&us->csr);	} while (i & 0x20000000);	sbus_writel((attr_bgcol_ec(p,conp)<<24), &ss->fg);	if (fontheightlog(p)) {		y = sy << fontheightlog(p); h = height << fontheightlog(p);	} else {		y = sy * fontheight(p); h = height * fontheight(p);	}	if (fontwidthlog(p)) {		x = sx << fontwidthlog(p); w = width << fontwidthlog(p);	} else {		x = sx * fontwidth(p); w = width * fontwidth(p);	}	sbus_writel((w - 1) | ((h - 1) << 11), &us->extent);	sbus_writel((x + fb->x_margin) | ((y + fb->y_margin) << 11) | 0x80000000,		    &us->fill);	spin_unlock_irqrestore(&fb->lock, flags);}static void leo_fill(struct fb_info_sbusfb *fb, struct display *p, int s,		     int count, unsigned short *boxes){	int i;	register struct leo_lc_ss0_usr *us = fb->s.leo.lc_ss0_usr;	register struct leo_ld *ss = (struct leo_ld *) fb->s.leo.ld_ss0;	unsigned long flags;		spin_lock_irqsave(&fb->lock, flags);	sbus_writel((attr_bgcol(p,s)<<24), &ss->fg);	while (count-- > 0) {		do {			i = sbus_readl(&us->csr);		} while (i & 0x20000000);		sbus_writel((boxes[2] - boxes[0] - 1) | 			    ((boxes[3] - boxes[1] - 1) << 11),			    &us->extent);		sbus_writel(boxes[0] | (boxes[1] << 11) | 0x80000000,			    &us->fill);		boxes += 4;	}	spin_unlock_irqrestore(&fb->lock, flags);}static void leo_putc(struct vc_data *conp, struct display *p, int c, int yy, int xx){	struct fb_info_sbusfb *fb = (struct fb_info_sbusfb *)p->fb_info;	register struct leo_lc_ss0_usr *us = fb->s.leo.lc_ss0_usr;	register struct leo_ld *ss = (struct leo_ld *) fb->s.leo.ld_ss0;	unsigned long flags;	int i, x, y;	u8 *fd;	u32 *u;	spin_lock_irqsave(&fb->lock, flags);	if (fontheightlog(p)) {		y = yy << (fontheightlog(p) + 11);		i = (c & p->charmask) << fontheightlog(p);	} else {		y = (yy * fontheight(p)) << 11;		i = (c & p->charmask) * fontheight(p);	}	if (fontwidth(p) <= 8)		fd = p->fontdata + i;	else		fd = p->fontdata + (i << 1);	if (fontwidthlog(p))		x = xx << fontwidthlog(p);	else		x = xx * fontwidth(p);	do {		i = sbus_readl(&us->csr);	} while (i & 0x20000000);	sbus_writel(attr_fgcol(p,c) << 24, &ss->fg);	sbus_writel(attr_bgcol(p,c) << 24, &ss->bg);	sbus_writel(0xFFFFFFFF<<(32-fontwidth(p)),		    &us->fontmsk);	u = ((u32 *)p->screen_base) + y + x;	if (fontwidth(p) <= 8) {		for (i = 0; i < fontheight(p); i++, u += 2048) {			u32 val = *fd++ << 24;			sbus_writel(val, u);		}	} else {		for (i = 0; i < fontheight(p); i++, u += 2048) {			u32 val = *(u16 *)fd << 16;			sbus_writel(val, u);			fd += 2;		}	}	spin_unlock_irqrestore(&fb->lock, flags);}static void leo_putcs(struct vc_data *conp, struct display *p, const unsigned short *s,		      int count, int yy, int xx){	struct fb_info_sbusfb *fb = (struct fb_info_sbusfb *)p->fb_info;	register struct leo_lc_ss0_usr *us = fb->s.leo.lc_ss0_usr;	register struct leo_ld *ss = (struct leo_ld *) fb->s.leo.ld_ss0;	unsigned long flags;	int i, x, y;	u8 *fd1, *fd2, *fd3, *fd4;	u16 c;	u32 *u;	spin_lock_irqsave(&fb->lock, flags);	do {		i = sbus_readl(&us->csr);	} while (i & 0x20000000);	c = scr_readw(s);	sbus_writel(attr_fgcol(p, c) << 24, &ss->fg);	sbus_writel(attr_bgcol(p, c) << 24, &ss->bg);	sbus_writel(0xFFFFFFFF<<(32-fontwidth(p)), &us->fontmsk);	if (fontwidthlog(p))		x = (xx << fontwidthlog(p));	else		x = xx * fontwidth(p);	if (fontheightlog(p))		y = yy << (fontheightlog(p) + 11);	else		y = (yy * fontheight(p)) << 11;	u = ((u32 *)p->screen_base) + y + x;	if (fontwidth(p) <= 8) {		sbus_writel(0xFFFFFFFF<<(32-4*fontwidth(p)), &us->fontmsk);		x = 4*fontwidth(p) - fontheight(p)*2048;		while (count >= 4) {			count -= 4;			if (fontheightlog(p)) {				fd1 = p->fontdata + ((scr_readw(s++) & p->charmask) << fontheightlog(p));				fd2 = p->fontdata + ((scr_readw(s++) & p->charmask) << fontheightlog(p));				fd3 = p->fontdata + ((scr_readw(s++) & p->charmask) << fontheightlog(p));				fd4 = p->fontdata + ((scr_readw(s++) & p->charmask) << fontheightlog(p));			} else {				fd1 = p->fontdata + ((scr_readw(s++) & p->charmask) * fontheight(p));				fd2 = p->fontdata + ((scr_readw(s++) & p->charmask) * fontheight(p));				fd3 = p->fontdata + ((scr_readw(s++) & p->charmask) * fontheight(p));				fd4 = p->fontdata + ((scr_readw(s++) & p->charmask) * fontheight(p));			}			if (fontwidth(p) == 8) {				for (i = 0; i < fontheight(p); i++, u += 2048) {					u32 val;					val = ((u32)*fd4++) | ((((u32)*fd3++) | ((((u32)*fd2++) | (((u32)*fd1++) 						<< 8)) << 8)) << 8);					sbus_writel(val, u);				}				u += x;			} else {				for (i = 0; i < fontheight(p); i++, u += 2048) {					u32 val;					val = (((u32)*fd4++) | ((((u32)*fd3++) | ((((u32)*fd2++) | (((u32)*fd1++) 						<< fontwidth(p))) << fontwidth(p))) << fontwidth(p))) << (24 - 3 * fontwidth(p));					sbus_writel(val, u);				}				u += x;			}		}	} else {		sbus_writel(0xFFFFFFFF<<(32-2*fontwidth(p)), &us->fontmsk);		x = 2*fontwidth(p) - fontheight(p)*2048;		while (count >= 2) {			count -= 2;			if (fontheightlog(p)) {				fd1 = p->fontdata + ((scr_readw(s++) & p->charmask) << (fontheightlog(p) + 1));				fd2 = p->fontdata + ((scr_readw(s++) & p->charmask) << (fontheightlog(p) + 1));			} else {				fd1 = p->fontdata + (((scr_readw(s++) & p->charmask) * fontheight(p)) << 1);				fd2 = p->fontdata + (((scr_readw(s++) & p->charmask) * fontheight(p)) << 1);			}			for (i = 0; i < fontheight(p); i++, u += 2048) {				u32 val;				val = ((((u32)*(u16 *)fd1) << fontwidth(p)) | ((u32)*(u16 *)fd2)) << (16 - fontwidth(p));				sbus_writel(val, u);				fd1 += 2; fd2 += 2;			}			u += x;		}	}	sbus_writel(0xFFFFFFFF<<(32-fontwidth(p)), &us->fontmsk);	x = fontwidth(p) - fontheight(p)*2048;	while (count) {		count--;		if (fontheightlog(p))			i = ((scr_readw(s++) & p->charmask) << fontheightlog(p));		else			i = ((scr_readw(s++) & p->charmask) * fontheight(p));		if (fontwidth(p) <= 8) {			fd1 = p->fontdata + i;			for (i = 0; i < fontheight(p); i++, u += 2048) {				u32 val = *fd1++ << 24;				sbus_writel(val, u);			}		} else {			fd1 = p->fontdata + (i << 1);

⌨️ 快捷键说明

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