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

📄 intelfbdrv.c

📁 Linux环境下视频显示卡设备的驱动程序源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
	info->pixmap.scan_align = 1;	strcpy(info->fix.id, dinfo->name);	info->fix.smem_start = dinfo->fb.physical;	info->fix.smem_len = dinfo->fb.size;	info->fix.type = FB_TYPE_PACKED_PIXELS;	info->fix.type_aux = 0;	info->fix.xpanstep = 8;	info->fix.ypanstep = 1;	info->fix.ywrapstep = 0;	info->fix.mmio_start = dinfo->mmio_base_phys;	info->fix.mmio_len = INTEL_REG_SIZE;	info->fix.accel = FB_ACCEL_I830;	update_dinfo(dinfo, &info->var);	return 0;}/* Update dinfo to match the active video mode. */static void update_dinfo(struct intelfb_info *dinfo,			 struct fb_var_screeninfo *var){	DBG_MSG("update_dinfo\n");	dinfo->bpp = var->bits_per_pixel;	dinfo->depth = intelfb_var_to_depth(var);	dinfo->xres = var->xres;	dinfo->yres = var->xres;	dinfo->pixclock = var->pixclock;	dinfo->info->fix.visual = dinfo->visual;	dinfo->info->fix.line_length = dinfo->pitch;	switch (dinfo->bpp) {	case 8:		dinfo->visual = FB_VISUAL_PSEUDOCOLOR;		dinfo->pitch = var->xres_virtual;		break;	case 16:		dinfo->visual = FB_VISUAL_TRUECOLOR;		dinfo->pitch = var->xres_virtual * 2;		break;	case 32:		dinfo->visual = FB_VISUAL_TRUECOLOR;		dinfo->pitch = var->xres_virtual * 4;		break;	}	/* Make sure the line length is a aligned correctly. */	if (IS_I9XX(dinfo))		dinfo->pitch = ROUND_UP_TO(dinfo->pitch, STRIDE_ALIGNMENT_I9XX);	else		dinfo->pitch = ROUND_UP_TO(dinfo->pitch, STRIDE_ALIGNMENT);	if (FIXED_MODE(dinfo))		dinfo->pitch = dinfo->initial_pitch;	dinfo->info->screen_base = (char __iomem *)dinfo->fb.virtual;	dinfo->info->fix.line_length = dinfo->pitch;	dinfo->info->fix.visual = dinfo->visual;}/* fbops functions *//*************************************************************** *                       fbdev interface                       * ***************************************************************/static int intelfb_open(struct fb_info *info, int user){	struct intelfb_info *dinfo = GET_DINFO(info);	if (user)		dinfo->open++;	return 0;}static int intelfb_release(struct fb_info *info, int user){	struct intelfb_info *dinfo = GET_DINFO(info);	if (user) {		dinfo->open--;		msleep(1);		if (!dinfo->open)			intelfbhw_disable_irq(dinfo);	}	return 0;}static int intelfb_check_var(struct fb_var_screeninfo *var,			     struct fb_info *info){	int change_var = 0;	struct fb_var_screeninfo v;	struct intelfb_info *dinfo;	static int first = 1;	int i;	/* Good pitches to allow tiling.  Don't care about pitches < 1024. */	static const int pitches[] = {		128 * 8,		128 * 16,		128 * 32,		128 * 64,		0	};	DBG_MSG("intelfb_check_var: accel_flags is %d\n", var->accel_flags);	dinfo = GET_DINFO(info);	/* update the pitch */	if (intelfbhw_validate_mode(dinfo, var) != 0)		return -EINVAL;	v = *var;	for (i = 0; pitches[i] != 0; i++) {		if (pitches[i] >= v.xres_virtual) {			v.xres_virtual = pitches[i];			break;		}	}	/* Check for a supported bpp. */	if (v.bits_per_pixel <= 8)		v.bits_per_pixel = 8;	else if (v.bits_per_pixel <= 16) {		if (v.bits_per_pixel == 16)			v.green.length = 6;		v.bits_per_pixel = 16;	} else if (v.bits_per_pixel <= 32)		v.bits_per_pixel = 32;	else		return -EINVAL;	change_var = ((info->var.xres != var->xres) ||		      (info->var.yres != var->yres) ||		      (info->var.xres_virtual != var->xres_virtual) ||		      (info->var.yres_virtual != var->yres_virtual) ||		      (info->var.bits_per_pixel != var->bits_per_pixel) ||		      memcmp(&info->var.red, &var->red, sizeof(var->red)) ||		      memcmp(&info->var.green, &var->green,			     sizeof(var->green)) ||		      memcmp(&info->var.blue, &var->blue, sizeof(var->blue)));	if (FIXED_MODE(dinfo) &&	    (change_var ||	     var->yres_virtual > dinfo->initial_var.yres_virtual ||	     var->yres_virtual < dinfo->initial_var.yres ||	     var->xoffset || var->nonstd)) {		if (first) {			ERR_MSG("Changing the video mode is not supported.\n");			first = 0;		}		return -EINVAL;	}	switch (intelfb_var_to_depth(&v)) {	case 8:		v.red.offset = v.green.offset = v.blue.offset = 0;		v.red.length = v.green.length = v.blue.length = 8;		v.transp.offset = v.transp.length = 0;		break;	case 15:		v.red.offset = 10;		v.green.offset = 5;		v.blue.offset = 0;		v.red.length = v.green.length = v.blue.length = 5;		v.transp.offset = v.transp.length = 0;		break;	case 16:		v.red.offset = 11;		v.green.offset = 5;		v.blue.offset = 0;		v.red.length = 5;		v.green.length = 6;		v.blue.length = 5;		v.transp.offset = v.transp.length = 0;		break;	case 24:		v.red.offset = 16;		v.green.offset = 8;		v.blue.offset = 0;		v.red.length = v.green.length = v.blue.length = 8;		v.transp.offset = v.transp.length = 0;		break;	case 32:		v.red.offset = 16;		v.green.offset = 8;		v.blue.offset = 0;		v.red.length = v.green.length = v.blue.length = 8;		v.transp.offset = 24;		v.transp.length = 8;		break;	}	if (v.xoffset < 0)		v.xoffset = 0;	if (v.yoffset < 0)		v.yoffset = 0;	if (v.xoffset > v.xres_virtual - v.xres)		v.xoffset = v.xres_virtual - v.xres;	if (v.yoffset > v.yres_virtual - v.yres)		v.yoffset = v.yres_virtual - v.yres;	v.red.msb_right = v.green.msb_right = v.blue.msb_right =			  v.transp.msb_right = 0;        *var = v;	return 0;}static int intelfb_set_par(struct fb_info *info){	struct intelfb_hwstate *hw;        struct intelfb_info *dinfo = GET_DINFO(info);	if (FIXED_MODE(dinfo)) {		ERR_MSG("Changing the video mode is not supported.\n");		return -EINVAL;	}	hw = kmalloc(sizeof(*hw), GFP_ATOMIC);	if (!hw)		return -ENOMEM;	DBG_MSG("intelfb_set_par (%dx%d-%d)\n", info->var.xres,		info->var.yres, info->var.bits_per_pixel);	intelfb_blank(FB_BLANK_POWERDOWN, info);	if (ACCEL(dinfo, info))		intelfbhw_2d_stop(dinfo);	memcpy(hw, &dinfo->save_state, sizeof(*hw));	if (intelfbhw_mode_to_hw(dinfo, hw, &info->var))		goto invalid_mode;	if (intelfbhw_program_mode(dinfo, hw, 0))		goto invalid_mode;#if REGDUMP > 0	intelfbhw_read_hw_state(dinfo, hw, 0);	intelfbhw_print_hw_state(dinfo, hw);#endif	update_dinfo(dinfo, &info->var);	if (ACCEL(dinfo, info))		intelfbhw_2d_start(dinfo);	intelfb_pan_display(&info->var, info);	intelfb_blank(FB_BLANK_UNBLANK, info);	if (ACCEL(dinfo, info)) {		info->flags = FBINFO_DEFAULT | FBINFO_HWACCEL_YPAN |		FBINFO_HWACCEL_COPYAREA | FBINFO_HWACCEL_FILLRECT |		FBINFO_HWACCEL_IMAGEBLIT;	} else		info->flags = FBINFO_DEFAULT | FBINFO_HWACCEL_YPAN;	kfree(hw);	return 0;invalid_mode:	kfree(hw);	return -EINVAL;}static int intelfb_setcolreg(unsigned regno, unsigned red, unsigned green,			     unsigned blue, unsigned transp,			     struct fb_info *info){	struct intelfb_info *dinfo = GET_DINFO(info);#if VERBOSE > 0	DBG_MSG("intelfb_setcolreg: regno %d, depth %d\n", regno, dinfo->depth);#endif	if (regno > 255)		return 1;	if (dinfo->depth == 8) {		red >>= 8;		green >>= 8;		blue >>= 8;		intelfbhw_setcolreg(dinfo, regno, red, green, blue,				    transp);	}	if (regno < 16) {		switch (dinfo->depth) {		case 15:			dinfo->pseudo_palette[regno] = ((red & 0xf800) >>  1) |				((green & 0xf800) >>  6) |				((blue & 0xf800) >> 11);			break;		case 16:			dinfo->pseudo_palette[regno] = (red & 0xf800) |				((green & 0xfc00) >>  5) |				((blue  & 0xf800) >> 11);			break;		case 24:			dinfo->pseudo_palette[regno] = ((red & 0xff00) << 8) |				(green & 0xff00) |				((blue  & 0xff00) >> 8);			break;		}	}	return 0;}static int intelfb_blank(int blank, struct fb_info *info){	intelfbhw_do_blank(blank, info);	return 0;}static int intelfb_pan_display(struct fb_var_screeninfo *var,			       struct fb_info *info){	intelfbhw_pan_display(var, info);	return 0;}/* When/if we have our own ioctls. */static int intelfb_ioctl(struct fb_info *info, unsigned int cmd,			 unsigned long arg){	int retval = 0;	struct intelfb_info *dinfo = GET_DINFO(info);	u32 pipe = 0;	switch (cmd) {		case FBIO_WAITFORVSYNC:			if (get_user(pipe, (__u32 __user *)arg))				return -EFAULT;			retval = intelfbhw_wait_for_vsync(dinfo, pipe);			break;		default:			break;	}	return retval;}static void intelfb_fillrect (struct fb_info *info,			      const struct fb_fillrect *rect){        struct intelfb_info *dinfo = GET_DINFO(info);	u32 rop, color;#if VERBOSE > 0	DBG_MSG("intelfb_fillrect\n");#endif	if (!ACCEL(dinfo, info) || dinfo->depth == 4) {		cfb_fillrect(info, rect);		return;	}	if (rect->rop == ROP_COPY)		rop = PAT_ROP_GXCOPY;	else /* ROP_XOR */		rop = PAT_ROP_GXXOR;	if (dinfo->depth != 8)		color = dinfo->pseudo_palette[rect->color];	else		color = rect->color;	intelfbhw_do_fillrect(dinfo, rect->dx, rect->dy,			      rect->width, rect->height, color,			      dinfo->pitch, info->var.bits_per_pixel,			      rop);}static void intelfb_copyarea(struct fb_info *info,			     const struct fb_copyarea *region){        struct intelfb_info *dinfo = GET_DINFO(info);#if VERBOSE > 0	DBG_MSG("intelfb_copyarea\n");#endif	if (!ACCEL(dinfo, info) || dinfo->depth == 4) {		cfb_copyarea(info, region);		return;	}	intelfbhw_do_bitblt(dinfo, region->sx, region->sy, region->dx,			    region->dy, region->width, region->height,			    dinfo->pitch, info->var.bits_per_pixel);}static void intelfb_imageblit(struct fb_info *info,			      const struct fb_image *image){        struct intelfb_info *dinfo = GET_DINFO(info);	u32 fgcolor, bgcolor;#if VERBOSE > 0	DBG_MSG("intelfb_imageblit\n");#endif	if (!ACCEL(dinfo, info) || dinfo->depth == 4	    || image->depth != 1) {		cfb_imageblit(info, image);		return;	}	if (dinfo->depth != 8) {		fgcolor = dinfo->pseudo_palette[image->fg_color];		bgcolor = dinfo->pseudo_palette[image->bg_color];	} else {		fgcolor = image->fg_color;		bgcolor = image->bg_color;	}	if (!intelfbhw_do_drawglyph(dinfo, fgcolor, bgcolor, image->width,				    image->height, image->data,				    image->dx, image->dy,				    dinfo->pitch, info->var.bits_per_pixel)) {		cfb_imageblit(info, image);		return;	}}static int intelfb_cursor(struct fb_info *info, struct fb_cursor *cursor){        struct intelfb_info *dinfo = GET_DINFO(info);	u32 physical;#if VERBOSE > 0	DBG_MSG("intelfb_cursor\n");#endif	if (!dinfo->hwcursor)		return -ENODEV;	intelfbhw_cursor_hide(dinfo);	/* If XFree killed the cursor - restore it */	physical = (dinfo->mobile || IS_I9XX(dinfo)) ? dinfo->cursor.physical :		   (dinfo->cursor.offset << 12);	if (INREG(CURSOR_A_BASEADDR) != physical) {		u32 fg, bg;		DBG_MSG("the cursor was killed - restore it !!\n");		DBG_MSG("size %d, %d   pos %d, %d\n",			cursor->image.width, cursor->image.height,			cursor->image.dx, cursor->image.dy);		intelfbhw_cursor_init(dinfo);		intelfbhw_cursor_reset(dinfo);		intelfbhw_cursor_setpos(dinfo, cursor->image.dx,					cursor->image.dy);		if (dinfo->depth != 8) {			fg =dinfo->pseudo_palette[cursor->image.fg_color];			bg =dinfo->pseudo_palette[cursor->image.bg_color];		} else {			fg = cursor->image.fg_color;			bg = cursor->image.bg_color;		}		intelfbhw_cursor_setcolor(dinfo, bg, fg);		intelfbhw_cursor_load(dinfo, cursor->image.width,				      cursor->image.height,				      dinfo->cursor_src);		if (cursor->enable)			intelfbhw_cursor_show(dinfo);		return 0;	}	if (cursor->set & FB_CUR_SETPOS) {		u32 dx, dy;		dx = cursor->image.dx - info->var.xoffset;		dy = cursor->image.dy - info->var.yoffset;		intelfbhw_cursor_setpos(dinfo, dx, dy);	}	if (cursor->set & FB_CUR_SETSIZE) {		if (cursor->image.width > 64 || cursor->image.height > 64)			return -ENXIO;		intelfbhw_cursor_reset(dinfo);	}	if (cursor->set & FB_CUR_SETCMAP) {		u32 fg, bg;		if (dinfo->depth != 8) {			fg = dinfo->pseudo_palette[cursor->image.fg_color];			bg = dinfo->pseudo_palette[cursor->image.bg_color];		} else {			fg = cursor->image.fg_color;			bg = cursor->image.bg_color;		}		intelfbhw_cursor_setcolor(dinfo, bg, fg);	}	if (cursor->set & (FB_CUR_SETSHAPE | FB_CUR_SETIMAGE)) {		u32 s_pitch = (ROUND_UP_TO(cursor->image.width, 8) / 8);		u32 size = s_pitch * cursor->image.height;		u8 *dat = (u8 *) cursor->image.data;		u8 *msk = (u8 *) cursor->mask;		u8 src[64];		u32 i;		if (cursor->image.depth != 1)			return -ENXIO;		switch (cursor->rop) {		case ROP_XOR:			for (i = 0; i < size; i++)				src[i] = dat[i] ^ msk[i];			break;		case ROP_COPY:		default:			for (i = 0; i < size; i++)				src[i] = dat[i] & msk[i];			break;		}		/* save the bitmap to restore it when XFree will		   make the cursor dirty */		memcpy(dinfo->cursor_src, src, size);		intelfbhw_cursor_load(dinfo, cursor->image.width,				      cursor->image.height, src);	}	if (cursor->enable)		intelfbhw_cursor_show(dinfo);	return 0;}static int intelfb_sync(struct fb_info *info){        struct intelfb_info *dinfo = GET_DINFO(info);#if VERBOSE > 0	DBG_MSG("intelfb_sync\n");#endif	if (dinfo->ring_lockup)		return 0;	intelfbhw_do_sync(dinfo);	return 0;}

⌨️ 快捷键说明

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