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

📄 cirrusfb.c

📁 Linux环境下视频显示卡设备的驱动程序源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
	DPRINTK("EXIT\n");	return mem;}static void get_pci_addrs(const struct pci_dev *pdev,			  unsigned long *display, unsigned long *registers){	assert(pdev != NULL);	assert(display != NULL);	assert(registers != NULL);	DPRINTK("ENTER\n");	*display = 0;	*registers = 0;	/* This is a best-guess for now */	if (pci_resource_flags(pdev, 0) & IORESOURCE_IO) {		*display = pci_resource_start(pdev, 1);		*registers = pci_resource_start(pdev, 0);	} else {		*display = pci_resource_start(pdev, 0);		*registers = pci_resource_start(pdev, 1);	}	assert(*display != 0);	DPRINTK("EXIT\n");}static void cirrusfb_pci_unmap(struct fb_info *info){	struct pci_dev *pdev = to_pci_dev(info->device);	iounmap(info->screen_base);#if 0 /* if system didn't claim this region, we would... */	release_mem_region(0xA0000, 65535);#endif	if (release_io_ports)		release_region(0x3C0, 32);	pci_release_regions(pdev);}#endif /* CONFIG_PCI */#ifdef CONFIG_ZORROstatic void cirrusfb_zorro_unmap(struct fb_info *info){	struct cirrusfb_info *cinfo = info->par;	struct zorro_dev *zdev = to_zorro_dev(info->device);	zorro_release_device(zdev);	if (cinfo->btype == BT_PICASSO4) {		cinfo->regbase -= 0x600000;		iounmap((void *)cinfo->regbase);		iounmap(info->screen_base);	} else {		if (zorro_resource_start(zdev) > 0x01000000)			iounmap(info->screen_base);	}}#endif /* CONFIG_ZORRO */static int __devinit cirrusfb_set_fbinfo(struct fb_info *info){	struct cirrusfb_info *cinfo = info->par;	struct fb_var_screeninfo *var = &info->var;	info->pseudo_palette = cinfo->pseudo_palette;	info->flags = FBINFO_DEFAULT		    | FBINFO_HWACCEL_XPAN		    | FBINFO_HWACCEL_YPAN		    | FBINFO_HWACCEL_FILLRECT		    | FBINFO_HWACCEL_COPYAREA;	if (noaccel)		info->flags |= FBINFO_HWACCEL_DISABLED;	info->fbops = &cirrusfb_ops;	if (cinfo->btype == BT_GD5480) {		if (var->bits_per_pixel == 16)			info->screen_base += 1 * MB_;		if (var->bits_per_pixel == 32)			info->screen_base += 2 * MB_;	}	/* Fill fix common fields */	strlcpy(info->fix.id, cirrusfb_board_info[cinfo->btype].name,		sizeof(info->fix.id));	/* monochrome: only 1 memory plane */	/* 8 bit and above: Use whole memory area */	info->fix.smem_len   = info->screen_size;	if (var->bits_per_pixel == 1)		info->fix.smem_len /= 4;	info->fix.type_aux   = 0;	info->fix.xpanstep   = 1;	info->fix.ypanstep   = 1;	info->fix.ywrapstep  = 0;	/* FIXME: map region at 0xB8000 if available, fill in here */	info->fix.mmio_len   = 0;	info->fix.accel = FB_ACCEL_NONE;	fb_alloc_cmap(&info->cmap, 256, 0);	return 0;}static int __devinit cirrusfb_register(struct fb_info *info){	struct cirrusfb_info *cinfo = info->par;	int err;	enum cirrus_board btype;	DPRINTK("ENTER\n");	printk(KERN_INFO "cirrusfb: Driver for Cirrus Logic based "		"graphic boards, v" CIRRUSFB_VERSION "\n");	btype = cinfo->btype;	/* sanity checks */	assert(btype != BT_NONE);	/* set all the vital stuff */	cirrusfb_set_fbinfo(info);	DPRINTK("cirrusfb: (RAM start set to: 0x%p)\n", info->screen_base);	err = fb_find_mode(&info->var, info, mode_option, NULL, 0, NULL, 8);	if (!err) {		DPRINTK("wrong initial video mode\n");		err = -EINVAL;		goto err_dealloc_cmap;	}	info->var.activate = FB_ACTIVATE_NOW;	err = cirrusfb_decode_var(&info->var, &cinfo->currentmode, info);	if (err < 0) {		/* should never happen */		DPRINTK("choking on default var... umm, no good.\n");		goto err_dealloc_cmap;	}	err = register_framebuffer(info);	if (err < 0) {		printk(KERN_ERR "cirrusfb: could not register "			"fb device; err = %d!\n", err);		goto err_dealloc_cmap;	}	DPRINTK("EXIT, returning 0\n");	return 0;err_dealloc_cmap:	fb_dealloc_cmap(&info->cmap);	cinfo->unmap(info);	framebuffer_release(info);	return err;}static void __devexit cirrusfb_cleanup(struct fb_info *info){	struct cirrusfb_info *cinfo = info->par;	DPRINTK("ENTER\n");	switch_monitor(cinfo, 0);	unregister_framebuffer(info);	fb_dealloc_cmap(&info->cmap);	printk("Framebuffer unregistered\n");	cinfo->unmap(info);	framebuffer_release(info);	DPRINTK("EXIT\n");}#ifdef CONFIG_PCIstatic int __devinit cirrusfb_pci_register(struct pci_dev *pdev,					   const struct pci_device_id *ent){	struct cirrusfb_info *cinfo;	struct fb_info *info;	enum cirrus_board btype;	unsigned long board_addr, board_size;	int ret;	ret = pci_enable_device(pdev);	if (ret < 0) {		printk(KERN_ERR "cirrusfb: Cannot enable PCI device\n");		goto err_out;	}	info = framebuffer_alloc(sizeof(struct cirrusfb_info), &pdev->dev);	if (!info) {		printk(KERN_ERR "cirrusfb: could not allocate memory\n");		ret = -ENOMEM;		goto err_disable;	}	cinfo = info->par;	cinfo->btype = btype = (enum cirrus_board) ent->driver_data;	DPRINTK(" Found PCI device, base address 0 is 0x%x, btype set to %d\n",		pdev->resource[0].start, btype);	DPRINTK(" base address 1 is 0x%x\n", pdev->resource[1].start);	if (isPReP) {		pci_write_config_dword(pdev, PCI_BASE_ADDRESS_0, 0x00000000);#ifdef CONFIG_PPC_PREP		get_prep_addrs(&board_addr, &info->fix.mmio_start);#endif	/* PReP dies if we ioremap the IO registers, but it works w/out... */		cinfo->regbase = (char __iomem *) info->fix.mmio_start;	} else {		DPRINTK("Attempt to get PCI info for Cirrus Graphics Card\n");		get_pci_addrs(pdev, &board_addr, &info->fix.mmio_start);		/* FIXME: this forces VGA.  alternatives? */		cinfo->regbase = NULL;	}	DPRINTK("Board address: 0x%lx, register address: 0x%lx\n",		board_addr, info->fix.mmio_start);	board_size = (btype == BT_GD5480) ?		32 * MB_ : cirrusfb_get_memsize(cinfo->regbase);	ret = pci_request_regions(pdev, "cirrusfb");	if (ret < 0) {		printk(KERN_ERR "cirrusfb: cannot reserve region 0x%lx, "		       "abort\n",		       board_addr);		goto err_release_fb;	}#if 0 /* if the system didn't claim this region, we would... */	if (!request_mem_region(0xA0000, 65535, "cirrusfb")) {		printk(KERN_ERR "cirrusfb: cannot reserve region 0x%lx, abort\n",		       0xA0000L);		ret = -EBUSY;		goto err_release_regions;	}#endif	if (request_region(0x3C0, 32, "cirrusfb"))		release_io_ports = 1;	info->screen_base = ioremap(board_addr, board_size);	if (!info->screen_base) {		ret = -EIO;		goto err_release_legacy;	}	info->fix.smem_start = board_addr;	info->screen_size = board_size;	cinfo->unmap = cirrusfb_pci_unmap;	printk(KERN_INFO "RAM (%lu kB) at 0x%lx, Cirrus "			"Logic chipset on PCI bus\n",			info->screen_size >> 10, board_addr);	pci_set_drvdata(pdev, info);	ret = cirrusfb_register(info);	if (ret)		iounmap(info->screen_base);	return ret;err_release_legacy:	if (release_io_ports)		release_region(0x3C0, 32);#if 0	release_mem_region(0xA0000, 65535);err_release_regions:#endif	pci_release_regions(pdev);err_release_fb:	framebuffer_release(info);err_disable:err_out:	return ret;}static void __devexit cirrusfb_pci_unregister(struct pci_dev *pdev){	struct fb_info *info = pci_get_drvdata(pdev);	DPRINTK("ENTER\n");	cirrusfb_cleanup(info);	DPRINTK("EXIT\n");}static struct pci_driver cirrusfb_pci_driver = {	.name		= "cirrusfb",	.id_table	= cirrusfb_pci_table,	.probe		= cirrusfb_pci_register,	.remove		= __devexit_p(cirrusfb_pci_unregister),#ifdef CONFIG_PM#if 0	.suspend	= cirrusfb_pci_suspend,	.resume		= cirrusfb_pci_resume,#endif#endif};#endif /* CONFIG_PCI */#ifdef CONFIG_ZORROstatic int __devinit cirrusfb_zorro_register(struct zorro_dev *z,					     const struct zorro_device_id *ent){	struct cirrusfb_info *cinfo;	struct fb_info *info;	enum cirrus_board btype;	struct zorro_dev *z2 = NULL;	unsigned long board_addr, board_size, size;	int ret;	btype = ent->driver_data;	if (cirrusfb_zorro_table2[btype].id2)		z2 = zorro_find_device(cirrusfb_zorro_table2[btype].id2, NULL);	size = cirrusfb_zorro_table2[btype].size;	printk(KERN_INFO "cirrusfb: %s board detected; ",	       cirrusfb_board_info[btype].name);	info = framebuffer_alloc(sizeof(struct cirrusfb_info), &z->dev);	if (!info) {		printk(KERN_ERR "cirrusfb: could not allocate memory\n");		ret = -ENOMEM;		goto err_out;	}	cinfo = info->par;	cinfo->btype = btype;	assert(z);	assert(btype != BT_NONE);	board_addr = zorro_resource_start(z);	board_size = zorro_resource_len(z);	info->screen_size = size;	if (!zorro_request_device(z, "cirrusfb")) {		printk(KERN_ERR "cirrusfb: cannot reserve region 0x%lx, "		       "abort\n",		       board_addr);		ret = -EBUSY;		goto err_release_fb;	}	printk(" RAM (%lu MB) at $%lx, ", board_size / MB_, board_addr);	ret = -EIO;	if (btype == BT_PICASSO4) {		printk(KERN_INFO " REG at $%lx\n", board_addr + 0x600000);		/* To be precise, for the P4 this is not the */		/* begin of the board, but the begin of RAM. */		/* for P4, map in its address space in 2 chunks (### TEST! ) */		/* (note the ugly hardcoded 16M number) */		cinfo->regbase = ioremap(board_addr, 16777216);		if (!cinfo->regbase)			goto err_release_region;		DPRINTK("cirrusfb: Virtual address for board set to: $%p\n",			cinfo->regbase);		cinfo->regbase += 0x600000;		info->fix.mmio_start = board_addr + 0x600000;		info->fix.smem_start = board_addr + 16777216;		info->screen_base = ioremap(info->fix.smem_start, 16777216);		if (!info->screen_base)			goto err_unmap_regbase;	} else {		printk(KERN_INFO " REG at $%lx\n",			(unsigned long) z2->resource.start);		info->fix.smem_start = board_addr;		if (board_addr > 0x01000000)			info->screen_base = ioremap(board_addr, board_size);		else			info->screen_base = (caddr_t) ZTWO_VADDR(board_addr);		if (!info->screen_base)			goto err_release_region;		/* set address for REG area of board */		cinfo->regbase = (caddr_t) ZTWO_VADDR(z2->resource.start);		info->fix.mmio_start = z2->resource.start;		DPRINTK("cirrusfb: Virtual address for board set to: $%p\n",			cinfo->regbase);	}	cinfo->unmap = cirrusfb_zorro_unmap;	printk(KERN_INFO "Cirrus Logic chipset on Zorro bus\n");	zorro_set_drvdata(z, info);	ret = cirrusfb_register(info);	if (ret) {		if (btype == BT_PICASSO4) {			iounmap(info->screen_base);			iounmap(cinfo->regbase - 0x600000);		} else if (board_addr > 0x01000000)			iounmap(info->screen_base);	}	return ret;err_unmap_regbase:	/* Parental advisory: explicit hack */	iounmap(cinfo->regbase - 0x600000);err_release_region:	release_region(board_addr, board_size);err_release_fb:	framebuffer_release(info);err_out:	return ret;}void __devexit cirrusfb_zorro_unregister(struct zorro_dev *z){	struct fb_info *info = zorro_get_drvdata(z);	DPRINTK("ENTER\n");	cirrusfb_cleanup(info);	DPRINTK("EXIT\n");}static struct zorro_driver cirrusfb_zorro_driver = {	.name		= "cirrusfb",	.id_table	= cirrusfb_zorro_table,	.probe		= cirrusfb_zorro_register,	.remove		= __devexit_p(cirrusfb_zorro_unregister),};#endif /* CONFIG_ZORRO */static int __init cirrusfb_init(void){	int error = 0;#ifndef MODULE	char *option = NULL;	if (fb_get_options("cirrusfb", &option))		return -ENODEV;	cirrusfb_setup(option);#endif#ifdef CONFIG_ZORRO	error |= zorro_register_driver(&cirrusfb_zorro_driver);#endif#ifdef CONFIG_PCI	error |= pci_register_driver(&cirrusfb_pci_driver);#endif	return error;}#ifndef MODULEstatic int __init cirrusfb_setup(char *options) {	char *this_opt;	DPRINTK("ENTER\n");	if (!options || !*options)		return 0;	while ((this_opt = strsep(&options, ",")) != NULL) {		if (!*this_opt)			continue;		DPRINTK("cirrusfb_setup: option '%s'\n", this_opt);		if (!strcmp(this_opt, "noaccel"))			noaccel = 1;		else if (!strncmp(this_opt, "mode:", 5))			mode_option = this_opt + 5;		else			mode_option = this_opt;	}	return 0;}#endif    /*     *  Modularization     */MODULE_AUTHOR("Copyright 1999,2000 Jeff Garzik <jgarzik@pobox.com>");MODULE_DESCRIPTION("Accelerated FBDev driver for Cirrus Logic chips");MODULE_LICENSE("GPL");static void __exit cirrusfb_exit(void){#ifdef CONFIG_PCI	pci_unregister_driver(&cirrusfb_pci_driver);#endif#ifdef CONFIG_ZORRO	zorro_unregister_driver(&cirrusfb_zorro_driver);#end

⌨️ 快捷键说明

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