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

📄 clgenfb.c

📁 S3C44B0X下的LCD (framebuffer)驱动资料与相关代码
💻 C
📖 第 1 页 / 共 5 页
字号:
		 {0, 0, 0},	       0, 0, -1, -1, FB_ACCEL_NONE, 20000, 128, 16, 24, 2, 96, 6,     0, FB_VMODE_NONINTERLACED	 }	},	/*	   Modeline from XF86Config:	   Mode "1024x768" 80  1024 1136 1340 1432  768 770 774 805	 */	{"1024x768",		/* 1024x768, 55.8 kHz, 70 Hz, 80 MHz PixClock */		{			1024, 768, 1024, 768, 0, 0, 8, 0,			{0, 8, 0},			{0, 8, 0},			{0, 8, 0},			{0, 0, 0},	      0, 0, -1, -1, FB_ACCEL_NONE, 12500, 144, 32, 30, 2, 192, 6,     0, FB_VMODE_NONINTERLACED		}	}};#define NUM_TOTAL_MODES    ARRAY_SIZE(clgenfb_predefined)static struct fb_var_screeninfo clgenfb_default;/* *    Frame Buffer Name */static const char *clgenfb_name = "CLgen";/****************************************************************************//**** BEGIN PROTOTYPES ******************************************************//*--- Interface used by the world ------------------------------------------*/int clgenfb_init (void);int clgenfb_setup (char *options);static int clgenfb_open (struct fb_info *info, int user);static int clgenfb_release (struct fb_info *info, int user);/* function table of the above functions */static struct fb_ops clgenfb_ops = {	owner:		THIS_MODULE,	fb_open:	clgenfb_open,	fb_release:	clgenfb_release,	fb_get_fix:	fbgen_get_fix,	fb_get_var:	fbgen_get_var,	fb_set_var:	fbgen_set_var,	fb_get_cmap:	fbgen_get_cmap,	fb_set_cmap:	fbgen_set_cmap,	fb_pan_display:	fbgen_pan_display,};/*--- Hardware Specific Routines -------------------------------------------*/static void clgen_detect (void);static int clgen_encode_fix (struct fb_fix_screeninfo *fix, const void *par,			     struct fb_info_gen *info);static int clgen_decode_var (const struct fb_var_screeninfo *var, void *par,			     struct fb_info_gen *info);static int clgen_encode_var (struct fb_var_screeninfo *var, const void *par,			     struct fb_info_gen *info);static void clgen_get_par (void *par, struct fb_info_gen *info);static void clgen_set_par (const void *par, struct fb_info_gen *info);static int clgen_getcolreg (unsigned regno, unsigned *red, unsigned *green,			    unsigned *blue, unsigned *transp,			    struct fb_info *info);static int clgen_setcolreg (unsigned regno, unsigned red, unsigned green,			    unsigned blue, unsigned transp,			    struct fb_info *info);static int clgen_pan_display (const struct fb_var_screeninfo *var,			      struct fb_info_gen *info);static int clgen_blank (int blank_mode, struct fb_info_gen *info);static void clgen_set_disp (const void *par, struct display *disp,			    struct fb_info_gen *info);/* function table of the above functions */static struct fbgen_hwswitch clgen_hwswitch ={	clgen_detect,	clgen_encode_fix,	clgen_decode_var,	clgen_encode_var,	clgen_get_par,	clgen_set_par,	clgen_getcolreg,	clgen_setcolreg,	clgen_pan_display,	clgen_blank,	clgen_set_disp};/* Text console acceleration */#ifdef FBCON_HAS_CFB8static void fbcon_clgen8_bmove (struct display *p, int sy, int sx,				int dy, int dx, int height, int width);static void fbcon_clgen8_clear (struct vc_data *conp, struct display *p,				int sy, int sx, int height, int width);static struct display_switch fbcon_clgen_8 = {	setup:		fbcon_cfb8_setup,	bmove:		fbcon_clgen8_bmove,	clear:		fbcon_clgen8_clear,	putc:		fbcon_cfb8_putc,	putcs:		fbcon_cfb8_putcs,	revc:		fbcon_cfb8_revc,	clear_margins:	fbcon_cfb8_clear_margins,	fontwidthmask:	FONTWIDTH (4) | FONTWIDTH (8) | FONTWIDTH (12) | FONTWIDTH (16)};#endif#ifdef FBCON_HAS_CFB16static void fbcon_clgen16_bmove (struct display *p, int sy, int sx,				 int dy, int dx, int height, int width);static void fbcon_clgen16_clear (struct vc_data *conp, struct display *p,				 int sy, int sx, int height, int width);static struct display_switch fbcon_clgen_16 = {	setup:		fbcon_cfb16_setup,	bmove:		fbcon_clgen16_bmove,	clear:		fbcon_clgen16_clear,	putc:		fbcon_cfb16_putc,	putcs:		fbcon_cfb16_putcs,	revc:		fbcon_cfb16_revc,	clear_margins:	fbcon_cfb16_clear_margins,	fontwidthmask:	FONTWIDTH (4) | FONTWIDTH (8) | FONTWIDTH (12) | FONTWIDTH (16)};#endif#ifdef FBCON_HAS_CFB32static void fbcon_clgen32_bmove (struct display *p, int sy, int sx,				 int dy, int dx, int height, int width);static void fbcon_clgen32_clear (struct vc_data *conp, struct display *p,				 int sy, int sx, int height, int width);static struct display_switch fbcon_clgen_32 = {	setup:		fbcon_cfb32_setup,	bmove:		fbcon_clgen32_bmove,	clear:		fbcon_clgen32_clear,	putc:		fbcon_cfb32_putc,	putcs:		fbcon_cfb32_putcs,	revc:		fbcon_cfb32_revc,	clear_margins:	fbcon_cfb32_clear_margins,	fontwidthmask:	FONTWIDTH (4) | FONTWIDTH (8) | FONTWIDTH (12) | FONTWIDTH (16)};#endif/*--- Internal routines ----------------------------------------------------*/static void init_vgachip (struct clgenfb_info *fb_info);static void switch_monitor (struct clgenfb_info *fb_info, int on);static void WGen (const struct clgenfb_info *fb_info,		  int regnum, unsigned char val);static unsigned char RGen (const struct clgenfb_info *fb_info, int regnum);static void AttrOn (const struct clgenfb_info *fb_info);static void WHDR (const struct clgenfb_info *fb_info, unsigned char val);static void WSFR (struct clgenfb_info *fb_info, unsigned char val);static void WSFR2 (struct clgenfb_info *fb_info, unsigned char val);static void WClut (struct clgenfb_info *fb_info, unsigned char regnum, unsigned char red,		   unsigned char green,		   unsigned char blue);#if 0static void RClut (struct clgenfb_info *fb_info, unsigned char regnum, unsigned char *red,		   unsigned char *green,		   unsigned char *blue);#endifstatic void clgen_WaitBLT (caddr_t regbase);static void clgen_BitBLT (caddr_t regbase, u_short curx, u_short cury,			  u_short destx, u_short desty,			  u_short width, u_short height,			  u_short line_length);static void clgen_RectFill (struct clgenfb_info *fb_info, u_short x, u_short y,			    u_short width, u_short height,			    u_char color, u_short line_length);static void bestclock (long freq, long *best,		       long *nom, long *den,		       long *div, long maxfreq);#ifdef CLGEN_DEBUGstatic void clgen_dump (void);static void clgen_dbg_reg_dump (caddr_t regbase);static void clgen_dbg_print_regs (caddr_t regbase, clgen_dbg_reg_class_t reg_class,...);static void clgen_dbg_print_byte (const char *name, unsigned char val);#endif /* CLGEN_DEBUG *//*** END   PROTOTYPES ********************************************************//*****************************************************************************//*** BEGIN Interface Used by the World ***************************************/static int opencount = 0;/*--- Open /dev/fbx ---------------------------------------------------------*/static int clgenfb_open (struct fb_info *info, int user){	if (opencount++ == 0)		switch_monitor ((struct clgenfb_info *) info, 1);	return 0;}/*--- Close /dev/fbx --------------------------------------------------------*/static int clgenfb_release (struct fb_info *info, int user){	if (--opencount == 0)		switch_monitor ((struct clgenfb_info *) info, 0);	return 0;}/**** END   Interface used by the World *************************************//****************************************************************************//**** BEGIN Hardware specific Routines **************************************/static void clgen_detect (void){	DPRINTK ("ENTER\n");	DPRINTK ("EXIT\n");}static int clgen_encode_fix (struct fb_fix_screeninfo *fix, const void *par,			     struct fb_info_gen *info){	struct clgenfb_par *_par = (struct clgenfb_par *) par;	struct clgenfb_info *_info = (struct clgenfb_info *) info;	DPRINTK ("ENTER\n");	memset (fix, 0, sizeof (struct fb_fix_screeninfo));	strcpy (fix->id, clgenfb_name);	if (_info->btype == BT_GD5480) {		/* Select proper byte-swapping aperture */		switch (_par->var.bits_per_pixel) {		case 1:		case 8:			fix->smem_start = _info->fbmem_phys;			break;		case 16:			fix->smem_start = _info->fbmem_phys + 1 * MB_;			break;		case 24:		case 32:			fix->smem_start = _info->fbmem_phys + 2 * MB_;			break;		}	} else {		fix->smem_start = _info->fbmem_phys;	}	/* monochrome: only 1 memory plane */	/* 8 bit and above: Use whole memory area */	fix->smem_len = _par->var.bits_per_pixel == 1 ? _info->size / 4	    : _info->size;	fix->type = _par->type;	fix->type_aux = 0;	fix->visual = _par->visual;	fix->xpanstep = 1;	fix->ypanstep = 1;	fix->ywrapstep = 0;	fix->line_length = _par->line_length;	/* FIXME: map region at 0xB8000 if available, fill in here */	fix->mmio_start = 0;	fix->mmio_len = 0;	fix->accel = FB_ACCEL_NONE;	DPRINTK ("EXIT\n");	return 0;}/* Get a good MCLK value */static long clgen_get_mclk (long freq, int bpp, long *div){	long mclk;	assert (div != NULL);	/* Calculate MCLK, in case VCLK is high enough to require > 50MHz.	 * Assume a 64-bit data path for now.  The formula is:	 * ((B * PCLK * 2)/W) * 1.2	 * B = bytes per pixel, PCLK = pixclock, W = data width in bytes */	mclk = ((bpp / 8) * freq * 2) / 4;	mclk = (mclk * 12) / 10;	if (mclk < 50000)		mclk = 50000;	DPRINTK ("Use MCLK of %ld kHz\n", mclk);	/* Calculate value for SR1F.  Multiply by 2 so we can round up. */	mclk = ((mclk * 16) / 14318);	mclk = (mclk + 1) / 2;	DPRINTK ("Set SR1F[5:0] to 0x%lx\n", mclk);	/* Determine if we should use MCLK instead of VCLK, and if so, what we	   * should divide it by to get VCLK */	switch (freq) {	case 24751 ... 25249:		*div = 2;		DPRINTK ("Using VCLK = MCLK/2\n");		break;	case 49501 ... 50499:		*div = 1;		DPRINTK ("Using VCLK = MCLK\n");		break;	default:		*div = 0;		break;	}	return mclk;}static int clgen_decode_var (const struct fb_var_screeninfo *var, void *par,			     struct fb_info_gen *info){	long freq;	long maxclock;	int xres, hfront, hsync, hback;	int yres, vfront, vsync, vback;	int nom, den;		/* translyting from pixels->bytes */	int i;	static struct {		int xres, yres;	} modes[] = { {			1600, 1280	}, {		1280, 1024	}, {		1024, 768	},	{		800, 600	}, {		640, 480	}, {		-1, -1	}	};	struct clgenfb_par *_par = (struct clgenfb_par *) par;	struct clgenfb_info *fb_info = (struct clgenfb_info *) info;	assert (var != NULL);	assert (par != NULL);	assert (info != NULL);	DPRINTK ("ENTER\n");	DPRINTK ("Requested: %dx%dx%d\n", var->xres, var->yres, var->bits_per_pixel);	DPRINTK ("  virtual: %dx%d\n", var->xres_virtual, var->yres_virtual);	DPRINTK ("   offset: (%d,%d)\n", var->xoffset, var->yoffset);	DPRINTK ("grayscale: %d\n", var->grayscale);	memset (par, 0, sizeof (struct clgenfb_par));	_par->var = *var;	switch (var->bits_per_pixel) {	case 1:		nom = 4;		den = 8;		break;		/* 8 pixel per byte, only 1/4th of mem usable */	case 2 ... 8:		_par->var.bits_per_pixel = 8;		nom = 1;		den = 1;		break;		/* 1 pixel == 1 byte */	case 9 ... 16:		_par->var.bits_per_pixel = 16;		nom = 2;		den = 1;		break;		/* 2 bytes per pixel */	case 17 ... 24:		_par->var.bits_per_pixel = 24;		nom = 3;		den = 1;		break;		/* 3 bytes per pixel */	case 25 ... 32:		_par->var.bits_per_pixel = 32;		nom = 4;		den = 1;		break;		/* 4 bytes per pixel */	default:		printk ("clgen: mode %dx%dx%d rejected...color depth not supported.\n",			var->xres, var->yres, var->bits_per_pixel);		DPRINTK ("EXIT - EINVAL error\n");		return -EINVAL;	}	if (_par->var.xres * nom / den * _par->var.yres > fb_info->size) {		printk ("clgen: mode %dx%dx%d rejected...resolution too high to fit into video memory!\n",			var->xres, var->yres, var->bits_per_pixel);		DPRINTK ("EXIT - EINVAL error\n");		return -EINVAL;	}	/* use highest possible virtual resolution */	if (_par->var.xres_virtual == -1 &&	    _par->var.yres_virtual == -1) {		printk ("clgen: using maximum available virtual resolution\n");		for (i = 0; modes[i].xres != -1; i++) {			if (modes[i].xres * nom / den * modes[i].yres < fb_info->size / 2)				break;		}		if (modes[i].xres == -1) {			printk ("clgen: could not find a virtual resolution that fits into video memory!!\n");			DPRINTK ("EXIT - EINVAL error\n");			return -EINVAL;		}		_par->var.xres_virtual = modes[i].xres;		_par->var.yres_virtual = modes[i].yres;		printk ("clgen: virtual resolution set to maximum of %dx%d\n",			_par->var.xres_virtual, _par->var.yres_virtual);	} else if (_par->var.xres_virtual == -1) {		/* FIXME: maximize X virtual resolution only */	} else if (_par->var.yres_virtual == -1) {		/* FIXME: maximize Y virtual resolution only */	}	if (_par->var.xoffset < 0)		_par->var.xoffset = 0;	if (_par->var.yoffset < 0)		_par->var.yoffset = 0;	/* truncate xoffset and yoffset to maximum if too high */	if (_par->var.xoffset > _par->var.xres_virtual - _par->var.xres)		_par->var.xoffset = _par->var.xres_virtual - _par->var.xres - 1;	if (_par->var.yoffset > _par->var.yres_virtual - _par->var.yres)		_par->var.yoffset = _par->var.yres_virtual - _par->var.yres - 1;	switch (_par->var.bits_per_pixel) {	case 1:		_par->line_length = _par->var.xres_virtual / 8;		_par->visual = FB_VISUAL_MONO10;		break;	case 8:		_par->line_length = _par->var.xres_virtual;		_par->visual = FB_VISUAL_PSEUDOCOLOR;		_par->var.red.offset = 0;		_par->var.red.length = 6;		_par->var.green.offset = 0;		_par->var.green.length = 6;		_par->var.blue.offset = 0;		_par->var.blue.length = 6;		break;	case 16:		_par->line_length = _par->var.xres_virtual * 2;		_par->visual = FB_VISUAL_DIRECTCOLOR;		if(isPReP) {			_par->var.red.offset = 2;			_par->var.green.offset = -3;			_par->var.blue.offset = 8;		} else {			_par->var.red.offset = 10;			_par->var.green.offset = 5;

⌨️ 快捷键说明

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