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

📄 sgivwfb.c

📁 Linux环境下视频显示卡设备的驱动程序源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
		udelay(1);	} else		dbe_TurnOffDma(par);	/* dbe_Initdbe(); */	for (i = 0; i < 256; i++) {		for (j = 0; j < 100; j++) {			DBE_GETREG(cm_fifo, readVal);			if (readVal != 0x00000000)				break;			else				udelay(10);		}		// DBE_ISETREG(cmap, i, 0x00000000);		DBE_ISETREG(cmap, i, (i << 8) | (i << 16) | (i << 24));	}	/* dbe_InitFramebuffer(); */	frmWrite1 = 0;	SET_DBE_FIELD(FRM_SIZE_TILE, FRM_WIDTH_TILE, frmWrite1,		      wholeTilesX);	SET_DBE_FIELD(FRM_SIZE_TILE, FRM_RHS, frmWrite1, 0);	switch (bytesPerPixel) {	case 1:		SET_DBE_FIELD(FRM_SIZE_TILE, FRM_DEPTH, frmWrite1,			      DBE_FRM_DEPTH_8);		break;	case 2:		SET_DBE_FIELD(FRM_SIZE_TILE, FRM_DEPTH, frmWrite1,			      DBE_FRM_DEPTH_16);		break;	case 4:		SET_DBE_FIELD(FRM_SIZE_TILE, FRM_DEPTH, frmWrite1,			      DBE_FRM_DEPTH_32);		break;	}	frmWrite2 = 0;	SET_DBE_FIELD(FRM_SIZE_PIXEL, FB_HEIGHT_PIX, frmWrite2, ypmax);	// Tell dbe about the framebuffer location and type	// XXX What format is the FRM_TILE_PTR??  64K aligned address?	frmWrite3b = 0;	SET_DBE_FIELD(FRM_CONTROL, FRM_TILE_PTR, frmWrite3b,		      sgivwfb_mem_phys >> 9);	SET_DBE_FIELD(FRM_CONTROL, FRM_DMA_ENABLE, frmWrite3b, 1);	SET_DBE_FIELD(FRM_CONTROL, FRM_LINEAR, frmWrite3b, 1);	/* Initialize DIDs */	outputVal = 0;	switch (bytesPerPixel) {	case 1:		SET_DBE_FIELD(WID, TYP, outputVal, DBE_CMODE_I8);		break;	case 2:		SET_DBE_FIELD(WID, TYP, outputVal, DBE_CMODE_RGBA5);		break;	case 4:		SET_DBE_FIELD(WID, TYP, outputVal, DBE_CMODE_RGB8);		break;	}	SET_DBE_FIELD(WID, BUF, outputVal, DBE_BMODE_BOTH);	for (i = 0; i < 32; i++) {		DBE_ISETREG(mode_regs, i, outputVal);	}	/* dbe_InitTiming(); */	DBE_SETREG(vt_intr01, 0xffffffff);	DBE_SETREG(vt_intr23, 0xffffffff);	DBE_GETREG(dotclock, readVal);	DBE_SETREG(dotclock, readVal & 0xffff);	DBE_SETREG(vt_xymax, 0x00000000);	outputVal = 0;	SET_DBE_FIELD(VT_VSYNC, VT_VSYNC_ON, outputVal,		      currentTiming->vsync_start);	SET_DBE_FIELD(VT_VSYNC, VT_VSYNC_OFF, outputVal,		      currentTiming->vsync_end);	DBE_SETREG(vt_vsync, outputVal);	outputVal = 0;	SET_DBE_FIELD(VT_HSYNC, VT_HSYNC_ON, outputVal,		      currentTiming->hsync_start);	SET_DBE_FIELD(VT_HSYNC, VT_HSYNC_OFF, outputVal,		      currentTiming->hsync_end);	DBE_SETREG(vt_hsync, outputVal);	outputVal = 0;	SET_DBE_FIELD(VT_VBLANK, VT_VBLANK_ON, outputVal,		      currentTiming->vblank_start);	SET_DBE_FIELD(VT_VBLANK, VT_VBLANK_OFF, outputVal,		      currentTiming->vblank_end);	DBE_SETREG(vt_vblank, outputVal);	outputVal = 0;	SET_DBE_FIELD(VT_HBLANK, VT_HBLANK_ON, outputVal,		      currentTiming->hblank_start);	SET_DBE_FIELD(VT_HBLANK, VT_HBLANK_OFF, outputVal,		      currentTiming->hblank_end - 3);	DBE_SETREG(vt_hblank, outputVal);	outputVal = 0;	SET_DBE_FIELD(VT_VCMAP, VT_VCMAP_ON, outputVal,		      currentTiming->vblank_start);	SET_DBE_FIELD(VT_VCMAP, VT_VCMAP_OFF, outputVal,		      currentTiming->vblank_end);	DBE_SETREG(vt_vcmap, outputVal);	outputVal = 0;	SET_DBE_FIELD(VT_HCMAP, VT_HCMAP_ON, outputVal,		      currentTiming->hblank_start);	SET_DBE_FIELD(VT_HCMAP, VT_HCMAP_OFF, outputVal,		      currentTiming->hblank_end - 3);	DBE_SETREG(vt_hcmap, outputVal);	if (flatpanel_id != -1)		sgivwfb_setup_flatpanel(par, currentTiming);	outputVal = 0;	temp = currentTiming->vblank_start - currentTiming->vblank_end - 1;	if (temp > 0)		temp = -temp;	SET_DBE_FIELD(DID_START_XY, DID_STARTY, outputVal, (u32) temp);	if (currentTiming->hblank_end >= 20)		SET_DBE_FIELD(DID_START_XY, DID_STARTX, outputVal,			      currentTiming->hblank_end - 20);	else		SET_DBE_FIELD(DID_START_XY, DID_STARTX, outputVal,			      currentTiming->htotal - (20 -						       currentTiming->						       hblank_end));	DBE_SETREG(did_start_xy, outputVal);	outputVal = 0;	SET_DBE_FIELD(CRS_START_XY, CRS_STARTY, outputVal,		      (u32) (temp + 1));	if (currentTiming->hblank_end >= DBE_CRS_MAGIC)		SET_DBE_FIELD(CRS_START_XY, CRS_STARTX, outputVal,			      currentTiming->hblank_end - DBE_CRS_MAGIC);	else		SET_DBE_FIELD(CRS_START_XY, CRS_STARTX, outputVal,			      currentTiming->htotal - (DBE_CRS_MAGIC -						       currentTiming->						       hblank_end));	DBE_SETREG(crs_start_xy, outputVal);	outputVal = 0;	SET_DBE_FIELD(VC_START_XY, VC_STARTY, outputVal, (u32) temp);	SET_DBE_FIELD(VC_START_XY, VC_STARTX, outputVal,		      currentTiming->hblank_end - 4);	DBE_SETREG(vc_start_xy, outputVal);	DBE_SETREG(frm_size_tile, frmWrite1);	DBE_SETREG(frm_size_pixel, frmWrite2);	outputVal = 0;	SET_DBE_FIELD(DOTCLK, M, outputVal, currentTiming->pll_m - 1);	SET_DBE_FIELD(DOTCLK, N, outputVal, currentTiming->pll_n - 1);	SET_DBE_FIELD(DOTCLK, P, outputVal, currentTiming->pll_p);	SET_DBE_FIELD(DOTCLK, RUN, outputVal, 1);	DBE_SETREG(dotclock, outputVal);	udelay(11 * 1000);	DBE_SETREG(vt_vpixen, 0xffffff);	DBE_SETREG(vt_hpixen, 0xffffff);	outputVal = 0;	SET_DBE_FIELD(VT_XYMAX, VT_MAXX, outputVal, currentTiming->htotal);	SET_DBE_FIELD(VT_XYMAX, VT_MAXY, outputVal, currentTiming->vtotal);	DBE_SETREG(vt_xymax, outputVal);	outputVal = frmWrite1;	SET_DBE_FIELD(FRM_SIZE_TILE, FRM_FIFO_RESET, outputVal, 1);	DBE_SETREG(frm_size_tile, outputVal);	DBE_SETREG(frm_size_tile, frmWrite1);	outputVal = 0;	SET_DBE_FIELD(OVR_WIDTH_TILE, OVR_FIFO_RESET, outputVal, 1);	DBE_SETREG(ovr_width_tile, outputVal);	DBE_SETREG(ovr_width_tile, 0);	DBE_SETREG(frm_control, frmWrite3b);	DBE_SETREG(did_control, 0);	// Wait for dbe to take frame settings	for (i = 0; i < 100000; i++) {		DBE_GETREG(frm_inhwctrl, readVal);		if (GET_DBE_FIELD(FRM_INHWCTRL, FRM_DMA_ENABLE, readVal) !=		    0)			break;		else			udelay(1);	}	if (i == 100000)		printk(KERN_INFO		       "sgivwfb: timeout waiting for frame DMA enable.\n");	outputVal = 0;	htmp = currentTiming->hblank_end - 19;	if (htmp < 0)		htmp += currentTiming->htotal;	/* allow blank to wrap around */	SET_DBE_FIELD(VT_HPIXEN, VT_HPIXEN_ON, outputVal, htmp);	SET_DBE_FIELD(VT_HPIXEN, VT_HPIXEN_OFF, outputVal,		      ((htmp + currentTiming->width -			2) % currentTiming->htotal));	DBE_SETREG(vt_hpixen, outputVal);	outputVal = 0;	SET_DBE_FIELD(VT_VPIXEN, VT_VPIXEN_OFF, outputVal,		      currentTiming->vblank_start);	SET_DBE_FIELD(VT_VPIXEN, VT_VPIXEN_ON, outputVal,		      currentTiming->vblank_end);	DBE_SETREG(vt_vpixen, outputVal);	// Turn off mouse cursor	par->regs->crs_ctl = 0;	// XXX What's this section for??	DBE_GETREG(ctrlstat, readVal);	readVal &= 0x02000000;	if (readVal != 0) {		DBE_SETREG(ctrlstat, 0x30000000);	}	return 0;}/* *  Set a single color register. The values supplied are already *  rounded down to the hardware's capabilities (according to the *  entries in the var structure). Return != 0 for invalid regno. */static int sgivwfb_setcolreg(u_int regno, u_int red, u_int green,			     u_int blue, u_int transp,			     struct fb_info *info){	struct sgivw_par *par = (struct sgivw_par *) info->par;	if (regno > 255)		return 1;	red >>= 8;	green >>= 8;	blue >>= 8;	/* wait for the color map FIFO to have a free entry */	while (par->cmap_fifo == 0)		par->cmap_fifo = par->regs->cm_fifo;	par->regs->cmap[regno] = (red << 24) | (green << 16) | (blue << 8);	par->cmap_fifo--;	/* assume FIFO is filling up */	return 0;}static int sgivwfb_mmap(struct fb_info *info,			struct vm_area_struct *vma){	unsigned long size = vma->vm_end - vma->vm_start;	unsigned long offset = vma->vm_pgoff << PAGE_SHIFT;	if (vma->vm_pgoff > (~0UL >> PAGE_SHIFT))		return -EINVAL;	if (offset + size > sgivwfb_mem_size)		return -EINVAL;	offset += sgivwfb_mem_phys;	pgprot_val(vma->vm_page_prot) =	    pgprot_val(vma->vm_page_prot) | _PAGE_PCD;	vma->vm_flags |= VM_IO;	if (remap_pfn_range(vma, vma->vm_start, offset >> PAGE_SHIFT,						size, vma->vm_page_prot))		return -EAGAIN;	printk(KERN_DEBUG "sgivwfb: mmap framebuffer P(%lx)->V(%lx)\n",	       offset, vma->vm_start);	return 0;}int __init sgivwfb_setup(char *options){	char *this_opt;	if (!options || !*options)		return 0;	while ((this_opt = strsep(&options, ",")) != NULL) {		if (!strncmp(this_opt, "monitor:", 8)) {			if (!strncmp(this_opt + 8, "crt", 3))				flatpanel_id = -1;			else if (!strncmp(this_opt + 8, "1600sw", 6))				flatpanel_id = FLATPANEL_SGI_1600SW;		}	}	return 0;}/* *  Initialisation */static int __init sgivwfb_probe(struct platform_device *dev){	struct sgivw_par *par;	struct fb_info *info;	char *monitor;	info = framebuffer_alloc(sizeof(struct sgivw_par) + sizeof(u32) * 16, &dev->dev);	if (!info)		return -ENOMEM;	par = info->par;	if (!request_mem_region(DBE_REG_PHYS, DBE_REG_SIZE, "sgivwfb")) {		printk(KERN_ERR "sgivwfb: couldn't reserve mmio region\n");		framebuffer_release(info);		return -EBUSY;	}	par->regs = (struct asregs *) ioremap_nocache(DBE_REG_PHYS, DBE_REG_SIZE);	if (!par->regs) {		printk(KERN_ERR "sgivwfb: couldn't ioremap registers\n");		goto fail_ioremap_regs;	}	mtrr_add(sgivwfb_mem_phys, sgivwfb_mem_size, MTRR_TYPE_WRCOMB, 1);	sgivwfb_fix.smem_start = sgivwfb_mem_phys;	sgivwfb_fix.smem_len = sgivwfb_mem_size;	sgivwfb_fix.ywrapstep = ywrap;	sgivwfb_fix.ypanstep = ypan;	info->fix = sgivwfb_fix;	switch (flatpanel_id) {		case FLATPANEL_SGI_1600SW:			info->var = sgivwfb_var1600sw;			monitor = "SGI 1600SW flatpanel";			break;		default:			info->var = sgivwfb_var;			monitor = "CRT";	}	printk(KERN_INFO "sgivwfb: %s monitor selected\n", monitor);	info->fbops = &sgivwfb_ops;	info->pseudo_palette = (void *) (par + 1);	info->flags = FBINFO_DEFAULT;	info->screen_base = ioremap_nocache((unsigned long) sgivwfb_mem_phys, sgivwfb_mem_size);	if (!info->screen_base) {		printk(KERN_ERR "sgivwfb: couldn't ioremap screen_base\n");		goto fail_ioremap_fbmem;	}	if (fb_alloc_cmap(&info->cmap, 256, 0) < 0)		goto fail_color_map;	if (register_framebuffer(info) < 0) {		printk(KERN_ERR "sgivwfb: couldn't register framebuffer\n");		goto fail_register_framebuffer;	}	platform_set_drvdata(dev, info);	printk(KERN_INFO "fb%d: SGI DBE frame buffer device, using %ldK of video memory at %#lx\n",      		info->node, sgivwfb_mem_size >> 10, sgivwfb_mem_phys);	return 0;fail_register_framebuffer:	fb_dealloc_cmap(&info->cmap);fail_color_map:	iounmap((char *) info->screen_base);fail_ioremap_fbmem:	iounmap(par->regs);fail_ioremap_regs:	release_mem_region(DBE_REG_PHYS, DBE_REG_SIZE);	framebuffer_release(info);	return -ENXIO;}static int sgivwfb_remove(struct platform_device *dev){	struct fb_info *info = platform_get_drvdata(dev);	if (info) {		struct sgivw_par *par = info->par;		unregister_framebuffer(info);		dbe_TurnOffDma(par);		iounmap(par->regs);		iounmap(info->screen_base);		release_mem_region(DBE_REG_PHYS, DBE_REG_SIZE);	}	return 0;}static struct platform_driver sgivwfb_driver = {	.probe	= sgivwfb_probe,	.remove	= sgivwfb_remove,	.driver	= {		.name	= "sgivwfb",	},};static struct platform_device *sgivwfb_device;int __init sgivwfb_init(void){	int ret;#ifndef MODULE	char *option = NULL;	if (fb_get_options("sgivwfb", &option))		return -ENODEV;	sgivwfb_setup(option);#endif	ret = platform_driver_register(&sgivwfb_driver);	if (!ret) {		sgivwfb_device = platform_device_alloc("sgivwfb", 0);		if (sgivwfb_device) {			ret = platform_device_add(sgivwfb_device);		} else			ret = -ENOMEM;		if (ret) {			platform_driver_unregister(&sgivwfb_driver);			platform_device_put(sgivwfb_device);		}	}	return ret;}module_init(sgivwfb_init);#ifdef MODULEMODULE_LICENSE("GPL");static void __exit sgivwfb_exit(void){	platform_device_unregister(sgivwfb_device);	platform_driver_unregister(&sgivwfb_driver);}module_exit(sgivwfb_exit);#endif				/* MODULE */

⌨️ 快捷键说明

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