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

📄 stifb.c

📁 Linux环境下视频显示卡设备的驱动程序源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
		struct fb_var_screeninfo *var = &fb->info.var;		if (regno < 16)			((u32 *)fb->info.pseudo_palette)[regno] =				regno << var->red.offset |				regno << var->green.offset |				regno << var->blue.offset;	}	WRITE_IMAGE_COLOR(fb, regno, color);	if (fb->id == S9000_ID_HCRX) {		NgleLutBltCtl lutBltCtl;		lutBltCtl = setHyperLutBltCtl(fb,				0,	/* Offset w/i LUT */				256);	/* Load entire LUT */		NGLE_BINC_SET_SRCADDR(fb,				NGLE_LONG_FB_ADDRESS(0, 0x100, 0)); 				/* 0x100 is same as used in WRITE_IMAGE_COLOR() */		START_COLORMAPLOAD(fb, lutBltCtl.all);		SETUP_FB(fb);	} else {		/* cleanup colormap hardware */		FINISH_IMAGE_COLORMAP_ACCESS(fb);	}	DEBUG_ON();	return 0;}static intstifb_blank(int blank_mode, struct fb_info *info){	struct stifb_info *fb = (struct stifb_info *) info;	int enable = (blank_mode == 0) ? ENABLE : DISABLE;	switch (fb->id) {	case S9000_ID_A1439A:		CRX24_ENABLE_DISABLE_DISPLAY(fb, enable);		break;	case CRT_ID_VISUALIZE_EG:	case S9000_ID_ARTIST:		ARTIST_ENABLE_DISABLE_DISPLAY(fb, enable);		break;	case S9000_ID_HCRX:		HYPER_ENABLE_DISABLE_DISPLAY(fb, enable);		break;	case S9000_ID_A1659A:	/* fall through */	case S9000_ID_TIMBER:	case CRX24_OVERLAY_PLANES:	default:		ENABLE_DISABLE_DISPLAY(fb, enable);		break;	}		SETUP_FB(fb);	return 0;}static void __initstifb_init_display(struct stifb_info *fb){	int id = fb->id;	SETUP_FB(fb);	/* HCRX specific initialization */	SETUP_HCRX(fb);		/*	if (id == S9000_ID_HCRX)		hyperInitSprite(fb);	else		ngleInitSprite(fb);	*/		/* Initialize the image planes. */         switch (id) {	 case S9000_ID_HCRX:	    hyperResetPlanes(fb, ENABLE);	    break;	 case S9000_ID_A1439A:	    rattlerSetupPlanes(fb);	    break;	 case S9000_ID_A1659A:	 case S9000_ID_ARTIST:	 case CRT_ID_VISUALIZE_EG:	    elkSetupPlanes(fb);	    break;	}	/* Clear attribute planes on non HCRX devices. */        switch (id) {	 case S9000_ID_A1659A:	 case S9000_ID_A1439A:	    if (fb->info.var.bits_per_pixel == 32)		ngleSetupAttrPlanes(fb, BUFF1_CMAP3);	    else {		ngleSetupAttrPlanes(fb, BUFF1_CMAP0);	    }	    if (id == S9000_ID_A1439A)		ngleClearOverlayPlanes(fb, 0xff, 0);	    break;	 case S9000_ID_ARTIST:	 case CRT_ID_VISUALIZE_EG:	    if (fb->info.var.bits_per_pixel == 32)		ngleSetupAttrPlanes(fb, BUFF1_CMAP3);	    else {		ngleSetupAttrPlanes(fb, ARTIST_CMAP0);	    }	    break;	}	stifb_blank(0, (struct fb_info *)fb);	/* 0=enable screen */	SETUP_FB(fb);}/* ------------ Interfaces to hardware functions ------------ */static struct fb_ops stifb_ops = {	.owner		= THIS_MODULE,	.fb_setcolreg	= stifb_setcolreg,	.fb_blank	= stifb_blank,	.fb_fillrect	= cfb_fillrect,	.fb_copyarea	= cfb_copyarea,	.fb_imageblit	= cfb_imageblit,};/* *  Initialization */static int __init stifb_init_fb(struct sti_struct *sti, int bpp_pref){	struct fb_fix_screeninfo *fix;	struct fb_var_screeninfo *var;	struct stifb_info *fb;	struct fb_info *info;	unsigned long sti_rom_address;	char *dev_name;	int bpp, xres, yres;	fb = kzalloc(sizeof(*fb), GFP_ATOMIC);	if (!fb) {		printk(KERN_ERR "stifb: Could not allocate stifb structure\n");		return -ENODEV;	}		info = &fb->info;	/* set struct to a known state */	fix = &info->fix;	var = &info->var;	fb->sti = sti;	/* store upper 32bits of the graphics id */	fb->id = fb->sti->graphics_id[0];	/* only supported cards are allowed */	switch (fb->id) {	case CRT_ID_VISUALIZE_EG:		/* Visualize cards can run either in "double buffer" or 		  "standard" mode. Depending on the mode, the card reports		  a different device name, e.g. "INTERNAL_EG_DX1024" in double		  buffer mode and "INTERNAL_EG_X1024" in standard mode.		  Since this driver only supports standard mode, we check		  if the device name contains the string "DX" and tell the		  user how to reconfigure the card. */		if (strstr(sti->outptr.dev_name, "DX")) {		   printk(KERN_WARNING "WARNING: stifb framebuffer driver does not "			"support '%s' in double-buffer mode.\n"			KERN_WARNING "WARNING: Please disable the double-buffer mode "			"in IPL menu (the PARISC-BIOS).\n",			sti->outptr.dev_name);		   goto out_err0;		}		/* fall though */	case S9000_ID_ARTIST:	case S9000_ID_HCRX:	case S9000_ID_TIMBER:	case S9000_ID_A1659A:	case S9000_ID_A1439A:		break;	default:		printk(KERN_WARNING "stifb: '%s' (id: 0x%08x) not supported.\n",			sti->outptr.dev_name, fb->id);		goto out_err0;	}		/* default to 8 bpp on most graphic chips */	bpp = 8;	xres = sti_onscreen_x(fb->sti);	yres = sti_onscreen_y(fb->sti);	ngleGetDeviceRomData(fb);	/* get (virtual) io region base addr */	fix->mmio_start = REGION_BASE(fb,2);	fix->mmio_len   = 0x400000;       	/* Reject any device not in the NGLE family */	switch (fb->id) {	case S9000_ID_A1659A:	/* CRX/A1659A */		break;	case S9000_ID_ELM:	/* GRX, grayscale but else same as A1659A */		var->grayscale = 1;		fb->id = S9000_ID_A1659A;		break;	case S9000_ID_TIMBER:	/* HP9000/710 Any (may be a grayscale device) */		dev_name = fb->sti->outptr.dev_name;		if (strstr(dev_name, "GRAYSCALE") || 		    strstr(dev_name, "Grayscale") ||		    strstr(dev_name, "grayscale"))			var->grayscale = 1;		break;	case S9000_ID_TOMCAT:	/* Dual CRX, behaves else like a CRX */		/* FIXME: TomCat supports two heads:		 * fb.iobase = REGION_BASE(fb_info,3);		 * fb.screen_base = ioremap_nocache(REGION_BASE(fb_info,2),xxx);		 * for now we only support the left one ! */		xres = fb->ngle_rom.x_size_visible;		yres = fb->ngle_rom.y_size_visible;		fb->id = S9000_ID_A1659A;		break;	case S9000_ID_A1439A:	/* CRX24/A1439A */		bpp = 32;		break;	case S9000_ID_HCRX:	/* Hyperdrive/HCRX */		memset(&fb->ngle_rom, 0, sizeof(fb->ngle_rom));		if ((fb->sti->regions_phys[0] & 0xfc000000) ==		    (fb->sti->regions_phys[2] & 0xfc000000))			sti_rom_address = F_EXTEND(fb->sti->regions_phys[0]);		else			sti_rom_address = F_EXTEND(fb->sti->regions_phys[1]);		fb->deviceSpecificConfig = gsc_readl(sti_rom_address);		if (IS_24_DEVICE(fb)) {			if (bpp_pref == 8 || bpp_pref == 32)				bpp = bpp_pref;			else				bpp = 32;		} else			bpp = 8;		READ_WORD(fb, REG_15);		SETUP_HW(fb);		break;	case CRT_ID_VISUALIZE_EG:	case S9000_ID_ARTIST:	/* Artist */		break;	default: #ifdef FALLBACK_TO_1BPP	       	printk(KERN_WARNING 			"stifb: Unsupported graphics card (id=0x%08x) "				"- now trying 1bpp mode instead\n",			fb->id);		bpp = 1;	/* default to 1 bpp */		break;#else	       	printk(KERN_WARNING 			"stifb: Unsupported graphics card (id=0x%08x) "				"- skipping.\n",			fb->id);		goto out_err0;#endif	}	/* get framebuffer physical and virtual base addr & len (64bit ready) */	fix->smem_start = F_EXTEND(fb->sti->regions_phys[1]);	fix->smem_len = fb->sti->regions[1].region_desc.length * 4096;	fix->line_length = (fb->sti->glob_cfg->total_x * bpp) / 8;	if (!fix->line_length)		fix->line_length = 2048; /* default */		/* limit fbsize to max visible screen size */	if (fix->smem_len > yres*fix->line_length)		fix->smem_len = yres*fix->line_length;		fix->accel = FB_ACCEL_NONE;	switch (bpp) {	    case 1:		fix->type = FB_TYPE_PLANES;	/* well, sort of */		fix->visual = FB_VISUAL_MONO10;		var->red.length = var->green.length = var->blue.length = 1;		break;	    case 8:		fix->type = FB_TYPE_PACKED_PIXELS;		fix->visual = FB_VISUAL_PSEUDOCOLOR;		var->red.length = var->green.length = var->blue.length = 8;		break;	    case 32:		fix->type = FB_TYPE_PACKED_PIXELS;		fix->visual = FB_VISUAL_DIRECTCOLOR;		var->red.length = var->green.length = var->blue.length = var->transp.length = 8;		var->blue.offset = 0;		var->green.offset = 8;		var->red.offset = 16;		var->transp.offset = 24;		break;	    default:		break;	}		var->xres = var->xres_virtual = xres;	var->yres = var->yres_virtual = yres;	var->bits_per_pixel = bpp;	strcpy(fix->id, "stifb");	info->fbops = &stifb_ops;	info->screen_base = ioremap_nocache(REGION_BASE(fb,1), fix->smem_len);	info->screen_size = fix->smem_len;	info->flags = FBINFO_DEFAULT;	info->pseudo_palette = &fb->pseudo_palette;	/* This has to been done !!! */	fb_alloc_cmap(&info->cmap, NR_PALETTE, 0);	stifb_init_display(fb);	if (!request_mem_region(fix->smem_start, fix->smem_len, "stifb fb")) {		printk(KERN_ERR "stifb: cannot reserve fb region 0x%04lx-0x%04lx\n",				fix->smem_start, fix->smem_start+fix->smem_len);		goto out_err1;	}			if (!request_mem_region(fix->mmio_start, fix->mmio_len, "stifb mmio")) {		printk(KERN_ERR "stifb: cannot reserve sti mmio region 0x%04lx-0x%04lx\n",				fix->mmio_start, fix->mmio_start+fix->mmio_len);		goto out_err2;	}	if (register_framebuffer(&fb->info) < 0)		goto out_err3;	sti->info = info; /* save for unregister_framebuffer() */	printk(KERN_INFO 	    "fb%d: %s %dx%d-%d frame buffer device, %s, id: %04x, mmio: 0x%04lx\n",		fb->info.node, 		fix->id,		var->xres, 		var->yres,		var->bits_per_pixel,		sti->outptr.dev_name,		fb->id, 		fix->mmio_start);	return 0;out_err3:	release_mem_region(fix->mmio_start, fix->mmio_len);out_err2:	release_mem_region(fix->smem_start, fix->smem_len);out_err1:	iounmap(info->screen_base);	fb_dealloc_cmap(&info->cmap);out_err0:	kfree(fb);	return -ENXIO;}static int stifb_disabled __initdata;int __initstifb_setup(char *options);static int __init stifb_init(void){	struct sti_struct *sti;	struct sti_struct *def_sti;	int i;	#ifndef MODULE	char *option = NULL;	if (fb_get_options("stifb", &option))		return -ENODEV;	stifb_setup(option);#endif	if (stifb_disabled) {		printk(KERN_INFO "stifb: disabled by \"stifb=off\" kernel parameter\n");		return -ENXIO;	}		def_sti = sti_get_rom(0);	if (def_sti) {		for (i = 1; i <= MAX_STI_ROMS; i++) {			sti = sti_get_rom(i);			if (!sti)				break;			if (sti == def_sti) {				stifb_init_fb(sti, stifb_bpp_pref[i - 1]);				break;			}		}	}	for (i = 1; i <= MAX_STI_ROMS; i++) {		sti = sti_get_rom(i);		if (!sti)			break;		if (sti == def_sti)			continue;		stifb_init_fb(sti, stifb_bpp_pref[i - 1]);	}	return 0;}/* *  Cleanup */static void __exitstifb_cleanup(void){	struct sti_struct *sti;	int i;		for (i = 1; i <= MAX_STI_ROMS; i++) {		sti = sti_get_rom(i);		if (!sti)			break;		if (sti->info) {			struct fb_info *info = sti->info;			unregister_framebuffer(sti->info);			release_mem_region(info->fix.mmio_start, info->fix.mmio_len);		        release_mem_region(info->fix.smem_start, info->fix.smem_len);				if (info->screen_base)					iounmap(info->screen_base);		        fb_dealloc_cmap(&info->cmap);		        kfree(info); 		}		sti->info = NULL;	}}int __initstifb_setup(char *options){	int i;		if (!options || !*options)		return 1;		if (strncmp(options, "off", 3) == 0) {		stifb_disabled = 1;		options += 3;	}	if (strncmp(options, "bpp", 3) == 0) {		options += 3;		for (i = 0; i < MAX_STI_ROMS; i++) {			if (*options++ != ':')				break;			stifb_bpp_pref[i] = simple_strtoul(options, &options, 10);		}	}	return 1;}__setup("stifb=", stifb_setup);module_init(stifb_init);module_exit(stifb_cleanup);MODULE_AUTHOR("Helge Deller <deller@gmx.de>, Thomas Bogendoerfer <tsbogend@alpha.franken.de>");MODULE_DESCRIPTION("Framebuffer driver for HP's NGLE series graphics cards in HP PARISC machines");MODULE_LICENSE("GPL v2");

⌨️ 快捷键说明

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