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

📄 pvr2fb.c

📁 Linux环境下视频显示卡设备的驱动程序源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
 * in for flexibility anyways. Who knows, maybe someone has tv-out on a * PCI-based version of these things ;-) */static int __devinit pvr2fb_common_init(void){	struct pvr2fb_par *par = currentpar;	unsigned long modememused, rev;	fb_info->screen_base = ioremap_nocache(pvr2_fix.smem_start,					       pvr2_fix.smem_len);	if (!fb_info->screen_base) {		printk(KERN_ERR "pvr2fb: Failed to remap smem space\n");		goto out_err;	}	par->mmio_base = (unsigned long)ioremap_nocache(pvr2_fix.mmio_start,							pvr2_fix.mmio_len);	if (!par->mmio_base) {		printk(KERN_ERR "pvr2fb: Failed to remap mmio space\n");		goto out_err;	}	fb_memset(fb_info->screen_base, 0, pvr2_fix.smem_len);	pvr2_fix.ypanstep	= nopan  ? 0 : 1;	pvr2_fix.ywrapstep	= nowrap ? 0 : 1;	fb_info->fbops		= &pvr2fb_ops;	fb_info->fix		= pvr2_fix;	fb_info->par		= currentpar;	fb_info->pseudo_palette	= currentpar->palette;	fb_info->flags		= FBINFO_DEFAULT | FBINFO_HWACCEL_YPAN;	if (video_output == VO_VGA)		defmode = DEFMODE_VGA;	if (!mode_option)		mode_option = "640x480@60";	if (!fb_find_mode(&fb_info->var, fb_info, mode_option, pvr2_modedb,	                  NUM_TOTAL_MODES, &pvr2_modedb[defmode], 16))		fb_info->var = pvr2_var;	fb_alloc_cmap(&fb_info->cmap, 256, 0);	if (register_framebuffer(fb_info) < 0)		goto out_err;	/*Must write PIXDEPTH to register before anything is displayed - so force init */	pvr2_init_display(fb_info);	modememused = get_line_length(fb_info->var.xres_virtual,				      fb_info->var.bits_per_pixel);	modememused *= fb_info->var.yres_virtual;	rev = fb_readl(par->mmio_base + 0x04);	printk("fb%d: %s (rev %ld.%ld) frame buffer device, using %ldk/%ldk of video memory\n",	       fb_info->node, fb_info->fix.id, (rev >> 4) & 0x0f, rev & 0x0f,	       modememused >> 10, (unsigned long)(fb_info->fix.smem_len >> 10));	printk("fb%d: Mode %dx%d-%d pitch = %ld cable: %s video output: %s\n",	       fb_info->node, fb_info->var.xres, fb_info->var.yres,	       fb_info->var.bits_per_pixel,	       get_line_length(fb_info->var.xres, fb_info->var.bits_per_pixel),	       (char *)pvr2_get_param(cables, NULL, cable_type, 3),	       (char *)pvr2_get_param(outputs, NULL, video_output, 3));#ifdef CONFIG_SH_STORE_QUEUES	printk(KERN_NOTICE "fb%d: registering with SQ API\n", fb_info->node);	pvr2fb_map = sq_remap(fb_info->fix.smem_start, fb_info->fix.smem_len,			      fb_info->fix.id, pgprot_val(PAGE_SHARED));	printk(KERN_NOTICE "fb%d: Mapped video memory to SQ addr 0x%lx\n",	       fb_info->node, pvr2fb_map);#endif	return 0;out_err:	if (fb_info->screen_base)		iounmap(fb_info->screen_base);	if (par->mmio_base)		iounmap((void *)par->mmio_base);	return -ENXIO;}#ifdef CONFIG_SH_DREAMCASTstatic int __init pvr2fb_dc_init(void){	if (!mach_is_dreamcast())		return -ENXIO;	/* Make a guess at the monitor based on the attached cable */	if (pvr2_init_cable() == CT_VGA) {		fb_info->monspecs.hfmin = 30000;		fb_info->monspecs.hfmax = 70000;		fb_info->monspecs.vfmin = 60;		fb_info->monspecs.vfmax = 60;	} else {		/* Not VGA, using a TV (taken from acornfb) */		fb_info->monspecs.hfmin = 15469;		fb_info->monspecs.hfmax = 15781;		fb_info->monspecs.vfmin = 49;		fb_info->monspecs.vfmax = 51;	}	/*	 * XXX: This needs to pull default video output via BIOS or other means	 */	if (video_output < 0) {		if (cable_type == CT_VGA) {			video_output = VO_VGA;		} else {			video_output = VO_NTSC;		}	}	/*	 * Nothing exciting about the DC PVR2 .. only a measly 8MiB.	 */	pvr2_fix.smem_start	= 0xa5000000;	/* RAM starts here */	pvr2_fix.smem_len	= 8 << 20;	pvr2_fix.mmio_start	= 0xa05f8000;	/* registers start here */	pvr2_fix.mmio_len	= 0x2000;	if (request_irq(HW_EVENT_VSYNC, pvr2fb_interrupt, IRQF_SHARED,	                "pvr2 VBL handler", fb_info)) {		return -EBUSY;	}#ifdef CONFIG_SH_DMA	if (request_dma(pvr2dma, "pvr2") != 0) {		free_irq(HW_EVENT_VSYNC, 0);		return -EBUSY;	}#endif	return pvr2fb_common_init();}static void __exit pvr2fb_dc_exit(void){	if (fb_info->screen_base) {		iounmap(fb_info->screen_base);		fb_info->screen_base = NULL;	}	if (currentpar->mmio_base) {		iounmap((void *)currentpar->mmio_base);		currentpar->mmio_base = 0;	}	free_irq(HW_EVENT_VSYNC, 0);#ifdef CONFIG_SH_DMA	free_dma(pvr2dma);#endif}#endif /* CONFIG_SH_DREAMCAST */#ifdef CONFIG_PCIstatic int __devinit pvr2fb_pci_probe(struct pci_dev *pdev,				      const struct pci_device_id *ent){	int ret;	ret = pci_enable_device(pdev);	if (ret) {		printk(KERN_ERR "pvr2fb: PCI enable failed\n");		return ret;	}	ret = pci_request_regions(pdev, "pvr2fb");	if (ret) {		printk(KERN_ERR "pvr2fb: PCI request regions failed\n");		return ret;	}	/*	 * Slightly more exciting than the DC PVR2 .. 16MiB!	 */	pvr2_fix.smem_start	= pci_resource_start(pdev, 0);	pvr2_fix.smem_len	= pci_resource_len(pdev, 0);	pvr2_fix.mmio_start	= pci_resource_start(pdev, 1);	pvr2_fix.mmio_len	= pci_resource_len(pdev, 1);	fb_info->device		= &pdev->dev;	return pvr2fb_common_init();}static void __devexit pvr2fb_pci_remove(struct pci_dev *pdev){	if (fb_info->screen_base) {		iounmap(fb_info->screen_base);		fb_info->screen_base = NULL;	}	if (currentpar->mmio_base) {		iounmap((void *)currentpar->mmio_base);		currentpar->mmio_base = 0;	}	pci_release_regions(pdev);}static struct pci_device_id pvr2fb_pci_tbl[] __devinitdata = {	{ PCI_VENDOR_ID_NEC, PCI_DEVICE_ID_NEC_NEON250,	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },	{ 0, },};MODULE_DEVICE_TABLE(pci, pvr2fb_pci_tbl);static struct pci_driver pvr2fb_pci_driver = {	.name		= "pvr2fb",	.id_table	= pvr2fb_pci_tbl,	.probe		= pvr2fb_pci_probe,	.remove		= __devexit_p(pvr2fb_pci_remove),};static int __init pvr2fb_pci_init(void){	return pci_register_driver(&pvr2fb_pci_driver);}static void __exit pvr2fb_pci_exit(void){	pci_unregister_driver(&pvr2fb_pci_driver);}#endif /* CONFIG_PCI */static int __devinit pvr2_get_param(const struct pvr2_params *p, const char *s,                                   int val, int size){	int i;	for (i = 0 ; i < size ; i++ ) {		if (s != NULL) {			if (!strnicmp(p[i].name, s, strlen(s)))				return p[i].val;		} else {			if (p[i].val == val)				return (int)p[i].name;		}	}	return -1;}/* * Parse command arguments.  Supported arguments are: *    inverse                             Use inverse color maps *    cable:composite|rgb|vga             Override the video cable type *    output:NTSC|PAL|VGA                 Override the video output format * *    <xres>x<yres>[-<bpp>][@<refresh>]   or, *    <name>[-<bpp>][@<refresh>]          Startup using this video mode */#ifndef MODULEstatic int __init pvr2fb_setup(char *options){	char *this_opt;	char cable_arg[80];	char output_arg[80];	if (!options || !*options)		return 0;	while ((this_opt = strsep(&options, ","))) {		if (!*this_opt)			continue;		if (!strcmp(this_opt, "inverse")) {			fb_invert_cmaps();		} else if (!strncmp(this_opt, "cable:", 6)) {			strcpy(cable_arg, this_opt + 6);		} else if (!strncmp(this_opt, "output:", 7)) {			strcpy(output_arg, this_opt + 7);		} else if (!strncmp(this_opt, "nopan", 5)) {			nopan = 1;		} else if (!strncmp(this_opt, "nowrap", 6)) {			nowrap = 1;		} else {			mode_option = this_opt;		}	}	if (*cable_arg)		cable_type = pvr2_get_param(cables, cable_arg, 0, 3);	if (*output_arg)		video_output = pvr2_get_param(outputs, output_arg, 0, 3);	return 0;}#endifstatic struct pvr2_board {	int (*init)(void);	void (*exit)(void);	char name[16];} board_driver[] = {#ifdef CONFIG_SH_DREAMCAST	{ pvr2fb_dc_init, pvr2fb_dc_exit, "Sega DC PVR2" },#endif#ifdef CONFIG_PCI	{ pvr2fb_pci_init, pvr2fb_pci_exit, "PCI PVR2" },#endif	{ 0, },};static int __init pvr2fb_init(void){	int i, ret = -ENODEV;	int size;#ifndef MODULE	char *option = NULL;	if (fb_get_options("pvr2fb", &option))		return -ENODEV;	pvr2fb_setup(option);#endif	size = sizeof(struct fb_info) + sizeof(struct pvr2fb_par) + 16 * sizeof(u32);	fb_info = framebuffer_alloc(sizeof(struct pvr2fb_par), NULL);	if (!fb_info) {		printk(KERN_ERR "Failed to allocate memory for fb_info\n");		return -ENOMEM;	}	currentpar = fb_info->par;	for (i = 0; i < ARRAY_SIZE(board_driver); i++) {		struct pvr2_board *pvr_board = board_driver + i;		if (!pvr_board->init)			continue;		ret = pvr_board->init();		if (ret != 0) {			printk(KERN_ERR "pvr2fb: Failed init of %s device\n",				pvr_board->name);			framebuffer_release(fb_info);			break;		}	}	return ret;}static void __exit pvr2fb_exit(void){	int i;	for (i = 0; i < ARRAY_SIZE(board_driver); i++) {		struct pvr2_board *pvr_board = board_driver + i;		if (pvr_board->exit)			pvr_board->exit();	}#ifdef CONFIG_SH_STORE_QUEUES	sq_unmap(pvr2fb_map);#endif	unregister_framebuffer(fb_info);	framebuffer_release(fb_info);}module_init(pvr2fb_init);module_exit(pvr2fb_exit);MODULE_AUTHOR("Paul Mundt <lethal@linux-sh.org>, M. R. Brown <mrbrown@0xd6.org>");MODULE_DESCRIPTION("Framebuffer driver for NEC PowerVR 2 based graphics boards");MODULE_LICENSE("GPL");

⌨️ 快捷键说明

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