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

📄 mb862xxfb.c

📁 Linux环境下视频显示卡设备的驱动程序源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
		return -ENODEV;	}	if (!par->pre_init) {		outreg(host, GC_CCF, ccf);		udelay(200);		outreg(host, GC_MMR, mmr);		udelay(10);	}	/* interrupt status */	outreg(host, GC_IST, 0);	outreg(host, GC_IMASK, GC_INT_EN);	return 0;}static int __devinit of_platform_mb862xx_probe(struct of_device *ofdev,					       const struct of_device_id *id){	struct device_node *np = ofdev->node;	struct device *dev = &ofdev->dev;	struct mb862xxfb_par *par;	struct fb_info *info;	struct resource res;	resource_size_t res_size;	unsigned long ret = -ENODEV;	if (of_address_to_resource(np, 0, &res)) {		dev_err(dev, "Invalid address\n");		return -ENXIO;	}	info = framebuffer_alloc(sizeof(struct mb862xxfb_par), dev);	if (info == NULL) {		dev_err(dev, "cannot allocate framebuffer\n");		return -ENOMEM;	}	par = info->par;	par->info = info;	par->dev = dev;	par->irq = irq_of_parse_and_map(np, 0);	if (par->irq == NO_IRQ) {		dev_err(dev, "failed to map irq\n");		ret = -ENODEV;		goto fbrel;	}	res_size = 1 + res.end - res.start;	par->res = request_mem_region(res.start, res_size, DRV_NAME);	if (par->res == NULL) {		dev_err(dev, "Cannot claim framebuffer/mmio\n");		ret = -ENXIO;		goto irqdisp;	}#if defined(CONFIG_LWMON5)	par->gc_mode = &lwmon5_gc_mode;#endif#if defined(CONFIG_SOCRATES)	par->gc_mode = &socrates_gc_mode;#endif	par->fb_base_phys = res.start;	par->mmio_base_phys = res.start + MB862XX_MMIO_BASE;	par->mmio_len = MB862XX_MMIO_SIZE;	if (par->gc_mode)		par->mapped_vram = par->gc_mode->max_vram;	else		par->mapped_vram = MB862XX_MEM_SIZE;	par->fb_base = ioremap(par->fb_base_phys, par->mapped_vram);	if (par->fb_base == NULL) {		dev_err(dev, "Cannot map framebuffer\n");		goto rel_reg;	}	par->mmio_base = ioremap(par->mmio_base_phys, par->mmio_len);	if (par->mmio_base == NULL) {		dev_err(dev, "Cannot map registers\n");		goto fb_unmap;	}	dev_dbg(dev, "fb phys 0x%llx 0x%lx\n",		(u64)par->fb_base_phys, (ulong)par->mapped_vram);	dev_dbg(dev, "mmio phys 0x%llx 0x%lx, (irq = %d)\n",		(u64)par->mmio_base_phys, (ulong)par->mmio_len, par->irq);	if (mb862xx_gdc_init(par))		goto io_unmap;	if (request_irq(par->irq, mb862xx_intr, IRQF_DISABLED,			DRV_NAME, (void *)par)) {		dev_err(dev, "Cannot request irq\n");		goto io_unmap;	}	mb862xxfb_init_fbinfo(info);	if (fb_alloc_cmap(&info->cmap, NR_PALETTE, 0) < 0) {		dev_err(dev, "Could not allocate cmap for fb_info.\n");		goto free_irq;	}	if ((info->fbops->fb_set_par)(info))		dev_err(dev, "set_var() failed on initial setup?\n");	if (register_framebuffer(info)) {		dev_err(dev, "failed to register framebuffer\n");		goto rel_cmap;	}	dev_set_drvdata(dev, info);	if (device_create_file(dev, &dev_attr_dispregs))		dev_err(dev, "Can't create sysfs regdump file\n");	return 0;rel_cmap:	fb_dealloc_cmap(&info->cmap);free_irq:	outreg(host, GC_IMASK, 0);	free_irq(par->irq, (void *)par);io_unmap:	iounmap(par->mmio_base);fb_unmap:	iounmap(par->fb_base);rel_reg:	release_mem_region(res.start, res_size);irqdisp:	irq_dispose_mapping(par->irq);fbrel:	dev_set_drvdata(dev, NULL);	framebuffer_release(info);	return ret;}static int __devexit of_platform_mb862xx_remove(struct of_device *ofdev){	struct fb_info *fbi = dev_get_drvdata(&ofdev->dev);	struct mb862xxfb_par *par = fbi->par;	resource_size_t res_size = 1 + par->res->end - par->res->start;	unsigned long reg;	dev_dbg(fbi->dev, "%s release\n", fbi->fix.id);	/* display off */	reg = inreg(disp, GC_DCM1);	reg &= ~(GC_DCM01_DEN | GC_DCM01_L0E);	outreg(disp, GC_DCM1, reg);	/* disable interrupts */	outreg(host, GC_IMASK, 0);	free_irq(par->irq, (void *)par);	irq_dispose_mapping(par->irq);	device_remove_file(&ofdev->dev, &dev_attr_dispregs);	unregister_framebuffer(fbi);	fb_dealloc_cmap(&fbi->cmap);	iounmap(par->mmio_base);	iounmap(par->fb_base);	dev_set_drvdata(&ofdev->dev, NULL);	release_mem_region(par->res->start, res_size);	framebuffer_release(fbi);	return 0;}/* * common types */static struct of_device_id __devinitdata of_platform_mb862xx_tbl[] = {	{ .compatible = "fujitsu,MB86276", },	{ .compatible = "fujitsu,lime", },	{ .compatible = "fujitsu,MB86277", },	{ .compatible = "fujitsu,mint", },	{ .compatible = "fujitsu,MB86293", },	{ .compatible = "fujitsu,MB86294", },	{ .compatible = "fujitsu,coral", },	{ /* end */ }};static struct of_platform_driver of_platform_mb862xxfb_driver = {	.owner		= THIS_MODULE,	.name		= DRV_NAME,	.match_table	= of_platform_mb862xx_tbl,	.probe		= of_platform_mb862xx_probe,	.remove		= __devexit_p(of_platform_mb862xx_remove),};#endif#if defined(CONFIG_FB_MB862XX_PCI_GDC)static int coralp_init(struct mb862xxfb_par *par){	int cn, ver;	par->host = par->mmio_base;	par->i2c = par->mmio_base + MB862XX_I2C_BASE;	par->disp = par->mmio_base + MB862XX_DISP_BASE;	par->cap = par->mmio_base + MB862XX_CAP_BASE;	par->draw = par->mmio_base + MB862XX_DRAW_BASE;	par->geo = par->mmio_base + MB862XX_GEO_BASE;	par->pio = par->mmio_base + MB862XX_PIO_BASE;	par->refclk = GC_DISP_REFCLK_400;	ver = inreg(host, GC_CID);	cn = (ver & GC_CID_CNAME_MSK) >> 8;	ver = ver & GC_CID_VERSION_MSK;	if (cn == 3) {		dev_info(par->dev, "Fujitsu Coral-%s GDC Rev.%d found\n",\			 (ver == 6) ? "P" : (ver == 8) ? "PA" : "?",			 par->pdev->revision);		outreg(host, GC_CCF, GC_CCF_CGE_166 | GC_CCF_COT_133);		udelay(200);		outreg(host, GC_MMR, GC_MMR_CORALP_EVB_VAL);		udelay(10);		/* Clear interrupt status */		outreg(host, GC_IST, 0);	} else {		return -ENODEV;	}	return 0;}static int init_dram_ctrl(struct mb862xxfb_par *par){	unsigned long i = 0;	/*	 * Set io mode first! Spec. says IC may be destroyed	 * if not set to SSTL2/LVCMOS before init.	 */	outreg(dram_ctrl, GC_DCTL_IOCONT1_IOCONT0, GC_EVB_DCTL_IOCONT1_IOCONT0);	/* DRAM init */	outreg(dram_ctrl, GC_DCTL_MODE_ADD, GC_EVB_DCTL_MODE_ADD);	outreg(dram_ctrl, GC_DCTL_SETTIME1_EMODE, GC_EVB_DCTL_SETTIME1_EMODE);	outreg(dram_ctrl, GC_DCTL_REFRESH_SETTIME2,	       GC_EVB_DCTL_REFRESH_SETTIME2);	outreg(dram_ctrl, GC_DCTL_RSV2_RSV1, GC_EVB_DCTL_RSV2_RSV1);	outreg(dram_ctrl, GC_DCTL_DDRIF2_DDRIF1, GC_EVB_DCTL_DDRIF2_DDRIF1);	outreg(dram_ctrl, GC_DCTL_RSV0_STATES, GC_EVB_DCTL_RSV0_STATES);	/* DLL reset done? */	while ((inreg(dram_ctrl, GC_DCTL_RSV0_STATES) & GC_DCTL_STATES_MSK)) {		udelay(GC_DCTL_INIT_WAIT_INTERVAL);		if (i++ > GC_DCTL_INIT_WAIT_CNT) {			dev_err(par->dev, "VRAM init failed.\n");			return -EINVAL;		}	}	outreg(dram_ctrl, GC_DCTL_MODE_ADD, GC_EVB_DCTL_MODE_ADD_AFT_RST);	outreg(dram_ctrl, GC_DCTL_RSV0_STATES, GC_EVB_DCTL_RSV0_STATES_AFT_RST);	return 0;}static int carmine_init(struct mb862xxfb_par *par){	unsigned long reg;	par->ctrl = par->mmio_base + MB86297_CTRL_BASE;	par->i2c = par->mmio_base + MB86297_I2C_BASE;	par->disp = par->mmio_base + MB86297_DISP0_BASE;	par->disp1 = par->mmio_base + MB86297_DISP1_BASE;	par->cap = par->mmio_base + MB86297_CAP0_BASE;	par->cap1 = par->mmio_base + MB86297_CAP1_BASE;	par->draw = par->mmio_base + MB86297_DRAW_BASE;	par->dram_ctrl = par->mmio_base + MB86297_DRAMCTRL_BASE;	par->wrback = par->mmio_base + MB86297_WRBACK_BASE;	par->refclk = GC_DISP_REFCLK_533;	/* warm up */	reg = GC_CTRL_CLK_EN_DRAM | GC_CTRL_CLK_EN_2D3D | GC_CTRL_CLK_EN_DISP0;	outreg(ctrl, GC_CTRL_CLK_ENABLE, reg);	/* check for engine module revision */	if (inreg(draw, GC_2D3D_REV) == GC_RE_REVISION)		dev_info(par->dev, "Fujitsu Carmine GDC Rev.%d found\n",			 par->pdev->revision);	else		goto err_init;	reg &= ~GC_CTRL_CLK_EN_2D3D;	outreg(ctrl, GC_CTRL_CLK_ENABLE, reg);	/* set up vram */	if (init_dram_ctrl(par) < 0)		goto err_init;	outreg(ctrl, GC_CTRL_INT_MASK, 0);	return 0;err_init:	outreg(ctrl, GC_CTRL_CLK_ENABLE, 0);	return -EINVAL;}static inline int mb862xx_pci_gdc_init(struct mb862xxfb_par *par){	switch (par->type) {	case BT_CORALP:		return coralp_init(par);	case BT_CARMINE:		return carmine_init(par);	default:		return -ENODEV;	}}#define CHIP_ID(id)	\	{ PCI_DEVICE(PCI_VENDOR_ID_FUJITSU_LIMITED, id) }static struct pci_device_id mb862xx_pci_tbl[] __devinitdata = {	/* MB86295/MB86296 */	CHIP_ID(PCI_DEVICE_ID_FUJITSU_CORALP),	CHIP_ID(PCI_DEVICE_ID_FUJITSU_CORALPA),	/* MB86297 */	CHIP_ID(PCI_DEVICE_ID_FUJITSU_CARMINE),	{ 0, }};MODULE_DEVICE_TABLE(pci, mb862xx_pci_tbl);static int __devinit mb862xx_pci_probe(struct pci_dev *pdev,				       const struct pci_device_id *ent){	struct mb862xxfb_par *par;	struct fb_info *info;	struct device *dev = &pdev->dev;	int ret;	ret = pci_enable_device(pdev);	if (ret < 0) {		dev_err(dev, "Cannot enable PCI device\n");		goto out;	}	info = framebuffer_alloc(sizeof(struct mb862xxfb_par), dev);	if (!info) {		dev_err(dev, "framebuffer alloc failed\n");		ret = -ENOMEM;		goto dis_dev;	}	par = info->par;	par->info = info;	par->dev = dev;	par->pdev = pdev;	par->irq = pdev->irq;	ret = pci_request_regions(pdev, DRV_NAME);	if (ret < 0) {		dev_err(dev, "Cannot reserve region(s) for PCI device\n");		goto rel_fb;	}	switch (pdev->device) {	case PCI_DEVICE_ID_FUJITSU_CORALP:	case PCI_DEVICE_ID_FUJITSU_CORALPA:		par->fb_base_phys = pci_resource_start(par->pdev, 0);		par->mapped_vram = CORALP_MEM_SIZE;		par->mmio_base_phys = par->fb_base_phys + MB862XX_MMIO_BASE;		par->mmio_len = MB862XX_MMIO_SIZE;		par->type = BT_CORALP;		break;	case PCI_DEVICE_ID_FUJITSU_CARMINE:		par->fb_base_phys = pci_resource_start(par->pdev, 2);		par->mmio_base_phys = pci_resource_start(par->pdev, 3);		par->mmio_len = pci_resource_len(par->pdev, 3);		par->mapped_vram = CARMINE_MEM_SIZE;		par->type = BT_CARMINE;		break;	default:		/* should never occur */		goto rel_reg;	}	par->fb_base = ioremap(par->fb_base_phys, par->mapped_vram);	if (par->fb_base == NULL) {		dev_err(dev, "Cannot map framebuffer\n");		goto rel_reg;	}	par->mmio_base = ioremap(par->mmio_base_phys, par->mmio_len);	if (par->mmio_base == NULL) {		dev_err(dev, "Cannot map registers\n");		ret = -EIO;		goto fb_unmap;	}	dev_dbg(dev, "fb phys 0x%llx 0x%lx\n",		(unsigned long long)par->fb_base_phys, (ulong)par->mapped_vram);	dev_dbg(dev, "mmio phys 0x%llx 0x%lx\n",		(unsigned long long)par->mmio_base_phys, (ulong)par->mmio_len);	if (mb862xx_pci_gdc_init(par))		goto io_unmap;	if (request_irq(par->irq, mb862xx_intr, IRQF_DISABLED | IRQF_SHARED,			DRV_NAME, (void *)par)) {		dev_err(dev, "Cannot request irq\n");		goto io_unmap;	}	mb862xxfb_init_fbinfo(info);	if (fb_alloc_cmap(&info->cmap, NR_PALETTE, 0) < 0) {		dev_err(dev, "Could not allocate cmap for fb_info.\n");		ret = -ENOMEM;		goto free_irq;	}	if ((info->fbops->fb_set_par)(info))		dev_err(dev, "set_var() failed on initial setup?\n");	ret = register_framebuffer(info);	if (ret < 0) {		dev_err(dev, "failed to register framebuffer\n");		goto rel_cmap;	}	pci_set_drvdata(pdev, info);	if (device_create_file(dev, &dev_attr_dispregs))		dev_err(dev, "Can't create sysfs regdump file\n");	if (par->type == BT_CARMINE)		outreg(ctrl, GC_CTRL_INT_MASK, GC_CARMINE_INT_EN);	else		outreg(host, GC_IMASK, GC_INT_EN);	return 0;rel_cmap:	fb_dealloc_cmap(&info->cmap);free_irq:	free_irq(par->irq, (void *)par);io_unmap:	iounmap(par->mmio_base);fb_unmap:	iounmap(par->fb_base);rel_reg:	pci_release_regions(pdev);rel_fb:	framebuffer_release(info);dis_dev:	pci_disable_device(pdev);out:	return ret;}static void __devexit mb862xx_pci_remove(struct pci_dev *pdev){	struct fb_info *fbi = pci_get_drvdata(pdev);	struct mb862xxfb_par *par = fbi->par;	unsigned long reg;	dev_dbg(fbi->dev, "%s release\n", fbi->fix.id);	/* display off */	reg = inreg(disp, GC_DCM1);	reg &= ~(GC_DCM01_DEN | GC_DCM01_L0E);	outreg(disp, GC_DCM1, reg);	if (par->type == BT_CARMINE) {		outreg(ctrl, GC_CTRL_INT_MASK, 0);		outreg(ctrl, GC_CTRL_CLK_ENABLE, 0);	} else {		outreg(host, GC_IMASK, 0);	}	device_remove_file(&pdev->dev, &dev_attr_dispregs);	pci_set_drvdata(pdev, NULL);	unregister_framebuffer(fbi);	fb_dealloc_cmap(&fbi->cmap);	free_irq(par->irq, (void *)par);	iounmap(par->mmio_base);	iounmap(par->fb_base);	pci_release_regions(pdev);	framebuffer_release(fbi);	pci_disable_device(pdev);}static struct pci_driver mb862xxfb_pci_driver = {	.name		= DRV_NAME,	.id_table	= mb862xx_pci_tbl,	.probe		= mb862xx_pci_probe,	.remove		= __devexit_p(mb862xx_pci_remove),};#endifstatic int __devinit mb862xxfb_init(void){	int ret = -ENODEV;#if defined(CONFIG_FB_MB862XX_LIME)	ret = of_register_platform_driver(&of_platform_mb862xxfb_driver);#endif#if defined(CONFIG_FB_MB862XX_PCI_GDC)	ret = pci_register_driver(&mb862xxfb_pci_driver);#endif	return ret;}static void __exit mb862xxfb_exit(void){#if defined(CONFIG_FB_MB862XX_LIME)	of_unregister_platform_driver(&of_platform_mb862xxfb_driver);#endif#if defined(CONFIG_FB_MB862XX_PCI_GDC)	pci_unregister_driver(&mb862xxfb_pci_driver);#endif}module_init(mb862xxfb_init);module_exit(mb862xxfb_exit);MODULE_DESCRIPTION("Fujitsu MB862xx Framebuffer driver");MODULE_AUTHOR("Anatolij Gustschin <agust@denx.de>");MODULE_LICENSE("GPL v2");

⌨️ 快捷键说明

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