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

📄 w100fb.c

📁 Linux环境下视频显示卡设备的驱动程序源代码
💻 C
📖 第 1 页 / 共 4 页
字号:
	w100_setup_memory(par);	w100_init_clocks(par);	w100fb_clear_screen(par);	w100_vsync();	w100_update_disable();	w100_init_lcd(par);	w100_set_dispregs(par);	w100_update_enable();	w100_init_graphic_engine(par);	calc_hsync(par);	if (!par->blanked && tg && tg->change)		tg->change(par);}/* Select the smallest mode that allows the desired resolution to be * displayed. If desired, the x and y parameters can be rounded up to * match the selected mode. */static struct w100_mode *w100fb_get_mode(struct w100fb_par *par, unsigned int *x, unsigned int *y, int saveval){	struct w100_mode *mode = NULL;	struct w100_mode *modelist = par->mach->modelist;	unsigned int best_x = 0xffffffff, best_y = 0xffffffff;	unsigned int i;	for (i = 0 ; i < par->mach->num_modes ; i++) {		if (modelist[i].xres >= *x && modelist[i].yres >= *y &&				modelist[i].xres < best_x && modelist[i].yres < best_y) {			best_x = modelist[i].xres;			best_y = modelist[i].yres;			mode = &modelist[i];		} else if(modelist[i].xres >= *y && modelist[i].yres >= *x &&		        modelist[i].xres < best_y && modelist[i].yres < best_x) {			best_x = modelist[i].yres;			best_y = modelist[i].xres;			mode = &modelist[i];		}	}	if (mode && saveval) {		*x = best_x;		*y = best_y;	}	return mode;}/* *  w100fb_check_var(): *  Get the video params out of 'var'. If a value doesn't fit, round it up, *  if it's too big, return -EINVAL. */static int w100fb_check_var(struct fb_var_screeninfo *var, struct fb_info *info){	struct w100fb_par *par=info->par;	if(!w100fb_get_mode(par, &var->xres, &var->yres, 1))		return -EINVAL;	if (par->mach->mem && ((var->xres*var->yres*BITS_PER_PIXEL/8) > (par->mach->mem->size+1)))		return -EINVAL;	if (!par->mach->mem && ((var->xres*var->yres*BITS_PER_PIXEL/8) > (MEM_INT_SIZE+1)))		return -EINVAL;	var->xres_virtual = max(var->xres_virtual, var->xres);	var->yres_virtual = max(var->yres_virtual, var->yres);	if (var->bits_per_pixel > BITS_PER_PIXEL)		return -EINVAL;	else		var->bits_per_pixel = BITS_PER_PIXEL;	var->red.offset = 11;	var->red.length = 5;	var->green.offset = 5;	var->green.length = 6;	var->blue.offset = 0;	var->blue.length = 5;	var->transp.offset = var->transp.length = 0;	var->nonstd = 0;	var->height = -1;	var->width = -1;	var->vmode = FB_VMODE_NONINTERLACED;	var->sync = 0;	var->pixclock = 0x04;  /* 171521; */	return 0;}/* * w100fb_set_par(): *	Set the user defined part of the display for the specified console *  by looking at the values in info.var */static int w100fb_set_par(struct fb_info *info){	struct w100fb_par *par=info->par;	if (par->xres != info->var.xres || par->yres != info->var.yres)	{		par->xres = info->var.xres;		par->yres = info->var.yres;		par->mode = w100fb_get_mode(par, &par->xres, &par->yres, 0);		info->fix.visual = FB_VISUAL_TRUECOLOR;		info->fix.ypanstep = 0;		info->fix.ywrapstep = 0;		info->fix.line_length = par->xres * BITS_PER_PIXEL / 8;		if ((par->xres*par->yres*BITS_PER_PIXEL/8) > (MEM_INT_SIZE+1)) {			par->extmem_active = 1;			info->fix.smem_len = par->mach->mem->size+1;		} else {			par->extmem_active = 0;			info->fix.smem_len = MEM_INT_SIZE+1;		}		w100fb_activate_var(par);	}	return 0;}/* *  Frame buffer operations */static struct fb_ops w100fb_ops = {	.owner        = THIS_MODULE,	.fb_check_var = w100fb_check_var,	.fb_set_par   = w100fb_set_par,	.fb_setcolreg = w100fb_setcolreg,	.fb_blank     = w100fb_blank,	.fb_fillrect  = w100fb_fillrect,	.fb_copyarea  = w100fb_copyarea,	.fb_imageblit = cfb_imageblit,	.fb_sync      = w100fb_sync,};#ifdef CONFIG_PMstatic void w100fb_save_vidmem(struct w100fb_par *par){	int memsize;	if (par->extmem_active) {		memsize=par->mach->mem->size;		par->saved_extmem = vmalloc(memsize);		if (par->saved_extmem)			memcpy_fromio(par->saved_extmem, remapped_fbuf + (W100_FB_BASE-MEM_WINDOW_BASE), memsize);	}	memsize=MEM_INT_SIZE;	par->saved_intmem = vmalloc(memsize);	if (par->saved_intmem && par->extmem_active)		memcpy_fromio(par->saved_intmem, remapped_fbuf + (W100_FB_BASE-MEM_INT_BASE_VALUE), memsize);	else if (par->saved_intmem)		memcpy_fromio(par->saved_intmem, remapped_fbuf + (W100_FB_BASE-MEM_WINDOW_BASE), memsize);}static void w100fb_restore_vidmem(struct w100fb_par *par){	int memsize;	if (par->extmem_active && par->saved_extmem) {		memsize=par->mach->mem->size;		memcpy_toio(remapped_fbuf + (W100_FB_BASE-MEM_WINDOW_BASE), par->saved_extmem, memsize);		vfree(par->saved_extmem);	}	if (par->saved_intmem) {		memsize=MEM_INT_SIZE;		if (par->extmem_active)			memcpy_toio(remapped_fbuf + (W100_FB_BASE-MEM_INT_BASE_VALUE), par->saved_intmem, memsize);		else			memcpy_toio(remapped_fbuf + (W100_FB_BASE-MEM_WINDOW_BASE), par->saved_intmem, memsize);		vfree(par->saved_intmem);	}}static int w100fb_suspend(struct platform_device *dev, pm_message_t state){	struct fb_info *info = platform_get_drvdata(dev);	struct w100fb_par *par=info->par;	struct w100_tg_info *tg = par->mach->tg;	w100fb_save_vidmem(par);	if(tg && tg->suspend)		tg->suspend(par);	w100_suspend(W100_SUSPEND_ALL);	par->blanked = 1;	return 0;}static int w100fb_resume(struct platform_device *dev){	struct fb_info *info = platform_get_drvdata(dev);	struct w100fb_par *par=info->par;	struct w100_tg_info *tg = par->mach->tg;	w100_hw_init(par);	w100fb_activate_var(par);	w100fb_restore_vidmem(par);	if(tg && tg->resume)		tg->resume(par);	par->blanked = 0;	return 0;}#else#define w100fb_suspend  NULL#define w100fb_resume   NULL#endifint __init w100fb_probe(struct platform_device *pdev){	int err = -EIO;	struct w100fb_mach_info *inf;	struct fb_info *info = NULL;	struct w100fb_par *par;	struct resource *mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);	unsigned int chip_id;	if (!mem)		return -EINVAL;	/* Remap the chip base address */	remapped_base = ioremap_nocache(mem->start+W100_CFG_BASE, W100_CFG_LEN);	if (remapped_base == NULL)		goto out;	/* Map the register space */	remapped_regs = ioremap_nocache(mem->start+W100_REG_BASE, W100_REG_LEN);	if (remapped_regs == NULL)		goto out;	/* Identify the chip */	printk("Found ");	chip_id = readl(remapped_regs + mmCHIP_ID);	switch(chip_id) {		case CHIP_ID_W100:  printk("w100");  break;		case CHIP_ID_W3200: printk("w3200"); break;		case CHIP_ID_W3220: printk("w3220"); break;		default:			printk("Unknown imageon chip ID\n");			err = -ENODEV;			goto out;	}	printk(" at 0x%08lx.\n", (unsigned long) mem->start+W100_CFG_BASE);	/* Remap the framebuffer */	remapped_fbuf = ioremap_nocache(mem->start+MEM_WINDOW_BASE, MEM_WINDOW_SIZE);	if (remapped_fbuf == NULL)		goto out;	info=framebuffer_alloc(sizeof(struct w100fb_par), &pdev->dev);	if (!info) {		err = -ENOMEM;		goto out;	}	par = info->par;	platform_set_drvdata(pdev, info);	inf = pdev->dev.platform_data;	par->chip_id = chip_id;	par->mach = inf;	par->fastpll_mode = 0;	par->blanked = 0;	par->pll_table=w100_get_xtal_table(inf->xtal_freq);	if (!par->pll_table) {		printk(KERN_ERR "No matching Xtal definition found\n");		err = -EINVAL;		goto out;	}	info->pseudo_palette = kmalloc(sizeof (u32) * MAX_PALETTES, GFP_KERNEL);	if (!info->pseudo_palette) {		err = -ENOMEM;		goto out;	}	info->fbops = &w100fb_ops;	info->flags = FBINFO_DEFAULT | FBINFO_HWACCEL_COPYAREA |		FBINFO_HWACCEL_FILLRECT;	info->node = -1;	info->screen_base = remapped_fbuf + (W100_FB_BASE-MEM_WINDOW_BASE);	info->screen_size = REMAPPED_FB_LEN;	strcpy(info->fix.id, "w100fb");	info->fix.type = FB_TYPE_PACKED_PIXELS;	info->fix.type_aux = 0;	info->fix.accel = FB_ACCEL_NONE;	info->fix.smem_start = mem->start+W100_FB_BASE;	info->fix.mmio_start = mem->start+W100_REG_BASE;	info->fix.mmio_len = W100_REG_LEN;	if (fb_alloc_cmap(&info->cmap, 256, 0) < 0) {		err = -ENOMEM;		goto out;	}	par->mode = &inf->modelist[0];	if(inf->init_mode & INIT_MODE_ROTATED) {		info->var.xres = par->mode->yres;		info->var.yres = par->mode->xres;	}	else {		info->var.xres = par->mode->xres;		info->var.yres = par->mode->yres;	}	if(inf->init_mode &= INIT_MODE_FLIPPED)		par->flip = 1;	else		par->flip = 0;	info->var.xres_virtual = info->var.xres;	info->var.yres_virtual = info->var.yres;	info->var.pixclock = 0x04;  /* 171521; */	info->var.sync = 0;	info->var.grayscale = 0;	info->var.xoffset = info->var.yoffset = 0;	info->var.accel_flags = 0;	info->var.activate = FB_ACTIVATE_NOW;	w100_hw_init(par);	if (w100fb_check_var(&info->var, info) < 0) {		err = -EINVAL;		goto out;	}	w100fb_set_par(info);	if (register_framebuffer(info) < 0) {		err = -EINVAL;		goto out;	}	err = device_create_file(&pdev->dev, &dev_attr_fastpllclk);	err |= device_create_file(&pdev->dev, &dev_attr_reg_read);	err |= device_create_file(&pdev->dev, &dev_attr_reg_write);	err |= device_create_file(&pdev->dev, &dev_attr_flip);	if (err != 0)		printk(KERN_WARNING "fb%d: failed to register attributes (%d)\n",				info->node, err);	printk(KERN_INFO "fb%d: %s frame buffer device\n", info->node, info->fix.id);	return 0;out:	if (info) {		fb_dealloc_cmap(&info->cmap);		kfree(info->pseudo_palette);	}	if (remapped_fbuf != NULL)		iounmap(remapped_fbuf);	if (remapped_regs != NULL)		iounmap(remapped_regs);	if (remapped_base != NULL)		iounmap(remapped_base);	if (info)		framebuffer_release(info);	return err;}static int w100fb_remove(struct platform_device *pdev){	struct fb_info *info = platform_get_drvdata(pdev);	struct w100fb_par *par=info->par;	device_remove_file(&pdev->dev, &dev_attr_fastpllclk);	device_remove_file(&pdev->dev, &dev_attr_reg_read);	device_remove_file(&pdev->dev, &dev_attr_reg_write);	device_remove_file(&pdev->dev, &dev_attr_flip);	unregister_framebuffer(info);	vfree(par->saved_intmem);	vfree(par->saved_extmem);	kfree(info->pseudo_palette);	fb_dealloc_cmap(&info->cmap);	iounmap(remapped_base);	iounmap(remapped_regs);	iounmap(remapped_fbuf);	framebuffer_release(info);	return 0;}/* ------------------- chipset specific functions -------------------------- */static void w100_soft_reset(void){	u16 val = readw((u16 *) remapped_base + cfgSTATUS);	writew(val | 0x08, (u16 *) remapped_base + cfgSTATUS);	udelay(100);

⌨️ 快捷键说明

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