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

📄 macfb.c

📁 S3C44B0X下的LCD (framebuffer)驱动资料与相关代码
💻 C
📖 第 1 页 / 共 3 页
字号:
/* macfb.c: Generic framebuffer for Macs whose colourmaps/modes we   don't know how to set *//* (c) 1999 David Huggins-Daines <dhd@debian.org>   Primarily based on vesafb.c, by Gerd Knorr   (c) 1998 Gerd Knorr <kraxel@cs.tu-berlin.de>   Also uses information and code from:      The original macfb.c from Linux/mac68k 2.0, by Alan Cox, Juergen   Mellinger, Mikael Forselius, Michael Schmitz, and others.   valkyriefb.c, by Martin Costabel, Kevin Schoedel, Barry Nathan, Dan   Jacobowitz, Paul Mackerras, Fabio Riccardi, and Geert Uytterhoeven.      This code is free software.  You may copy, modify, and distribute   it subject to the terms and conditions of the GNU General Public   License, version 2, or any later version, at your convenience. */#include <linux/module.h>#include <linux/kernel.h>#include <linux/sched.h>#include <linux/errno.h>#include <linux/string.h>#include <linux/mm.h>#include <linux/tty.h>#include <linux/slab.h>#include <linux/delay.h>#include <linux/nubus.h>#include <linux/init.h>#include <linux/fb.h>#include <asm/setup.h>#include <asm/bootinfo.h>#include <asm/uaccess.h>#include <asm/pgtable.h>#include <asm/irq.h>#include <asm/macintosh.h>#include <asm/io.h>#include <asm/machw.h>#include <video/fbcon.h>#include <video/fbcon-mfb.h>#include <video/fbcon-cfb2.h>#include <video/fbcon-cfb4.h>#include <video/fbcon-cfb8.h>#include <video/fbcon-cfb16.h>#include <video/fbcon-cfb24.h>#include <video/fbcon-cfb32.h>#if defined(FBCON_HAS_CFB8) || defined(FBCON_HAS_CFB4) || defined(FBCON_HAS_CFB2)/* Common DAC base address for the LC, RBV, Valkyrie, and IIvx */#define DAC_BASE 0x50f24000/* Some addresses for the DAFB */#define DAFB_BASE 0xf9800200/* Address for the built-in Civic framebuffer in Quadra AVs */#define CIVIC_BASE 0x50f30800	/* Only tested on 660AV! *//* GSC (Gray Scale Controller) base address */#define GSC_BASE 0x50F20000/* CSC (Color Screen Controller) base address */#define CSC_BASE 0x50F20000static int (*macfb_setpalette) (unsigned int regno, unsigned int red,				unsigned int green, unsigned int blue) = NULL;static int valkyrie_setpalette (unsigned int regno, unsigned int red,				unsigned int green, unsigned int blue);static int dafb_setpalette (unsigned int regno, unsigned int red,			    unsigned int green, unsigned int blue);static int rbv_setpalette (unsigned int regno, unsigned int red,			   unsigned int green, unsigned int blue);static int mdc_setpalette (unsigned int regno, unsigned int red,			   unsigned int green, unsigned int blue);static int toby_setpalette (unsigned int regno, unsigned int red,			    unsigned int green, unsigned int blue);static int civic_setpalette (unsigned int regno, unsigned int red,			     unsigned int green, unsigned int blue);static int csc_setpalette (unsigned int regno, unsigned int red,			     unsigned int green, unsigned int blue);static volatile struct {	unsigned char addr;	/* Note: word-aligned */	char pad[3];	unsigned char lut;} *valkyrie_cmap_regs;static volatile struct {	unsigned char addr;	unsigned char lut;} *v8_brazil_cmap_regs;static volatile struct {	unsigned char addr;	char pad1[3]; /* word aligned */	unsigned char lut;	char pad2[3]; /* word aligned */	unsigned char cntl; /* a guess as to purpose */} *rbv_cmap_regs;static volatile struct {	unsigned long reset;	unsigned long pad1[3];	unsigned char pad2[3];	unsigned char lut;} *dafb_cmap_regs;static volatile struct {	unsigned char addr;	/* OFFSET: 0x00 */	unsigned char pad1[15];	unsigned char lut;	/* OFFSET: 0x10 */	unsigned char pad2[15];	unsigned char status;	/* OFFSET: 0x20 */	unsigned char pad3[7];	unsigned long vbl_addr;	/* OFFSET: 0x28 */	unsigned int  status2;	/* OFFSET: 0x2C */} *civic_cmap_regs;static volatile struct {	char    pad1[0x40];        unsigned char	clut_waddr;	/* 0x40 */        char    pad2;        unsigned char	clut_data;	/* 0x42 */        char	pad3[0x3];        unsigned char	clut_raddr;	/* 0x46 */} *csc_cmap_regs;/* We will leave these the way they are for the time being */struct mdc_cmap_regs {	char pad1[0x200200];	unsigned char addr;	char pad2[6];	unsigned char lut;};struct toby_cmap_regs {	char pad1[0x90018];	unsigned char lut; /* TFBClutWDataReg, offset 0x90018 */	char pad2[3];	unsigned char addr; /* TFBClutAddrReg, offset 0x9001C */};struct jet_cmap_regs {	char pad1[0xe0e000];	unsigned char addr;	unsigned char lut;};#endif#define PIXEL_TO_MM(a)	(((a)*10)/28)	/* width in mm at 72 dpi */	static unsigned long video_base;static int   video_size;static char* video_vbase;        /* mapped *//* mode */static int  video_bpp;static int  video_width;static int  video_height;static int  video_type = FB_TYPE_PACKED_PIXELS;static int  video_visual;static int  video_linelength;static int  video_cmap_len;static int  video_slot = 0;static struct fb_var_screeninfo macfb_defined={	0,0,0,0,	/* W,H, W, H (virtual) load xres,xres_virtual*/	0,0,		/* virtual -> visible no offset */	8,		/* depth -> load bits_per_pixel */	0,		/* greyscale ? */	{0,0,0},	/* R */	{0,0,0},	/* G */	{0,0,0},	/* B */	{0,0,0},	/* transparency */	0,		/* standard pixel format */	FB_ACTIVATE_NOW,	-1, -1,	FB_ACCEL_NONE,	/* The only way to accelerate a mac is .. */	0L,0L,0L,0L,0L,	0L,0L,0,	/* No sync info */	FB_VMODE_NONINTERLACED,	{0,0,0,0,0,0}};static struct display disp;static struct fb_info fb_info;static struct { u_short blue, green, red, pad; } palette[256];static 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;static int             inverse   = 0;static int             vidtest   = 0;static int             currcon   = 0;static int macfb_update_var(int con, struct fb_info *info){	return 0;}static int macfb_get_fix(struct fb_fix_screeninfo *fix, int con,			 struct fb_info *info){	memset(fix, 0, sizeof(struct fb_fix_screeninfo));	strcpy(fix->id, "Mac Generic");	fix->smem_start = video_base;	fix->smem_len = video_size;	fix->type = video_type;	fix->visual = video_visual;	fix->xpanstep = 0;	fix->ypanstep = 0;	fix->line_length=video_linelength;	return 0;}static int macfb_get_var(struct fb_var_screeninfo *var, int con,			 struct fb_info *info){	if(con==-1)		memcpy(var, &macfb_defined, sizeof(struct fb_var_screeninfo));	else		*var=fb_display[con].var;	return 0;}static void macfb_set_disp(int con){	struct fb_fix_screeninfo fix;	struct display *display;		if (con >= 0)		display = &fb_display[con];	else		display = &disp;	/* used during initialization */	macfb_get_fix(&fix, con, &fb_info);	memset(display, 0, sizeof(struct display));	display->screen_base = video_vbase;	display->visual = fix.visual;	display->type = fix.type;	display->type_aux = fix.type_aux;	display->ypanstep = fix.ypanstep;	display->ywrapstep = fix.ywrapstep;	display->line_length = fix.line_length;	display->next_line = fix.line_length;	display->can_soft_blank = 0;	display->inverse = inverse;	display->scrollmode = SCROLL_YREDRAW;	macfb_get_var(&display->var, -1, &fb_info);	switch (video_bpp) {#ifdef FBCON_HAS_MFB	case 1:		display->dispsw = &fbcon_mfb;		break;#endif#ifdef FBCON_HAS_CFB2	case 2:		display->dispsw = &fbcon_cfb2;		break;#endif#ifdef FBCON_HAS_CFB4	case 4:		display->dispsw = &fbcon_cfb4;		break;#endif#ifdef FBCON_HAS_CFB8	case 8:		display->dispsw = &fbcon_cfb8;		break;#endif#ifdef FBCON_HAS_CFB16	case 15:	case 16:		display->dispsw = &fbcon_cfb16;		display->dispsw_data = fbcon_cmap.cfb16;		break;#endif#ifdef FBCON_HAS_CFB24	case 24:		display->dispsw = &fbcon_cfb24;		display->dispsw_data = fbcon_cmap.cfb24;		break;#endif#ifdef FBCON_HAS_CFB32	case 32:		display->dispsw = &fbcon_cfb32;		display->dispsw_data = fbcon_cmap.cfb32;		break;#endif	default:		display->dispsw = &fbcon_dummy;		return;	}}static int macfb_set_var(struct fb_var_screeninfo *var, int con,			 struct fb_info *info){	static int first = 1;	if (var->xres           != macfb_defined.xres           ||	    var->yres           != macfb_defined.yres           ||	    var->xres_virtual   != macfb_defined.xres_virtual   ||	    var->yres_virtual   != macfb_defined.yres           ||	    var->xoffset                                        ||	    var->bits_per_pixel != macfb_defined.bits_per_pixel ||	    var->nonstd) {		if (first) {			printk("macfb does not support changing the video mode\n");			first = 0;		}		return -EINVAL;	}	if ((var->activate & FB_ACTIVATE_MASK) == FB_ACTIVATE_TEST)		return 0;	if (var->yoffset)		return -EINVAL;	return 0;}#if defined(FBCON_HAS_CFB8) || defined(FBCON_HAS_CFB4) || defined(FBCON_HAS_CFB2)static int valkyrie_setpalette (unsigned int regno, unsigned int red,				unsigned int green, unsigned int blue){	unsigned long flags;		red >>= 8;	green >>= 8;	blue >>= 8;	save_flags(flags);	cli();		/* tell clut which address to fill */	nubus_writeb(regno, &valkyrie_cmap_regs->addr);	nop();	/* send one color channel at a time */	nubus_writeb(red, &valkyrie_cmap_regs->lut);	nop();	nubus_writeb(green, &valkyrie_cmap_regs->lut);	nop();	nubus_writeb(blue, &valkyrie_cmap_regs->lut);	restore_flags(flags);	return 0;}/* Unlike the Valkyrie, the DAFB cannot set individual colormap   registers.  Therefore, we do what the MacOS driver does (no   kidding!) and simply set them one by one until we hit the one we   want. */static int dafb_setpalette (unsigned int regno, unsigned int red,			    unsigned int green, unsigned int blue){	/* FIXME: really, really need to use ioremap() here,           phys_to_virt() doesn't work anymore */	static int lastreg = -1;	unsigned long flags;		red >>= 8;	green >>= 8;	blue >>= 8;	save_flags(flags);	cli();		/* fbcon will set an entire colourmap, but X won't.  Hopefully	   this should accomodate both of them */	if (regno != lastreg+1) {		int i;				/* Stab in the dark trying to reset the CLUT pointer */		nubus_writel(0, &dafb_cmap_regs->reset);		nop();				/* Loop until we get to the register we want */		for (i = 0; i < regno; i++) {			nubus_writeb(palette[i].red >> 8, &dafb_cmap_regs->lut);			nop();			nubus_writeb(palette[i].green >> 8, &dafb_cmap_regs->lut);			nop();			nubus_writeb(palette[i].blue >> 8, &dafb_cmap_regs->lut);			nop();		}	}			nubus_writeb(red, &dafb_cmap_regs->lut);	nop();	nubus_writeb(green, &dafb_cmap_regs->lut);	nop();	nubus_writeb(blue, &dafb_cmap_regs->lut);		restore_flags(flags);

⌨️ 快捷键说明

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