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

📄 platinumfb.c

📁 Linux环境下视频显示卡设备的驱动程序源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
		default_vmode = VMODE_640_480_60;#ifdef CONFIG_NVRAM	if (default_cmode == CMODE_NVRAM)		default_cmode = nvram_read_byte(NV_CMODE);#endif	if (default_cmode < CMODE_8 || default_cmode > CMODE_32)		default_cmode = CMODE_8;	/*	 * Reduce the pixel size if we don't have enough VRAM.	 */	while(default_cmode > CMODE_8 &&	      platinum_vram_reqd(default_vmode, default_cmode) > pinfo->total_vram)		default_cmode--;	printk("platinumfb:  Using video mode %d and color mode %d.\n", default_vmode, default_cmode);	/* Setup default var */	if (mac_vmode_to_var(default_vmode, default_cmode, &var) < 0) {		/* This shouldn't happen! */		printk("mac_vmode_to_var(%d, %d,) failed\n", default_vmode, default_cmode);try_again:		default_vmode = VMODE_640_480_60;		default_cmode = CMODE_8;		if (mac_vmode_to_var(default_vmode, default_cmode, &var) < 0) {			printk(KERN_ERR "platinumfb: mac_vmode_to_var() failed\n");			return -ENXIO;		}	}	/* Initialize info structure */	platinum_init_info(info, pinfo);	/* Apply default var */	info->var = var;	var.activate = FB_ACTIVATE_NOW;	rc = fb_set_var(info, &var);	if (rc && (default_vmode != VMODE_640_480_60 || default_cmode != CMODE_8))		goto try_again;	/* Register with fbdev layer */	rc = register_framebuffer(info);	if (rc < 0)		return rc;	printk(KERN_INFO "fb%d: Apple Platinum frame buffer device\n", info->node);	return 0;}/* * Get the monitor sense value. * Note that this can be called before calibrate_delay, * so we can't use udelay. */static int read_platinum_sense(struct fb_info_platinum *info){	volatile struct platinum_regs __iomem *platinum_regs = info->platinum_regs;	int sense;	out_be32(&platinum_regs->reg[23].r, 7);	/* turn off drivers */	__delay(2000);	sense = (~in_be32(&platinum_regs->reg[23].r) & 7) << 8;	/* drive each sense line low in turn and collect the other 2 */	out_be32(&platinum_regs->reg[23].r, 3);	/* drive A low */	__delay(2000);	sense |= (~in_be32(&platinum_regs->reg[23].r) & 3) << 4;	out_be32(&platinum_regs->reg[23].r, 5);	/* drive B low */	__delay(2000);	sense |= (~in_be32(&platinum_regs->reg[23].r) & 4) << 1;	sense |= (~in_be32(&platinum_regs->reg[23].r) & 1) << 2;	out_be32(&platinum_regs->reg[23].r, 6);	/* drive C low */	__delay(2000);	sense |= (~in_be32(&platinum_regs->reg[23].r) & 6) >> 1;	out_be32(&platinum_regs->reg[23].r, 7);	/* turn off drivers */	return sense;}/* * This routine takes a user-supplied var, and picks the best vmode/cmode from it. * It also updates the var structure to the actual mode data obtained */static int platinum_var_to_par(struct fb_var_screeninfo *var, 			       struct fb_info_platinum *pinfo,			       int check_only){	int vmode, cmode;	if (mac_var_to_vmode(var, &vmode, &cmode) != 0) {		printk(KERN_ERR "platinum_var_to_par: mac_var_to_vmode unsuccessful.\n");		printk(KERN_ERR "platinum_var_to_par: var->xres = %d\n", var->xres);		printk(KERN_ERR "platinum_var_to_par: var->yres = %d\n", var->yres);		printk(KERN_ERR "platinum_var_to_par: var->xres_virtual = %d\n", var->xres_virtual);		printk(KERN_ERR "platinum_var_to_par: var->yres_virtual = %d\n", var->yres_virtual);		printk(KERN_ERR "platinum_var_to_par: var->bits_per_pixel = %d\n", var->bits_per_pixel);		printk(KERN_ERR "platinum_var_to_par: var->pixclock = %d\n", var->pixclock);		printk(KERN_ERR "platinum_var_to_par: var->vmode = %d\n", var->vmode);		return -EINVAL;	}	if (!platinum_reg_init[vmode-1]) {		printk(KERN_ERR "platinum_var_to_par, vmode %d not valid.\n", vmode);		return -EINVAL;	}	if (platinum_vram_reqd(vmode, cmode) > pinfo->total_vram) {		printk(KERN_ERR "platinum_var_to_par, not enough ram for vmode %d, cmode %d.\n", vmode, cmode);		return -EINVAL;	}	if (mac_vmode_to_var(vmode, cmode, var))		return -EINVAL;	if (check_only)		return 0;	pinfo->vmode = vmode;	pinfo->cmode = cmode;	pinfo->xres = vmode_attrs[vmode-1].hres;	pinfo->yres = vmode_attrs[vmode-1].vres;	pinfo->xoffset = 0;	pinfo->yoffset = 0;	pinfo->vxres = pinfo->xres;	pinfo->vyres = pinfo->yres;		return 0;}/*  * Parse user speficied options (`video=platinumfb:') */static int __init platinumfb_setup(char *options){	char *this_opt;	if (!options || !*options)		return 0;	while ((this_opt = strsep(&options, ",")) != NULL) {		if (!strncmp(this_opt, "vmode:", 6)) {	    		int vmode = simple_strtoul(this_opt+6, NULL, 0);			if (vmode > 0 && vmode <= VMODE_MAX)				default_vmode = vmode;		} else if (!strncmp(this_opt, "cmode:", 6)) {			int depth = simple_strtoul(this_opt+6, NULL, 0);			switch (depth) {			 case 0:			 case 8:			    default_cmode = CMODE_8;			    break;			 case 15:			 case 16:			    default_cmode = CMODE_16;			    break;			 case 24:			 case 32:			    default_cmode = CMODE_32;			    break;			}		}	}	return 0;}#ifdef __powerpc__#define invalidate_cache(addr) \	asm volatile("eieio; dcbf 0,%1" \	: "=m" (*(addr)) : "r" (addr) : "memory");#else#define invalidate_cache(addr)#endifstatic int __devinit platinumfb_probe(struct of_device* odev,				      const struct of_device_id *match){	struct device_node	*dp = odev->node;	struct fb_info		*info;	struct fb_info_platinum	*pinfo;	volatile __u8		*fbuffer;	int			bank0, bank1, bank2, bank3, rc;	dev_info(&odev->dev, "Found Apple Platinum video hardware\n");	info = framebuffer_alloc(sizeof(*pinfo), &odev->dev);	if (info == NULL) {		dev_err(&odev->dev, "Failed to allocate fbdev !\n");		return -ENOMEM;	}	pinfo = info->par;	if (of_address_to_resource(dp, 0, &pinfo->rsrc_reg) ||	    of_address_to_resource(dp, 1, &pinfo->rsrc_fb)) {		dev_err(&odev->dev, "Can't get resources\n");		framebuffer_release(info);		return -ENXIO;	}	dev_dbg(&odev->dev, " registers  : 0x%llx...0x%llx\n",		(unsigned long long)pinfo->rsrc_reg.start,		(unsigned long long)pinfo->rsrc_reg.end);	dev_dbg(&odev->dev, " framebuffer: 0x%llx...0x%llx\n",		(unsigned long long)pinfo->rsrc_fb.start,		(unsigned long long)pinfo->rsrc_fb.end);	/* Do not try to request register space, they overlap with the	 * northbridge and that can fail. Only request framebuffer	 */	if (!request_mem_region(pinfo->rsrc_fb.start,				pinfo->rsrc_fb.end - pinfo->rsrc_fb.start + 1,				"platinumfb framebuffer")) {		printk(KERN_ERR "platinumfb: Can't request framebuffer !\n");		framebuffer_release(info);		return -ENXIO;	}	/* frame buffer - map only 4MB */	pinfo->frame_buffer_phys = pinfo->rsrc_fb.start;	pinfo->frame_buffer = __ioremap(pinfo->rsrc_fb.start, 0x400000,					_PAGE_WRITETHRU);	pinfo->base_frame_buffer = pinfo->frame_buffer;	/* registers */	pinfo->platinum_regs_phys = pinfo->rsrc_reg.start;	pinfo->platinum_regs = ioremap(pinfo->rsrc_reg.start, 0x1000);	pinfo->cmap_regs_phys = 0xf301b000;	/* XXX not in prom? */	request_mem_region(pinfo->cmap_regs_phys, 0x1000, "platinumfb cmap");	pinfo->cmap_regs = ioremap(pinfo->cmap_regs_phys, 0x1000);	/* Grok total video ram */	out_be32(&pinfo->platinum_regs->reg[16].r, (unsigned)pinfo->frame_buffer_phys);	out_be32(&pinfo->platinum_regs->reg[20].r, 0x1011);	/* select max vram */	out_be32(&pinfo->platinum_regs->reg[24].r, 0);	/* switch in vram */	fbuffer = pinfo->base_frame_buffer;	fbuffer[0x100000] = 0x34;	fbuffer[0x100008] = 0x0;	invalidate_cache(&fbuffer[0x100000]);	fbuffer[0x200000] = 0x56;	fbuffer[0x200008] = 0x0;	invalidate_cache(&fbuffer[0x200000]);	fbuffer[0x300000] = 0x78;	fbuffer[0x300008] = 0x0;	invalidate_cache(&fbuffer[0x300000]);	bank0 = 1; /* builtin 1MB vram, always there */	bank1 = fbuffer[0x100000] == 0x34;	bank2 = fbuffer[0x200000] == 0x56;	bank3 = fbuffer[0x300000] == 0x78;	pinfo->total_vram = (bank0 + bank1 + bank2 + bank3) * 0x100000;	printk(KERN_INFO "platinumfb: Total VRAM = %dMB (%d%d%d%d)\n",	       (unsigned int) (pinfo->total_vram / 1024 / 1024),	       bank3, bank2, bank1, bank0);	/*	 * Try to determine whether we have an old or a new DACula.	 */	out_8(&pinfo->cmap_regs->addr, 0x40);	pinfo->dactype = in_8(&pinfo->cmap_regs->d2);	switch (pinfo->dactype) {	case 0x3c:		pinfo->clktype = 1;		printk(KERN_INFO "platinumfb: DACula type 0x3c\n");		break;	case 0x84:		pinfo->clktype = 0;		printk(KERN_INFO "platinumfb: DACula type 0x84\n");		break;	default:		pinfo->clktype = 0;		printk(KERN_INFO "platinumfb: Unknown DACula type: %x\n", pinfo->dactype);		break;	}	dev_set_drvdata(&odev->dev, info);		rc = platinum_init_fb(info);	if (rc != 0) {		iounmap(pinfo->frame_buffer);		iounmap(pinfo->platinum_regs);		iounmap(pinfo->cmap_regs);		dev_set_drvdata(&odev->dev, NULL);		framebuffer_release(info);	}	return rc;}static int __devexit platinumfb_remove(struct of_device* odev){	struct fb_info		*info = dev_get_drvdata(&odev->dev);	struct fb_info_platinum	*pinfo = info->par;	        unregister_framebuffer (info);		/* Unmap frame buffer and registers */	iounmap(pinfo->frame_buffer);	iounmap(pinfo->platinum_regs);	iounmap(pinfo->cmap_regs);	release_mem_region(pinfo->rsrc_fb.start,			   pinfo->rsrc_fb.end -			   pinfo->rsrc_fb.start + 1);	release_mem_region(pinfo->cmap_regs_phys, 0x1000);	framebuffer_release(info);	return 0;}static struct of_device_id platinumfb_match[] = {	{	.name 		= "platinum",	},	{},};static struct of_platform_driver platinum_driver = {	.name 		= "platinumfb",	.match_table	= platinumfb_match,	.probe		= platinumfb_probe,	.remove		= platinumfb_remove,};static int __init platinumfb_init(void){#ifndef MODULE	char *option = NULL;	if (fb_get_options("platinumfb", &option))		return -ENODEV;	platinumfb_setup(option);#endif	of_register_platform_driver(&platinum_driver);	return 0;}static void __exit platinumfb_exit(void){	of_unregister_platform_driver(&platinum_driver);}MODULE_LICENSE("GPL");MODULE_DESCRIPTION("framebuffer driver for Apple Platinum video");module_init(platinumfb_init);#ifdef MODULEmodule_exit(platinumfb_exit);#endif

⌨️ 快捷键说明

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