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

📄 i810_main.c

📁 linux-2.6.15.6
💻 C
📖 第 1 页 / 共 4 页
字号:
 * DESCRIPTION: * Based on the contents of @var, @par will be dynamically filled up. * @par contains all information necessary to modify the hardware. */static void decode_var(const struct fb_var_screeninfo *var, 		       struct i810fb_par *par){	u32 xres, yres, vxres, vyres;	xres = var->xres;	yres = var->yres;	vxres = var->xres_virtual;	vyres = var->yres_virtual;	switch (var->bits_per_pixel) {	case 8:		par->pixconf = PIXCONF8;		par->bltcntl = 0;		par->depth = 1;		par->blit_bpp = BPP8;		break;	case 16:		if (var->green.length == 5)			par->pixconf = PIXCONF15;		else			par->pixconf = PIXCONF16;		par->bltcntl = 16;		par->depth = 2;		par->blit_bpp = BPP16;		break;	case 24:		par->pixconf = PIXCONF24;		par->bltcntl = 32;		par->depth = 3;		par->blit_bpp = BPP24;		break;	case 32:		par->pixconf = PIXCONF32;		par->bltcntl = 0;		par->depth = 4;		par->blit_bpp = 3 << 24;		break;	}	if (var->nonstd && var->bits_per_pixel != 8)		par->pixconf |= 1 << 27;	i810_calc_dclk(var->pixclock, &par->regs.M, 		       &par->regs.N, &par->regs.P);	i810fb_encode_registers(var, par, xres, yres);	par->watermark = i810_get_watermark(var, par);	par->pitch = get_line_length(par, vxres, var->bits_per_pixel);}	/** * i810fb_getcolreg - gets red, green and blue values of the hardware DAC * @regno: DAC index * @red: red * @green: green * @blue: blue * @transp: transparency (alpha) * @info: pointer to fb_info * * DESCRIPTION: * Gets the red, green and blue values of the hardware DAC as pointed by @regno * and writes them to @red, @green and @blue respectively */static int i810fb_getcolreg(u8 regno, u8 *red, u8 *green, u8 *blue, 			    u8 *transp, struct fb_info *info){	struct i810fb_par *par = (struct i810fb_par *) info->par;	u8 __iomem *mmio = par->mmio_start_virtual;	u8 temp;	if (info->fix.visual == FB_VISUAL_DIRECTCOLOR) {		if ((info->var.green.length == 5 && regno > 31) ||		    (info->var.green.length == 6 && regno > 63))			return 1;	}	temp = i810_readb(PIXCONF1, mmio);	i810_writeb(PIXCONF1, mmio, temp & ~EXTENDED_PALETTE);	if (info->fix.visual == FB_VISUAL_DIRECTCOLOR && 	    info->var.green.length == 5) 		i810_read_dac(regno * 8, red, green, blue, mmio);	else if (info->fix.visual == FB_VISUAL_DIRECTCOLOR && 		 info->var.green.length == 6) {		u8 tmp;		i810_read_dac(regno * 8, red, &tmp, blue, mmio);		i810_read_dac(regno * 4, &tmp, green, &tmp, mmio);	}	else 		i810_read_dac(regno, red, green, blue, mmio);    	*transp = 0;	i810_writeb(PIXCONF1, mmio, temp);    	return 0;}/******************************************************************  *           Framebuffer device-specific hooks                    * ******************************************************************/static int i810fb_open(struct fb_info *info, int user){	struct i810fb_par *par = (struct i810fb_par *) info->par;	u32 count = atomic_read(&par->use_count);		if (count == 0) {		memset(&par->state, 0, sizeof(struct vgastate));		par->state.flags = VGA_SAVE_CMAP;		par->state.vgabase = par->mmio_start_virtual;		save_vga(&par->state);		i810_save_vga_state(par);	}	atomic_inc(&par->use_count);		return 0;}static int i810fb_release(struct fb_info *info, int user){	struct i810fb_par *par = (struct i810fb_par *) info->par;	u32 count;		count = atomic_read(&par->use_count);	if (count == 0)		return -EINVAL;	if (count == 1) {		i810_restore_vga_state(par);		restore_vga(&par->state);	}	atomic_dec(&par->use_count);		return 0;}static int i810fb_setcolreg(unsigned regno, unsigned red, unsigned green, 			    unsigned blue, unsigned transp, 			    struct fb_info *info){	struct i810fb_par *par = (struct i810fb_par *) info->par;	u8 __iomem *mmio = par->mmio_start_virtual;	u8 temp;	int i; 	if (regno > 255) return 1;	if (info->fix.visual == FB_VISUAL_DIRECTCOLOR) {		if ((info->var.green.length == 5 && regno > 31) ||		    (info->var.green.length == 6 && regno > 63))			return 1;	}	if (info->var.grayscale)		red = green = blue = (19595 * red + 38470 * green +				      7471 * blue) >> 16;	temp = i810_readb(PIXCONF1, mmio);	i810_writeb(PIXCONF1, mmio, temp & ~EXTENDED_PALETTE);	if (info->fix.visual == FB_VISUAL_DIRECTCOLOR && 	    info->var.green.length == 5) {		for (i = 0; i < 8; i++) 			i810_write_dac((u8) (regno * 8) + i, (u8) red, 				       (u8) green, (u8) blue, mmio);	} else if (info->fix.visual == FB_VISUAL_DIRECTCOLOR && 		 info->var.green.length == 6) {		u8 r, g, b;		if (regno < 32) {			for (i = 0; i < 8; i++) 				i810_write_dac((u8) (regno * 8) + i,					       (u8) red, (u8) green, 					       (u8) blue, mmio);		}		i810_read_dac((u8) (regno*4), &r, &g, &b, mmio);		for (i = 0; i < 4; i++) 			i810_write_dac((u8) (regno*4) + i, r, (u8) green, 				       b, mmio);	} else if (info->fix.visual == FB_VISUAL_PSEUDOCOLOR) {		i810_write_dac((u8) regno, (u8) red, (u8) green,			       (u8) blue, mmio);	}	i810_writeb(PIXCONF1, mmio, temp);	if (regno < 16) {		switch (info->var.bits_per_pixel) {		case 16:				if (info->fix.visual == FB_VISUAL_DIRECTCOLOR) {				if (info->var.green.length == 5) 					((u32 *)info->pseudo_palette)[regno] = 						(regno << 10) | (regno << 5) |						regno;				else					((u32 *)info->pseudo_palette)[regno] = 						(regno << 11) | (regno << 5) |						regno;			} else {				if (info->var.green.length == 5) {					/* RGB 555 */					((u32 *)info->pseudo_palette)[regno] = 						((red & 0xf800) >> 1) |						((green & 0xf800) >> 6) |						((blue & 0xf800) >> 11);				} else {					/* RGB 565 */					((u32 *)info->pseudo_palette)[regno] =						(red & 0xf800) |						((green & 0xf800) >> 5) |						((blue & 0xf800) >> 11);				}			}			break;		case 24:	/* RGB 888 */		case 32:	/* RGBA 8888 */			if (info->fix.visual == FB_VISUAL_DIRECTCOLOR) 				((u32 *)info->pseudo_palette)[regno] = 					(regno << 16) | (regno << 8) |					regno;			else 				((u32 *)info->pseudo_palette)[regno] = 					((red & 0xff00) << 8) |					(green & 0xff00) |					((blue & 0xff00) >> 8);			break;		}	}	return 0;}static int i810fb_pan_display(struct fb_var_screeninfo *var, 			      struct fb_info *info){	struct i810fb_par *par = (struct i810fb_par *) info->par;	u32 total;		total = var->xoffset * par->depth + 		var->yoffset * info->fix.line_length;	i810fb_load_front(total, info);	return 0;}static int i810fb_blank (int blank_mode, struct fb_info *info){	struct i810fb_par *par = (struct i810fb_par *) info->par;	u8 __iomem *mmio = par->mmio_start_virtual;	int mode = 0, pwr, scr_off = 0;		pwr = i810_readl(PWR_CLKC, mmio);	switch (blank_mode) {	case FB_BLANK_UNBLANK:		mode = POWERON;		pwr |= 1;		scr_off = ON;		break;	case FB_BLANK_NORMAL:		mode = POWERON;		pwr |= 1;		scr_off = OFF;		break;	case FB_BLANK_VSYNC_SUSPEND:		mode = STANDBY;		pwr |= 1;		scr_off = OFF;		break;	case FB_BLANK_HSYNC_SUSPEND:		mode = SUSPEND;		pwr |= 1;		scr_off = OFF;		break;	case FB_BLANK_POWERDOWN:		mode = POWERDOWN;		pwr &= ~1;		scr_off = OFF;		break;	default:		return -EINVAL; 	}	i810_screen_off(mmio, scr_off);	i810_writel(HVSYNC, mmio, mode);	i810_writel(PWR_CLKC, mmio, pwr);	return 0;}static int i810fb_set_par(struct fb_info *info){	struct i810fb_par *par = (struct i810fb_par *) info->par;	decode_var(&info->var, par);	i810_load_regs(par);	i810_init_cursor(par);	encode_fix(&info->fix, info);	if (info->var.accel_flags && !(par->dev_flags & LOCKUP)) {		info->flags = FBINFO_DEFAULT | FBINFO_HWACCEL_YPAN |		FBINFO_HWACCEL_COPYAREA | FBINFO_HWACCEL_FILLRECT |		FBINFO_HWACCEL_IMAGEBLIT;		info->pixmap.scan_align = 2;	} else {		info->pixmap.scan_align = 1;		info->flags = FBINFO_DEFAULT | FBINFO_HWACCEL_YPAN;	}	return 0;}static int i810fb_check_var(struct fb_var_screeninfo *var, 			    struct fb_info *info){	int err;	if (IS_DVT) {		var->vmode &= ~FB_VMODE_MASK;		var->vmode |= FB_VMODE_NONINTERLACED;	}	if (var->vmode & FB_VMODE_DOUBLE) {		var->vmode &= ~FB_VMODE_MASK;		var->vmode |= FB_VMODE_NONINTERLACED;	}	i810_round_off(var);	if ((err = i810_check_params(var, info)))		return err;	i810fb_fill_var_timings(var);	set_color_bitfields(var);	return 0;}static int i810fb_cursor(struct fb_info *info, struct fb_cursor *cursor){	struct i810fb_par *par = (struct i810fb_par *)info->par;	u8 __iomem *mmio = par->mmio_start_virtual;	if (!par->dev_flags & LOCKUP)		return -ENXIO;	if (cursor->image.width > 64 || cursor->image.height > 64)		return -ENXIO;	if ((i810_readl(CURBASE, mmio) & 0xf) != par->cursor_heap.physical) {		i810_init_cursor(par);		cursor->set |= FB_CUR_SETALL;	}	i810_enable_cursor(mmio, OFF);	if (cursor->set & FB_CUR_SETPOS) {		u32 tmp;		tmp = (cursor->image.dx - info->var.xoffset) & 0xffff;		tmp |= (cursor->image.dy - info->var.yoffset) << 16;		i810_writel(CURPOS, mmio, tmp);	}	if (cursor->set & FB_CUR_SETSIZE)		i810_reset_cursor_image(par);	if (cursor->set & FB_CUR_SETCMAP)		i810_load_cursor_colors(cursor->image.fg_color,					cursor->image.bg_color,					info);	if (cursor->set & (FB_CUR_SETSHAPE | FB_CUR_SETIMAGE)) {		int size = ((cursor->image.width + 7) >> 3) *			cursor->image.height;		int i;		u8 *data = kmalloc(64 * 8, GFP_KERNEL);		if (data == NULL)			return -ENOMEM;		switch (cursor->rop) {		case ROP_XOR:			for (i = 0; i < size; i++)				data[i] = cursor->image.data[i] ^ cursor->mask[i];			break;		case ROP_COPY:		default:			for (i = 0; i < size; i++)				data[i] = cursor->image.data[i] & cursor->mask[i];			break;		}		i810_load_cursor_image(cursor->image.width,				       cursor->image.height, data,				       par);		kfree(data);	}	if (cursor->enable)		i810_enable_cursor(mmio, ON);	return 0;}static struct fb_ops i810fb_ops __devinitdata = {	.owner =             THIS_MODULE,	.fb_open =           i810fb_open,	.fb_release =        i810fb_release,	.fb_check_var =      i810fb_check_var,	.fb_set_par =        i810fb_set_par,	.fb_setcolreg =      i810fb_setcolreg,	.fb_blank =          i810fb_blank,	.fb_pan_display =    i810fb_pan_display, 	.fb_fillrect =       i810fb_fillrect,	.fb_copyarea =       i810fb_copyarea,	.fb_imageblit =      i810fb_imageblit,	.fb_cursor =         i810fb_cursor,	.fb_sync =           i810fb_sync,};/*********************************************************************** *                         Power Management                            * ***********************************************************************/static int i810fb_suspend(struct pci_dev *dev, pm_message_t state){	struct fb_info *info = pci_get_drvdata(dev);	struct i810fb_par *par = (struct i810fb_par *) info->par;	int blank = 0, prev_state = par->cur_state;	if (state.event == prev_state)		return 0;	par->cur_state = state.event;	switch (state.event) {	case 1:		blank = VESA_VSYNC_SUSPEND;		break;	case 2:		blank = VESA_HSYNC_SUSPEND;		break;	case 3:		blank = VESA_POWERDOWN;		break;	default:		return -EINVAL;	}	info->fbops->fb_blank(blank, info);	if (!prev_state) { 		agp_unbind_memory(par->i810_gtt.i810_fb_memory);		agp_unbind_memory(par->i810_gtt.i810_cursor_memory);		pci_disable_device(dev);	}	pci_save_state(dev);	pci_set_power_state(dev, pci_choose_state(dev, state));	return 0;}static int i810fb_resume(struct pci_dev *dev) {	struct fb_info *info = pci_get_drvdata(dev);	struct i810fb_par *par = (struct i810fb_par *) info->par;	if (par->cur_state == 0)		return 0;	pci_restore_state(dev);	pci_set_power_state(dev, PCI_D0);	pci_enable_device(dev);	agp_bind_memory(par->i810_gtt.i810_fb_memory,			par->fb.offset);	agp_bind_memory(par->i810_gtt.i810_cursor_memory,			par->cursor_heap.offset);	info->fbops->fb_blank(VESA_NO_BLANKING, info);	par->cur_state = 0;	return 0;}/*********************************************************************** *                  AGP resource allocation                            * ***********************************************************************/  static void __devinit i810_fix_pointers(struct i810fb_par *par){      	par->fb.physical = par->aperture.physical+(par->fb.offset << 12);	par->fb.virtual = par->aperture.virtual+(par->fb.offset << 12);	par->iring.physical = par->aperture.physical + 		(par->iring.offset << 12);	par->iring.virtual = par->aperture.virtual + 		(par->iring.offset << 12);	par->cursor_heap.virtual = par->aperture.virtual+		(par->cursor_heap.offset << 12);}static void __devinit i810_fix_offsets(struct i810fb_par *par){	if (vram + 1 > par->aperture.size >> 20)		vram = (par->aperture.size >> 20) - 1;	if (v_offset_default > (par->aperture.size >> 20))		v_offset_default = (par->aperture.size >> 20);	if (vram + v_offset_default + 1 > par->aperture.size >> 20)		v_offset_default = (par->aperture.size >> 20) - (vram + 1);	par->fb.size = vram << 20;	par->fb.offset = v_offset_default << 20;	par->fb.offset >>= 12;	par->iring.offset = par->fb.offset + (par->fb.size >> 12);	par->iring.size = RINGBUFFER_SIZE;	par->cursor_heap.offset = par->iring.offset + (RINGBUFFER_SIZE >> 12);	par->cursor_heap.size = 4096;}static int __devinit i810_alloc_agp_mem(struct fb_info *info){	struct i810fb_par *par = (struct i810fb_par *) info->par;	int size;	struct agp_bridge_data *bridge;		i810_fix_offsets(par);	size = par->fb.size + par->iring.size;	if (!(bridge = agp_backend_acquire(par->dev))) {		printk("i810fb_alloc_fbmem: cannot acquire agpgart\n");		return -ENODEV;	}	if (!(par->i810_gtt.i810_fb_memory = 	      agp_allocate_memory(bridge, size >> 12, AGP_NORMAL_MEMORY))) {		printk("i810fb_alloc_fbmem: can't allocate framebuffer "		       "memory\n");		agp_backend_release(bridge);		return -ENOMEM;

⌨️ 快捷键说明

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