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

📄 pm2fb.c

📁 S3C44B0X下的LCD (framebuffer)驱动资料与相关代码
💻 C
📖 第 1 页 / 共 4 页
字号:
					simple_strtoul(r, &q, 0);					if (r == q) break;				}				if (i < 3) w = 0;			}			if (w) {				for (r = q; *r && (*r < '0' || *r > '9'); r++);				h = simple_strtoul(r, &q, 0);				if (r == q) w = 0;			}			if (w == 640 && h == 480) w = 0;			if (w) {				for (i=0; user_mode[i].name[0] &&					  (w != user_mode[i].par.width ||					   h != user_mode[i].par.height); i++);				if (user_mode[i].name[0])					memcpy(&p->current_par, &user_mode[i].par, sizeof(user_mode[i].par));			}		}	}#else	if (pm2fb_options.flags & OPTF_VIRTUAL) {		p->regions.rg_base = __pa(pci_resource_start(pci->dev, 0));		p->regions.fb_base = __pa(pci_resource_start(pci->dev, 1));	}	else {		p->regions.rg_base = pci_resource_start(pci->dev, 0);		p->regions.fb_base = pci_resource_start(pci->dev, 1);	}#endif#ifdef PM2FB_BE_APERTURE	p->regions.rg_base += PM2_REGS_SIZE;#endif	if ((m=MMAP(p->regions.rg_base, PM2_REGS_SIZE))) {		pci->mem_control=RD32(m, PM2R_MEM_CONTROL);		pci->boot_address=RD32(m, PM2R_BOOT_ADDRESS);		pci->mem_config=RD32(m, PM2R_MEM_CONFIG);		switch (pci->mem_config & PM2F_MEM_CONFIG_RAM_MASK) {			case PM2F_MEM_BANKS_1:				p->regions.fb_size=0x200000;				break;			case PM2F_MEM_BANKS_2:				p->regions.fb_size=0x400000;				break;			case PM2F_MEM_BANKS_3:				p->regions.fb_size=0x600000;				break;			case PM2F_MEM_BANKS_4:				p->regions.fb_size=0x800000;				break;		}		p->memclock=CVPPC_MEMCLOCK;		UNMAP(m, PM2_REGS_SIZE);		return 1;	}	DPRINTK("MMAP() failed.\n");	return 0;}static void pm2pci_init(struct pm2fb_info* p) {	struct pm2pci_par* pci=&p->board_par.pci;	WAIT_FIFO(p, 3);	pm2_WR(p, PM2R_MEM_CONTROL, pci->mem_control);	pm2_WR(p, PM2R_BOOT_ADDRESS, pci->boot_address);	DEFW();	pm2_WR(p, PM2R_MEM_CONFIG, pci->mem_config);}#endif /* CONFIG_FB_PM2_PCI *//*************************************************************************** * Console hw acceleration ***************************************************************************/static int pm2fb_blank(int blank_mode, struct fb_info_gen* info) {	struct pm2fb_info* i=(struct pm2fb_info* )info;	u32 video;	if (!i->current_par_valid)		return 1;	video=i->current_par.video;	if (blank_mode>0) {		switch (blank_mode-1) {			case VESA_NO_BLANKING:		/* FIXME */				video=video&~(PM2F_VIDEO_ENABLE);				break;			case VESA_HSYNC_SUSPEND:				video=video&~(PM2F_HSYNC_MASK|						PM2F_BLANK_LOW);				break;			case VESA_VSYNC_SUSPEND:				video=video&~(PM2F_VSYNC_MASK|						PM2F_BLANK_LOW);				break;			case VESA_POWERDOWN:				video=video&~(PM2F_VSYNC_MASK|						PM2F_HSYNC_MASK|						PM2F_BLANK_LOW);				break;		}	}	WAIT_FIFO(i, 1);	pm2_WR(i, PM2R_VIDEO_CONTROL, video);	return 0;}static int pm2fb_pan_display(const struct fb_var_screeninfo* var,					struct fb_info_gen* info) {	struct pm2fb_info* i=(struct pm2fb_info* )info;	if (!i->current_par_valid)		return -EINVAL;	i->current_par.base=to3264(var->yoffset*i->current_par.width+				var->xoffset, i->current_par.depth, 1);	WAIT_FIFO(i, 1);	pm2_WR(i, PM2R_SCREEN_BASE, i->current_par.base);	return 0;}static void pm2fb_pp_bmove(struct display* p, int sy, int sx,				int dy, int dx, int height, int width) {	if (fontwidthlog(p)) {		sx=sx<<fontwidthlog(p);		dx=dx<<fontwidthlog(p);		width=width<<fontwidthlog(p);	}	else {		sx=sx*fontwidth(p);		dx=dx*fontwidth(p);		width=width*fontwidth(p);	}	sy=sy*fontheight(p);	dy=dy*fontheight(p);	height=height*fontheight(p);	pm2fb_pp_copy((struct pm2fb_info* )p->fb_info, sx, sy, dx,							dy, width, height);}static void pm2fb_bmove(struct display* p, int sy, int sx,				int dy, int dx, int height, int width) {	if (fontwidthlog(p)) {		sx=sx<<fontwidthlog(p);		dx=dx<<fontwidthlog(p);		width=width<<fontwidthlog(p);	}	else {		sx=sx*fontwidth(p);		dx=dx*fontwidth(p);		width=width*fontwidth(p);	}	sy=sy*fontheight(p);	dy=dy*fontheight(p);	height=height*fontheight(p);	pm2fb_block_op((struct pm2fb_info* )p->fb_info, 1, sx, sy, dx, dy,							width, height, 0);}#ifdef FBCON_HAS_CFB8static void pm2fb_clear8(struct vc_data* conp, struct display* p,				int sy, int sx, int height, int width) {	u32 c;	sx=sx*fontwidth(p);	width=width*fontwidth(p);	sy=sy*fontheight(p);	height=height*fontheight(p);	c=attr_bgcol_ec(p, conp);	c|=c<<8;	c|=c<<16;	pm2fb_block_op((struct pm2fb_info* )p->fb_info, 0, 0, 0, sx, sy,							width, height, c);}static void pm2fb_clear_margins8(struct vc_data* conp, struct display* p,							int bottom_only) {	u32 c;	u32 sx;	u32 sy;	c=attr_bgcol_ec(p, conp);	c|=c<<8;	c|=c<<16;	sx=conp->vc_cols*fontwidth(p);	sy=conp->vc_rows*fontheight(p);	if (!bottom_only)		pm2fb_block_op((struct pm2fb_info* )p->fb_info, 0, 0, 0,			sx, 0, (p->var.xres-sx), p->var.yres_virtual, c);	pm2fb_block_op((struct pm2fb_info* )p->fb_info, 0, 0, 0,				0, p->var.yoffset+sy, sx, p->var.yres-sy, c);}static struct display_switch pm2_cfb8 = {	setup:		fbcon_cfb8_setup,	bmove:		pm2fb_pp_bmove,#ifdef __alpha__	/* Not sure why, but this works and the other does not. */	/* Also, perhaps we need a separate routine to wait for the	   blitter to stop before doing this? */	/* In addition, maybe we need to do this for 16 and 32 bit depths? */	clear:		fbcon_cfb8_clear,#else	clear:		pm2fb_clear8,#endif	putc:		fbcon_cfb8_putc,	putcs:		fbcon_cfb8_putcs,	revc:		fbcon_cfb8_revc,	cursor:		pm2fb_cursor,	set_font:	pm2fb_set_font,	clear_margins:	pm2fb_clear_margins8,	fontwidthmask:	FONTWIDTH(4)|FONTWIDTH(8)|FONTWIDTH(12)|FONTWIDTH(16) };#endif /* FBCON_HAS_CFB8 */#ifdef FBCON_HAS_CFB16static void pm2fb_clear16(struct vc_data* conp, struct display* p,				int sy, int sx, int height, int width) {	u32 c;	sx=sx*fontwidth(p);	width=width*fontwidth(p);	sy=sy*fontheight(p);	height=height*fontheight(p);	c=((u16 *)p->dispsw_data)[attr_bgcol_ec(p, conp)];	c|=c<<16;	pm2fb_block_op((struct pm2fb_info* )p->fb_info, 0, 0, 0, sx, sy,							width, height, c);}static void pm2fb_clear_margins16(struct vc_data* conp, struct display* p,							int bottom_only) {	u32 c;	u32 sx;	u32 sy;	c = ((u16 *)p->dispsw_data)[attr_bgcol_ec(p, conp)];	c|=c<<16;	sx=conp->vc_cols*fontwidth(p);	sy=conp->vc_rows*fontheight(p);	if (!bottom_only)		pm2fb_block_op((struct pm2fb_info* )p->fb_info, 0, 0, 0,			sx, 0, (p->var.xres-sx), p->var.yres_virtual, c);	pm2fb_block_op((struct pm2fb_info* )p->fb_info, 0, 0, 0,				0, p->var.yoffset+sy, sx, p->var.yres-sy, c);}static struct display_switch pm2_cfb16 = {	setup:		fbcon_cfb16_setup,	bmove:		pm2fb_pp_bmove,	clear:		pm2fb_clear16,	putc:		fbcon_cfb16_putc,	putcs:		fbcon_cfb16_putcs,	revc:		fbcon_cfb16_revc,	cursor:		pm2fb_cursor,	set_font:	pm2fb_set_font,	clear_margins:	pm2fb_clear_margins16,	fontwidthmask:	FONTWIDTH(4)|FONTWIDTH(8)|FONTWIDTH(12)|FONTWIDTH(16)};#endif /* FBCON_HAS_CFB16 */#ifdef FBCON_HAS_CFB24/* * fast fill for 24bpp works only when red==green==blue */static void pm2fb_clear24(struct vc_data* conp, struct display* p,				int sy, int sx, int height, int width) {	struct pm2fb_info* i=(struct pm2fb_info* )p->fb_info;	u32 c;	c=attr_bgcol_ec(p, conp);	if (		i->palette[c].red==i->palette[c].green &&			i->palette[c].green==i->palette[c].blue) {		c=((u32 *)p->dispsw_data)[c];		c|=(c&0xff0000)<<8;		sx=sx*fontwidth(p);		width=width*fontwidth(p);		sy=sy*fontheight(p);		height=height*fontheight(p);		pm2fb_block_op(i, 0, 0, 0, sx, sy, width, height, c);	}	else		fbcon_cfb24_clear(conp, p, sy, sx, height, width);}static void pm2fb_clear_margins24(struct vc_data* conp, struct display* p,							int bottom_only) {	struct pm2fb_info* i=(struct pm2fb_info* )p->fb_info;	u32 c;	u32 sx;	u32 sy;	c=attr_bgcol_ec(p, conp);	if (		i->palette[c].red==i->palette[c].green &&			i->palette[c].green==i->palette[c].blue) {		c=((u32 *)p->dispsw_data)[c];		c|=(c&0xff0000)<<8;		sx=conp->vc_cols*fontwidth(p);		sy=conp->vc_rows*fontheight(p);		if (!bottom_only)		pm2fb_block_op(i, 0, 0, 0, sx, 0, (p->var.xres-sx),							p->var.yres_virtual, c);		pm2fb_block_op(i, 0, 0, 0, 0, p->var.yoffset+sy,						sx, p->var.yres-sy, c);	}	else		fbcon_cfb24_clear_margins(conp, p, bottom_only);}static struct display_switch pm2_cfb24 = {	setup:		fbcon_cfb24_setup,	bmove:		pm2fb_bmove,	clear:		pm2fb_clear24,	putc:		fbcon_cfb24_putc,	putcs:		fbcon_cfb24_putcs,	revc:		fbcon_cfb24_revc,	cursor:		pm2fb_cursor,	set_font:	pm2fb_set_font,	clear_margins:	pm2fb_clear_margins24,	fontwidthmask:	FONTWIDTH(4)|FONTWIDTH(8)|FONTWIDTH(12)|FONTWIDTH(16)};#endif /* FBCON_HAS_CFB24 */#ifdef FBCON_HAS_CFB32static void pm2fb_clear32(struct vc_data* conp, struct display* p,				int sy, int sx, int height, int width) {	u32 c;	sx=sx*fontwidth(p);	width=width*fontwidth(p);	sy=sy*fontheight(p);	height=height*fontheight(p);	c=((u32 *)p->dispsw_data)[attr_bgcol_ec(p, conp)];	pm2fb_block_op((struct pm2fb_info* )p->fb_info, 0, 0, 0, sx, sy,							width, height, c);}static void pm2fb_clear_margins32(struct vc_data* conp, struct display* p,							int bottom_only) {	u32 c;	u32 sx;	u32 sy;	c = ((u32 *)p->dispsw_data)[attr_bgcol_ec(p, conp)];	sx=conp->vc_cols*fontwidth(p);	sy=conp->vc_rows*fontheight(p);	if (!bottom_only)		pm2fb_block_op((struct pm2fb_info* )p->fb_info, 0, 0, 0,			sx, 0, (p->var.xres-sx), p->var.yres_virtual, c);	pm2fb_block_op((struct pm2fb_info* )p->fb_info, 0, 0, 0,				0, p->var.yoffset+sy, sx, p->var.yres-sy, c);}static struct display_switch pm2_cfb32 = {	setup:		fbcon_cfb32_setup,	bmove:		pm2fb_bmove,	clear:		pm2fb_clear32,	putc:		fbcon_cfb32_putc,	putcs:		fbcon_cfb32_putcs,	revc:		fbcon_cfb32_revc,	cursor:		pm2fb_cursor,	set_font:	pm2fb_set_font,	clear_margins:	pm2fb_clear_margins32,	fontwidthmask:	FONTWIDTH(4)|FONTWIDTH(8)|FONTWIDTH(12)|FONTWIDTH(16)};#endif /* FBCON_HAS_CFB32 *//*************************************************************************** * Framebuffer functions ***************************************************************************/static void pm2fb_detect(void) {}static int pm2fb_encode_fix(struct fb_fix_screeninfo* fix,			const void* par, struct fb_info_gen* info) {	struct pm2fb_info* i=(struct pm2fb_info* )info;	struct pm2fb_par* p=(struct pm2fb_par* )par;	strcpy(fix->id, permedia2_name);	fix->smem_start=i->regions.p_fb;	fix->smem_len=i->regions.fb_size;	fix->mmio_start=i->regions.p_regs;	fix->mmio_len=PM2_REGS_SIZE;	fix->accel=FB_ACCEL_3DLABS_PERMEDIA2;	fix->type=FB_TYPE_PACKED_PIXELS;	fix->visual=p->depth==8?FB_VISUAL_PSEUDOCOLOR:FB_VISUAL_TRUECOLOR;	if (i->current_par_valid)		fix->line_length=i->current_par.width*(i->current_par.depth/8);	else		fix->line_length=0;	fix->xpanstep=p->depth==24?8:64/p->depth;	fix->ypanstep=1;	fix->ywrapstep=0;	return 0;}#ifdef PM2FB_MASTER_DEBUGstatic void pm2fb_display_var(const struct fb_var_screeninfo* var) {	printk( KERN_DEBUG"- struct fb_var_screeninfo ---------------------------------------------------\n");	printk( KERN_DEBUG		"resolution: %ux%ux%u (virtual %ux%u+%u+%u)\n",			var->xres, var->yres, var->bits_per_pixel,			var->xres_virtual, var->yres_virtual,			var->xoffset, var->yoffset);	printk( KERN_DEBUG		"color: %c%c "		"R(%u,%u,%u), G(%u,%u,%u), B(%u,%u,%u), T(%u,%u,%u)\n",			var->grayscale?'G':'C', var->nonstd?'N':'S',			var->red.offset, var->red.length, var->red.msb_right,			var->green.offset, var->green.length, var->green.msb_right,			var->blue.offset, var->blue.length, var->blue.msb_right,			var->transp.offset, var->transp.length,			var->transp.msb_right);	printk( KERN_DEBUG		"timings: %ups (%u,%u)-(%u,%u)+%u+%u\n",		var->pixclock,		var->left_margin, var->upper_margin, var->right_margin,		var->lower_margin, var->hsync_len, var->vsync_len);	printk(	KERN_DEBUG		"activate %08x accel_flags %08x sync %08x vmode %08x\n",		var->activate, var->accel_flags, var->sync, var->vmode);	printk(	KERN_DEBUG"------------------------------------------------------------------------------\n");}#define pm2fb_decode_var pm2fb_wrapped_decode_var#endifstatic int pm2fb_decode_var(const struct fb_var_screeninfo* var,				void* par, struct fb_info_gen* info) {	struct pm2fb_info* i=(struct pm2fb_info* )info;	struct pm2fb_par p;	u32 xres;	int data64;	memset(&p, 0, sizeof(struct pm2fb_par));	p.width=(var->xres_virtual+7)&~7;	p.height=var->yres_virtual;	p.depth=(var->bits_per_pixel+7)&~7;	p.depth=p.depth>32?32:p.depth;	data64=p.depth>8 || i->type == PM2_TYPE_PERMEDIA2V;	xres=(var->xres+31)&~31;	if (p.width<xres+var->xoffset)		p.width=xres+var->xoffset;	if (p.height<var->yres+var->yoffset)		p.height=var->yres+var->yoffset;	if (!partprod(xres)) {		DPRINTK("width not supported: %u\n", xres);		return -EINVAL;	}	if (p.width>2047) {		DPRINTK("virtual width not supported: %u\n", p.width);		return -EINVAL;	}	if (var->yres<200) {		DPRINTK("height not supported: %u\n",						(u32 )var->yres);		return -EINVAL;	}	if (p.height<200 || p.height>2047) {		DPRINTK("virtual height not supported: %u\n", p.height);		return -EINVAL;	}	if (p.depth>32) {		DPRINTK("depth not supported: %u\n", p.depth);		return -EINVAL;	}	if (p.width*p.height*p.depth/8>i->regions.fb_size) {		DPRINTK("no memory for screen (%ux%ux%u)\n",						p.width, p.height, p.depth);		return -EINVAL;	}	p.pixclock=PICOS2KHZ(var->pixclock);	if (p.pixclock>PM2_MAX_PIXCLOCK) {		DPRINTK("pixclock too high (%uKHz)\n", p.pixclock);		return -EINVAL;	}	p.hsstart=to3264(var->right_margin, p.depth, data64);	p.hsend=p.hsstart+to3264(var->hsync_len, p.depth, data64);	p.hbend=p.hsend+to3264(var->left_margin, p.depth, data64);	p.htotal=to3264(xres, p.depth, data64)+p.hbend-1;	p.vsstart=var->lower_margin?var->lower_margin-1:0;	/* FIXME! */	p.vsend=var->lower_margin+var->vsync_len-1;	p.vbend=var->lower_margin+var->vsync_len+var->upper_margin;	p.vtotal=var->yres+p.vbend-1;	p.stride=to3264(p.width, p.depth, 1);	p.base=to3264(var->yoffset*xres+var->xoffset, p.depth, 1);	if (data64)		p.video|=PM2F_DATA_64_ENABLE;	if (var->sync & FB_SYNC_HOR_HIGH_ACT)		p.video|=PM2F_HSYNC_ACT_HIGH;	else		p.video|=PM2F_HSYNC_ACT_LOW;	if (var->sync & FB_SYNC_VERT_HIGH_ACT)		p.video|=PM2F_VSYNC_ACT_HIGH;	else		p.video|=PM2F_VSYNC_ACT_LOW;	if ((var->vmode & FB_VMODE_MASK)==FB_VMODE_INTERLACED) {		DPRINTK("interlaced not supported\n");		return -EINVAL;	}	if ((var->vmode & FB_VMODE_MASK)==FB_VMODE_DOUBLE)		p.video|=PM2F_LINE_DOUBLE;	if (var->activate==FB_ACTIVATE_NOW)		p.video|=PM2F_VIDEO_ENABLE;	*((struct pm2fb_par* )par)=p;	return 0;}#ifdef PM2FB_MASTER_DEBUG#undef pm2fb_decode_varstatic int pm2fb_decode_var(const struct fb_var_screeninfo* var,				void* par, struct fb_info_gen* info) {	int result;	result=pm2fb_wrapped_decode_var(var, par, info);	pm2fb_display_var(var);	return result;}#endifstatic int pm2fb_encode_var(struct fb_var_screeninfo* var,				const void* par, struct fb_info_gen* info) {	struct pm2fb_par* p=(struct pm2fb_par* )par;	struct fb_var_screeninfo v;	u32 base;	memset(&v, 0, sizeof(struct fb_var_screeninfo));	v.xres_virtual=p->width;	v.yres_virtual=p->height;	v.xres=(p->htotal+1)-p->hbend;	v.yres=(p->vtotal+1)-p->vbend;	v.right_margin=p->hsstart;	v.hsync_len=p->hsend-p->hsstart;	v.left_margin=p->hbend-p->hsend;	v.lower_margin=p->vsstart+1;	v.vsync_len=p->vsend-v.lower_margin+1;	v.upper_margin=p->vbend-v.lower_margin-v.vsync_len;	v.bits_per_pixel=p->depth;

⌨️ 快捷键说明

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