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

📄 mbxfb.c

📁 Linux环境下视频显示卡设备的驱动程序源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
	switch (alpha->overlay_colorkey_mode) {	case MBXFB_COLORKEY_DISABLED:		break;	case MBXFB_COLORKEY_PREVIOUS:		vscadr |= VSCADR_COLKEY_EN;		break;	case MBXFB_COLORKEY_CURRENT:		vscadr |= VSCADR_COLKEY_EN | VSCADR_COLKEYSRC;		break;	default:		return -EINVAL;	}	switch (alpha->overlay_blend_mode) {	case MBXFB_ALPHABLEND_NONE:		vscadr |= VSCADR_BLEND_NONE;		break;	case MBXFB_ALPHABLEND_GLOBAL:		vscadr |= VSCADR_BLEND_GLOB;		break;	case MBXFB_ALPHABLEND_PIXEL:		vscadr |= VSCADR_BLEND_PIX;		break;	default:		return -EINVAL;	}	switch (alpha->graphics_colorkey_mode) {	case MBXFB_COLORKEY_DISABLED:		break;	case MBXFB_COLORKEY_PREVIOUS:		gscadr |= GSCADR_COLKEY_EN;		break;	case MBXFB_COLORKEY_CURRENT:		gscadr |= GSCADR_COLKEY_EN | GSCADR_COLKEYSRC;		break;	default:		return -EINVAL;	}	switch (alpha->graphics_blend_mode) {	case MBXFB_ALPHABLEND_NONE:		gscadr |= GSCADR_BLEND_NONE;		break;	case MBXFB_ALPHABLEND_GLOBAL:		gscadr |= GSCADR_BLEND_GLOB;		break;	case MBXFB_ALPHABLEND_PIXEL:		gscadr |= GSCADR_BLEND_PIX;		break;	default:		return -EINVAL;	}	write_reg_dly(vbbase, VBBASE);	write_reg_dly(gbbase, GBBASE);	write_reg_dly(vcmsk, VCMSK);	write_reg_dly(gdrctrl, GDRCTRL);	write_reg_dly(gscadr, GSCADR);	write_reg_dly(vscadr, VSCADR);	return 0;}static int mbxfb_ioctl(struct fb_info *info, unsigned int cmd,				unsigned long arg){	struct mbxfb_overlaySetup	setup;	struct mbxfb_planeorder 	porder;	struct mbxfb_alphaCtl 		alpha;	struct mbxfb_reg			reg;	int res;	__u32 tmp;	switch (cmd)	{		case MBXFB_IOCX_OVERLAY:			if (copy_from_user(&setup, (void __user*)arg,						sizeof(struct mbxfb_overlaySetup)))				return -EFAULT;			res = mbxfb_setupOverlay(&setup);			if (res)				return res;			if (copy_to_user((void __user*)arg, &setup,						sizeof(struct mbxfb_overlaySetup)))				return -EFAULT;			return 0;		case MBXFB_IOCS_PLANEORDER:			if (copy_from_user(&porder, (void __user*)arg,					sizeof(struct mbxfb_planeorder)))			return -EFAULT;			return mbxfb_ioctl_planeorder(&porder);		case MBXFB_IOCS_ALPHA:			if (copy_from_user(&alpha, (void __user*)arg,					sizeof(struct mbxfb_alphaCtl)))			return -EFAULT;			return mbxfb_ioctl_alphactl(&alpha);		case MBXFB_IOCS_REG:			if (copy_from_user(&reg, (void __user*)arg,						sizeof(struct mbxfb_reg)))				return -EFAULT;			if (reg.addr >= 0x10000) /* regs are from 0x3fe0000 to 0x3feffff */				return -EINVAL;			tmp = readl(virt_base_2700 + reg.addr);			tmp &= ~reg.mask;			tmp |= reg.val & reg.mask;			writel(tmp, virt_base_2700 + reg.addr);			return 0;		case MBXFB_IOCX_REG:			if (copy_from_user(&reg, (void __user*)arg,						sizeof(struct mbxfb_reg)))				return -EFAULT;			if (reg.addr >= 0x10000)	/* regs are from 0x3fe0000 to 0x3feffff */				return -EINVAL;			reg.val = readl(virt_base_2700 + reg.addr);			if (copy_to_user((void __user*)arg, &reg,						sizeof(struct mbxfb_reg)))				return -EFAULT;			return 0;	}	return -EINVAL;}static struct fb_ops mbxfb_ops = {	.owner = THIS_MODULE,	.fb_check_var = mbxfb_check_var,	.fb_set_par = mbxfb_set_par,	.fb_setcolreg = mbxfb_setcolreg,	.fb_fillrect = cfb_fillrect,	.fb_copyarea = cfb_copyarea,	.fb_imageblit = cfb_imageblit,	.fb_blank = mbxfb_blank,	.fb_ioctl = mbxfb_ioctl,};/*  Enable external SDRAM controller. Assume that all clocks are active  by now.*/static void __devinit setup_memc(struct fb_info *fbi){	unsigned long tmp;	int i;	/* FIXME: use platfrom specific parameters */	/* setup SDRAM controller */	write_reg_dly((LMCFG_LMC_DS | LMCFG_LMC_TS | LMCFG_LMD_TS |		LMCFG_LMA_TS),	       LMCFG);	write_reg_dly(LMPWR_MC_PWR_ACT, LMPWR);	/* setup SDRAM timings */	write_reg_dly((Lmtim_Tras(7) | Lmtim_Trp(3) | Lmtim_Trcd(3) |		Lmtim_Trc(9) | Lmtim_Tdpl(2)),	       LMTIM);	/* setup SDRAM refresh rate */	write_reg_dly(0xc2b, LMREFRESH);	/* setup SDRAM type parameters */	write_reg_dly((LMTYPE_CASLAT_3 | LMTYPE_BKSZ_2 | LMTYPE_ROWSZ_11 |		LMTYPE_COLSZ_8),	       LMTYPE);	/* enable memory controller */	write_reg_dly(LMPWR_MC_PWR_ACT, LMPWR);	/* perform dummy reads */	for ( i = 0; i < 16; i++ ) {		tmp = readl(fbi->screen_base);	}}static void enable_clocks(struct fb_info *fbi){	/* enable clocks */	write_reg_dly(SYSCLKSRC_PLL_2, SYSCLKSRC);	write_reg_dly(PIXCLKSRC_PLL_1, PIXCLKSRC);	write_reg_dly(0x00000000, CLKSLEEP);	/* PLL output = (Frefclk * M) / (N * 2^P )	 *	 * M: 0x17, N: 0x3, P: 0x0 == 100 Mhz!	 * M: 0xb, N: 0x1, P: 0x1 == 71 Mhz	 * */	write_reg_dly((Core_Pll_M(0xb) | Core_Pll_N(0x1) | Core_Pll_P(0x1) |		CORE_PLL_EN),	       COREPLL);	write_reg_dly((Disp_Pll_M(0x1b) | Disp_Pll_N(0x7) | Disp_Pll_P(0x1) |		DISP_PLL_EN),	       DISPPLL);	write_reg_dly(0x00000000, VOVRCLK);	write_reg_dly(PIXCLK_EN, PIXCLK);	write_reg_dly(MEMCLK_EN, MEMCLK);	write_reg_dly(0x00000001, M24CLK);	write_reg_dly(0x00000001, MBXCLK);	write_reg_dly(SDCLK_EN, SDCLK);	write_reg_dly(0x00000001, PIXCLKDIV);}static void __devinit setup_graphics(struct fb_info *fbi){	unsigned long gsctrl;	unsigned long vscadr;	gsctrl = GSCTRL_GAMMA_EN | Gsctrl_Width(fbi->var.xres) |		Gsctrl_Height(fbi->var.yres);	switch (fbi->var.bits_per_pixel) {	case 16:		if (fbi->var.green.length == 5)			gsctrl |= GSCTRL_GPIXFMT_ARGB1555;		else			gsctrl |= GSCTRL_GPIXFMT_RGB565;		break;	case 24:		gsctrl |= GSCTRL_GPIXFMT_RGB888;		break;	case 32:		gsctrl |= GSCTRL_GPIXFMT_ARGB8888;		break;	}	write_reg_dly(gsctrl, GSCTRL);	write_reg_dly(0x00000000, GBBASE);	write_reg_dly(0x00ffffff, GDRCTRL);	write_reg_dly((GSCADR_STR_EN | Gscadr_Gbase_Adr(0x6000)), GSCADR);	write_reg_dly(0x00000000, GPLUT);	vscadr = readl(VSCADR);	vscadr &= ~(FMsk(VSCADR_BLEND_POS) | FMsk(VSCADR_BLEND_M));	vscadr |= VSCADR_BLEND_VID | VSCADR_BLEND_NONE;	write_reg_dly(vscadr, VSCADR);}static void __devinit setup_display(struct fb_info *fbi){	unsigned long dsctrl = 0;	dsctrl = DSCTRL_BLNK_POL;	if (fbi->var.sync & FB_SYNC_HOR_HIGH_ACT)		dsctrl |= DSCTRL_HS_POL;	if (fbi->var.sync & FB_SYNC_VERT_HIGH_ACT)		dsctrl |= DSCTRL_VS_POL;	write_reg_dly(dsctrl, DSCTRL);	write_reg_dly(0xd0303010, DMCTRL);	write_reg_dly((readl(DSCTRL) | DSCTRL_SYNCGEN_EN), DSCTRL);}static void __devinit enable_controller(struct fb_info *fbi){	u32 svctrl, shctrl;	write_reg_dly(SYSRST_RST, SYSRST);	/* setup a timeout, raise drive strength */	write_reg_dly(0xffffff0c, SYSCFG);	enable_clocks(fbi);	setup_memc(fbi);	setup_graphics(fbi);	setup_display(fbi);	shctrl = readl(SHCTRL);	shctrl &= ~(FMsk(SHCTRL_HINITIAL));	shctrl |= Shctrl_Hinitial(4<<11);	writel(shctrl, SHCTRL);	svctrl = Svctrl_Initial1(1<<10) | Svctrl_Initial2(1<<10);	writel(svctrl, SVCTRL);	writel(SPOCTRL_H_SC_BP | SPOCTRL_V_SC_BP | SPOCTRL_VORDER_4TAP			, SPOCTRL);	/* Those coefficients are good for scaling up. For scaling	 * down, the application has to calculate them. */	write_reg(0xff000100, VSCOEFF0);	write_reg(0xfdfcfdfe, VSCOEFF1);	write_reg(0x170d0500, VSCOEFF2);	write_reg(0x3d372d22, VSCOEFF3);	write_reg(0x00000040, VSCOEFF4);	write_reg(0xff010100, HSCOEFF0);	write_reg(0x00000000, HSCOEFF1);	write_reg(0x02010000, HSCOEFF2);	write_reg(0x01020302, HSCOEFF3);	write_reg(0xf9fbfe00, HSCOEFF4);	write_reg(0xfbf7f6f7, HSCOEFF5);	write_reg(0x1c110700, HSCOEFF6);	write_reg(0x3e393127, HSCOEFF7);	write_reg(0x00000040, HSCOEFF8);}#ifdef CONFIG_PM/* * Power management hooks.  Note that we won't be called from IRQ context, * unlike the blank functions above, so we may sleep. */static int mbxfb_suspend(struct platform_device *dev, pm_message_t state){	/* make frame buffer memory enter self-refresh mode */	write_reg_dly(LMPWR_MC_PWR_SRM, LMPWR);	while (LMPWRSTAT != LMPWRSTAT_MC_PWR_SRM)		; /* empty statement */	/* reset the device, since it's initial state is 'mostly sleeping' */	write_reg_dly(SYSRST_RST, SYSRST);	return 0;}static int mbxfb_resume(struct platform_device *dev){	struct fb_info *fbi = platform_get_drvdata(dev);	enable_clocks(fbi);/* 	setup_graphics(fbi); *//* 	setup_display(fbi); */	write_reg_dly((readl(DSCTRL) | DSCTRL_SYNCGEN_EN), DSCTRL);	return 0;}#else#define mbxfb_suspend	NULL#define mbxfb_resume	NULL#endif/* debugfs entries */#ifndef CONFIG_FB_MBX_DEBUG#define mbxfb_debugfs_init(x)	do {} while(0)#define mbxfb_debugfs_remove(x)	do {} while(0)#endif#define res_size(_r) (((_r)->end - (_r)->start) + 1)static int __devinit mbxfb_probe(struct platform_device *dev){	int ret;	struct fb_info *fbi;	struct mbxfb_info *mfbi;	struct mbxfb_platform_data *pdata;	dev_dbg(&dev->dev, "mbxfb_probe\n");	pdata = dev->dev.platform_data;	if (!pdata) {		dev_err(&dev->dev, "platform data is required\n");		return -EINVAL;	}	fbi = framebuffer_alloc(sizeof(struct mbxfb_info), &dev->dev);	if (fbi == NULL) {		dev_err(&dev->dev, "framebuffer_alloc failed\n");		return -ENOMEM;	}	mfbi = fbi->par;	fbi->pseudo_palette = mfbi->pseudo_palette;	if (pdata->probe)		mfbi->platform_probe = pdata->probe;	if (pdata->remove)		mfbi->platform_remove = pdata->remove;	mfbi->fb_res = platform_get_resource(dev, IORESOURCE_MEM, 0);	mfbi->reg_res = platform_get_resource(dev, IORESOURCE_MEM, 1);	if (!mfbi->fb_res || !mfbi->reg_res) {		dev_err(&dev->dev, "no resources found\n");		ret = -ENODEV;		goto err1;	}	mfbi->fb_req = request_mem_region(mfbi->fb_res->start,					  res_size(mfbi->fb_res), dev->name);	if (mfbi->fb_req == NULL) {		dev_err(&dev->dev, "failed to claim framebuffer memory\n");		ret = -EINVAL;		goto err1;	}	mfbi->fb_phys_addr = mfbi->fb_res->start;	mfbi->reg_req = request_mem_region(mfbi->reg_res->start,					   res_size(mfbi->reg_res), dev->name);	if (mfbi->reg_req == NULL) {		dev_err(&dev->dev, "failed to claim Marathon registers\n");		ret = -EINVAL;		goto err2;	}	mfbi->reg_phys_addr = mfbi->reg_res->start;	mfbi->reg_virt_addr = ioremap_nocache(mfbi->reg_phys_addr,					      res_size(mfbi->reg_req));	if (!mfbi->reg_virt_addr) {		dev_err(&dev->dev, "failed to ioremap Marathon registers\n");		ret = -EINVAL;		goto err3;	}	virt_base_2700 = (unsigned long)mfbi->reg_virt_addr;	mfbi->fb_virt_addr = ioremap_nocache(mfbi->fb_phys_addr,					     res_size(mfbi->fb_req));	if (!mfbi->reg_virt_addr) {		dev_err(&dev->dev, "failed to ioremap frame buffer\n");		ret = -EINVAL;		goto err4;	}	fbi->screen_base = (char __iomem *)(mfbi->fb_virt_addr + 0x60000);	fbi->screen_size = pdata->memsize;	fbi->fbops = &mbxfb_ops;	fbi->var = mbxfb_default;	fbi->fix = mbxfb_fix;	fbi->fix.smem_start = mfbi->fb_phys_addr + 0x60000;	fbi->fix.smem_len = pdata->memsize;	fbi->fix.line_length = mbxfb_default.xres_virtual *					mbxfb_default.bits_per_pixel / 8;	ret = fb_alloc_cmap(&fbi->cmap, 256, 0);	if (ret < 0) {		dev_err(&dev->dev, "fb_alloc_cmap failed\n");		ret = -EINVAL;		goto err5;	}	platform_set_drvdata(dev, fbi);	printk(KERN_INFO "fb%d: mbx frame buffer device\n", fbi->node);	if (mfbi->platform_probe)		mfbi->platform_probe(fbi);	enable_controller(fbi);	mbxfb_debugfs_init(fbi);	ret = register_framebuffer(fbi);	if (ret < 0) {		dev_err(&dev->dev, "register_framebuffer failed\n");		ret = -EINVAL;		goto err6;	}	return 0;err6:	fb_dealloc_cmap(&fbi->cmap);err5:	iounmap(mfbi->fb_virt_addr);err4:	iounmap(mfbi->reg_virt_addr);err3:	release_mem_region(mfbi->reg_res->start, res_size(mfbi->reg_res));err2:	release_mem_region(mfbi->fb_res->start, res_size(mfbi->fb_res));err1:	framebuffer_release(fbi);	return ret;}static int __devexit mbxfb_remove(struct platform_device *dev){	struct fb_info *fbi = platform_get_drvdata(dev);	write_reg_dly(SYSRST_RST, SYSRST);	mbxfb_debugfs_remove(fbi);	if (fbi) {		struct mbxfb_info *mfbi = fbi->par;		unregister_framebuffer(fbi);		if (mfbi) {			if (mfbi->platform_remove)				mfbi->platform_remove(fbi);			if (mfbi->fb_virt_addr)				iounmap(mfbi->fb_virt_addr);			if (mfbi->reg_virt_addr)				iounmap(mfbi->reg_virt_addr);			if (mfbi->reg_req)				release_mem_region(mfbi->reg_req->start,						   res_size(mfbi->reg_req));			if (mfbi->fb_req)				release_mem_region(mfbi->fb_req->start,						   res_size(mfbi->fb_req));		}		framebuffer_release(fbi);	}	return 0;}static struct platform_driver mbxfb_driver = {	.probe = mbxfb_probe,	.remove = mbxfb_remove,	.suspend = mbxfb_suspend,	.resume = mbxfb_resume,	.driver = {		.name = "mbx-fb",	},};int __devinit mbxfb_init(void){	return platform_driver_register(&mbxfb_driver);}static void __devexit mbxfb_exit(void){	platform_driver_unregister(&mbxfb_driver);}module_init(mbxfb_init);module_exit(mbxfb_exit);MODULE_DESCRIPTION("loadable framebuffer driver for Marathon device");MODULE_AUTHOR("Mike Rapoport, Compulab");MODULE_LICENSE("GPL");

⌨️ 快捷键说明

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