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

📄 fbdev.c

📁 linux-2.6.15.6
💻 C
📖 第 1 页 / 共 4 页
字号:
		NVTRACE("EXIT, returning -EINVAL\n");		return -EINVAL;	}	if (!strictmode) {		if (!info->monspecs.vfmax || !info->monspecs.hfmax ||		    !info->monspecs.dclkmax || !fb_validate_mode(var, info))			mode_valid = 1;	}	/* calculate modeline if supported by monitor */	if (!mode_valid && info->monspecs.gtf) {		if (!fb_get_mode(FB_MAXTIMINGS, 0, var, info))			mode_valid = 1;	}	if (!mode_valid) {		mode = fb_find_best_mode(var, &info->modelist);		if (mode) {			riva_update_var(var, mode);			mode_valid = 1;		}	}	if (!mode_valid && info->monspecs.modedb_len)		return -EINVAL;	if (var->xres_virtual < var->xres)		var->xres_virtual = var->xres;	if (var->yres_virtual <= var->yres)		var->yres_virtual = -1;	if (rivafb_do_maximize(info, var, nom, den) < 0)		return -EINVAL;	if (var->xoffset < 0)		var->xoffset = 0;	if (var->yoffset < 0)		var->yoffset = 0;	/* truncate xoffset and yoffset to maximum if too high */	if (var->xoffset > var->xres_virtual - var->xres)		var->xoffset = var->xres_virtual - var->xres - 1;	if (var->yoffset > var->yres_virtual - var->yres)		var->yoffset = var->yres_virtual - var->yres - 1;	var->red.msb_right = 	    var->green.msb_right =	    var->blue.msb_right =	    var->transp.offset = var->transp.length = var->transp.msb_right = 0;	NVTRACE_LEAVE();	return 0;}static int rivafb_set_par(struct fb_info *info){	struct riva_par *par = (struct riva_par *) info->par;	NVTRACE_ENTER();	/* vgaHWunlock() + riva unlock (0x7F) */	CRTCout(par, 0x11, 0xFF);	par->riva.LockUnlock(&par->riva, 0);	riva_load_video_mode(info);	if(!(info->flags & FBINFO_HWACCEL_DISABLED))		riva_setup_accel(info);		par->cursor_reset = 1;	info->fix.line_length = (info->var.xres_virtual * (info->var.bits_per_pixel >> 3));	info->fix.visual = (info->var.bits_per_pixel == 8) ?				FB_VISUAL_PSEUDOCOLOR : FB_VISUAL_DIRECTCOLOR;	if (info->flags & FBINFO_HWACCEL_DISABLED)		info->pixmap.scan_align = 1;	else		info->pixmap.scan_align = 4;	NVTRACE_LEAVE();	return 0;}/** * rivafb_pan_display * @var: standard kernel fb changeable data * @con: TODO * @info: pointer to fb_info object containing info for current riva board * * DESCRIPTION: * Pan (or wrap, depending on the `vmode' field) the display using the * `xoffset' and `yoffset' fields of the `var' structure. * If the values don't fit, return -EINVAL. * * This call looks only at xoffset, yoffset and the FB_VMODE_YWRAP flag */static int rivafb_pan_display(struct fb_var_screeninfo *var,			      struct fb_info *info){	struct riva_par *par = (struct riva_par *)info->par;	unsigned int base;	NVTRACE_ENTER();	if (var->xoffset > (var->xres_virtual - var->xres))		return -EINVAL;	if (var->yoffset > (var->yres_virtual - var->yres))		return -EINVAL;	if (var->vmode & FB_VMODE_YWRAP) {		if (var->yoffset < 0		    || var->yoffset >= info->var.yres_virtual		    || var->xoffset) return -EINVAL;	} else {		if (var->xoffset + info->var.xres > info->var.xres_virtual ||		    var->yoffset + info->var.yres > info->var.yres_virtual)			return -EINVAL;	}	base = var->yoffset * info->fix.line_length + var->xoffset;	par->riva.SetStartAddress(&par->riva, base);	info->var.xoffset = var->xoffset;	info->var.yoffset = var->yoffset;	if (var->vmode & FB_VMODE_YWRAP)		info->var.vmode |= FB_VMODE_YWRAP;	else		info->var.vmode &= ~FB_VMODE_YWRAP;	NVTRACE_LEAVE();	return 0;}static int rivafb_blank(int blank, struct fb_info *info){	struct riva_par *par= (struct riva_par *)info->par;	unsigned char tmp, vesa;	tmp = SEQin(par, 0x01) & ~0x20;	/* screen on/off */	vesa = CRTCin(par, 0x1a) & ~0xc0;	/* sync on/off */	NVTRACE_ENTER();	if (blank)		tmp |= 0x20;	switch (blank) {	case FB_BLANK_UNBLANK:	case FB_BLANK_NORMAL:		break;	case FB_BLANK_VSYNC_SUSPEND:		vesa |= 0x80;		break;	case FB_BLANK_HSYNC_SUSPEND:		vesa |= 0x40;		break;	case FB_BLANK_POWERDOWN:		vesa |= 0xc0;		break;	}	SEQout(par, 0x01, tmp);	CRTCout(par, 0x1a, vesa);#ifdef CONFIG_PMAC_BACKLIGHT	if ( par->FlatPanel && _machine == _MACH_Pmac) {		set_backlight_enable(!blank);	}#endif	NVTRACE_LEAVE();	return 0;}/** * rivafb_setcolreg * @regno: register index * @red: red component * @green: green component * @blue: blue component * @transp: transparency * @info: pointer to fb_info object containing info for current riva board * * DESCRIPTION: * Set a single color register. The values supplied have a 16 bit * magnitude. * * RETURNS: * Return != 0 for invalid regno. * * CALLED FROM: * fbcmap.c:fb_set_cmap() */static int rivafb_setcolreg(unsigned regno, unsigned red, unsigned green,			  unsigned blue, unsigned transp,			  struct fb_info *info){	struct riva_par *par = (struct riva_par *)info->par;	RIVA_HW_INST *chip = &par->riva;	int i;	if (regno >= riva_get_cmap_len(&info->var))			return -EINVAL;	if (info->var.grayscale) {		/* gray = 0.30*R + 0.59*G + 0.11*B */		red = green = blue =		    (red * 77 + green * 151 + blue * 28) >> 8;	}	if (regno < 16 && info->fix.visual == FB_VISUAL_DIRECTCOLOR) {		((u32 *) info->pseudo_palette)[regno] =			(regno << info->var.red.offset) |			(regno << info->var.green.offset) |			(regno << info->var.blue.offset);		/*		 * The Riva128 2D engine requires color information in		 * TrueColor format even if framebuffer is in DirectColor		 */		if (par->riva.Architecture == NV_ARCH_03) {			switch (info->var.bits_per_pixel) {			case 16:				par->palette[regno] = ((red & 0xf800) >> 1) |					((green & 0xf800) >> 6) |					((blue & 0xf800) >> 11);				break;			case 32:				par->palette[regno] = ((red & 0xff00) << 8) |					((green & 0xff00)) |					((blue & 0xff00) >> 8);				break;			}		}	}	switch (info->var.bits_per_pixel) {	case 8:		/* "transparent" stuff is completely ignored. */		riva_wclut(chip, regno, red >> 8, green >> 8, blue >> 8);		break;	case 16:		if (info->var.green.length == 5) {			for (i = 0; i < 8; i++) {				riva_wclut(chip, regno*8+i, red >> 8,					   green >> 8, blue >> 8);			}		} else {			u8 r, g, b;			if (regno < 32) {				for (i = 0; i < 8; i++) {					riva_wclut(chip, regno*8+i,						   red >> 8, green >> 8,						   blue >> 8);				}			}			riva_rclut(chip, regno*4, &r, &g, &b);			for (i = 0; i < 4; i++)				riva_wclut(chip, regno*4+i, r,					   green >> 8, b);		}		break;	case 32:		riva_wclut(chip, regno, red >> 8, green >> 8, blue >> 8);		break;	default:		/* do nothing */		break;	}	return 0;}/** * rivafb_fillrect - hardware accelerated color fill function * @info: pointer to fb_info structure * @rect: pointer to fb_fillrect structure * * DESCRIPTION: * This function fills up a region of framebuffer memory with a solid * color with a choice of two different ROP's, copy or invert. * * CALLED FROM: * framebuffer hook */static void rivafb_fillrect(struct fb_info *info, const struct fb_fillrect *rect){	struct riva_par *par = (struct riva_par *) info->par;	u_int color, rop = 0;	if ((info->flags & FBINFO_HWACCEL_DISABLED)) {		cfb_fillrect(info, rect);		return;	}	if (info->var.bits_per_pixel == 8)		color = rect->color;	else {		if (par->riva.Architecture != NV_ARCH_03)			color = ((u32 *)info->pseudo_palette)[rect->color];		else			color = par->palette[rect->color];	}	switch (rect->rop) {	case ROP_XOR:		rop = 0x66;		break;	case ROP_COPY:	default:		rop = 0xCC;		break;	}	riva_set_rop_solid(par, rop);	RIVA_FIFO_FREE(par->riva, Bitmap, 1);	NV_WR32(&par->riva.Bitmap->Color1A, 0, color);	RIVA_FIFO_FREE(par->riva, Bitmap, 2);	NV_WR32(&par->riva.Bitmap->UnclippedRectangle[0].TopLeft, 0,		(rect->dx << 16) | rect->dy);	mb();	NV_WR32(&par->riva.Bitmap->UnclippedRectangle[0].WidthHeight, 0,		(rect->width << 16) | rect->height);	mb();	riva_set_rop_solid(par, 0xcc);}/** * rivafb_copyarea - hardware accelerated blit function * @info: pointer to fb_info structure * @region: pointer to fb_copyarea structure * * DESCRIPTION: * This copies an area of pixels from one location to another * * CALLED FROM: * framebuffer hook */static void rivafb_copyarea(struct fb_info *info, const struct fb_copyarea *region){	struct riva_par *par = (struct riva_par *) info->par;	if ((info->flags & FBINFO_HWACCEL_DISABLED)) {		cfb_copyarea(info, region);		return;	}	RIVA_FIFO_FREE(par->riva, Blt, 3);	NV_WR32(&par->riva.Blt->TopLeftSrc, 0,		(region->sy << 16) | region->sx);	NV_WR32(&par->riva.Blt->TopLeftDst, 0,		(region->dy << 16) | region->dx);	mb();	NV_WR32(&par->riva.Blt->WidthHeight, 0,		(region->height << 16) | region->width);	mb();}static inline void convert_bgcolor_16(u32 *col){	*col = ((*col & 0x0000F800) << 8)		| ((*col & 0x00007E0) << 5)		| ((*col & 0x0000001F) << 3)		|	   0xFF000000;	mb();}/** * rivafb_imageblit: hardware accelerated color expand function * @info: pointer to fb_info structure * @image: pointer to fb_image structure * * DESCRIPTION: * If the source is a monochrome bitmap, the function fills up a a region * of framebuffer memory with pixels whose color is determined by the bit * setting of the bitmap, 1 - foreground, 0 - background. * * If the source is not a monochrome bitmap, color expansion is not done. * In this case, it is channeled to a software function. * * CALLED FROM: * framebuffer hook */static void rivafb_imageblit(struct fb_info *info, 			     const struct fb_image *image){	struct riva_par *par = (struct riva_par *) info->par;	u32 fgx = 0, bgx = 0, width, tmp;	u8 *cdat = (u8 *) image->data;	volatile u32 __iomem *d;	int i, size;	if ((info->flags & FBINFO_HWACCEL_DISABLED) || image->depth != 1) {		cfb_imageblit(info, image);		return;	}	switch (info->var.bits_per_pixel) {	case 8:		fgx = image->fg_color;		bgx = image->bg_color;		break;	case 16:	case 32:		if (par->riva.Architecture != NV_ARCH_03) {			fgx = ((u32 *)info->pseudo_palette)[image->fg_color];			bgx = ((u32 *)info->pseudo_palette)[image->bg_color];		} else {			fgx = par->palette[image->fg_color];			bgx = par->palette[image->bg_color];		}		if (info->var.green.length == 6)			convert_bgcolor_16(&bgx);			break;	}	RIVA_FIFO_FREE(par->riva, Bitmap, 7);	NV_WR32(&par->riva.Bitmap->ClipE.TopLeft, 0,		(image->dy << 16) | (image->dx & 0xFFFF));	NV_WR32(&par->riva.Bitmap->ClipE.BottomRight, 0,		(((image->dy + image->height) << 16) |		 ((image->dx + image->width) & 0xffff)));	NV_WR32(&par->riva.Bitmap->Color0E, 0, bgx);	NV_WR32(&par->riva.Bitmap->Color1E, 0, fgx);	NV_WR32(&par->riva.Bitmap->WidthHeightInE, 0,		(image->height << 16) | ((image->width + 31) & ~31));	NV_WR32(&par->riva.Bitmap->WidthHeightOutE, 0,		(image->height << 16) | ((image->width + 31) & ~31));	NV_WR32(&par->riva.Bitmap->PointE, 0,		(image->dy << 16) | (image->dx & 0xFFFF));	d = &par->riva.Bitmap->MonochromeData01E;	width = (image->width + 31)/32;	size = width * image->height;	while (size >= 16) {		RIVA_FIFO_FREE(par->riva, Bitmap, 16);		for (i = 0; i < 16; i++) {			tmp = *((u32 *)cdat);			cdat = (u8 *)((u32 *)cdat + 1);			reverse_order(&tmp);			NV_WR32(d, i*4, tmp);		}		size -= 16;	}	if (size) {		RIVA_FIFO_FREE(par->riva, Bitmap, size);		for (i = 0; i < size; i++) {			tmp = *((u32 *) cdat);			cdat = (u8 *)((u32 *)cdat + 1);			reverse_order(&tmp);			NV_WR32(d, i*4, tmp);		}	}}/** * rivafb_cursor - hardware cursor function * @info: pointer to info structure * @cursor: pointer to fbcursor structure * * DESCRIPTION: * A cursor function that supports displaying a cursor image via hardware. * Within the kernel, copy and invert rops are supported.  If exported * to user space, only the copy rop will be supported. * * CALLED FROM * framebuffer hook */static int rivafb_cursor(struct fb_info *info, struct fb_cursor *cursor){	struct riva_par *par = (struct riva_par *) info->par;	u8 data[MAX_CURS * MAX_CURS/8];	int i, set = cursor->set;	u16 fg, bg;	if (cursor->image.width > MAX_CURS || cursor->image.height > MAX_CURS)		return -ENXIO;	par->riva.ShowHideCursor(&par->riva, 0);	if (par->cursor_reset) {		set = FB_CUR_SETALL;		par->cursor_reset = 0;	}	if (set & FB_CUR_SETSIZE)		memset_io(par->riva.CURSOR, 0, MAX_CURS * MAX_CURS * 2);	if (set & FB_CUR_SETPOS) {		u32 xx, yy, temp;		yy = cursor->image.dy - info->var.yoffset;		xx = cursor->image.dx - info->var.xoffset;		temp = xx & 0xFFFF;		temp |= yy << 16;		NV_WR32(par->riva.PRAMDAC, 0x0000300, temp);	}	if (set & (FB_CUR_SETSHAPE | FB_CUR_SETCMAP | FB_CUR_SETIMAGE)) {		u32 bg_idx = cursor->image.bg_color;		u32 fg_idx = cursor->image.fg_color;		u32 s_pitch = (cursor->image.width+7) >> 3;		u32 d_pitch = MAX_CURS/8;		u8 *dat = (u8 *) cursor->image.data;		u8 *msk = (u8 *) cursor->mask;		u8 *src;				src = kmalloc(s_pitch * cursor->image.height, GFP_ATOMIC);		if (src) {			switch (cursor->rop) {			case ROP_XOR:				for (i = 0; i < s_pitch * cursor->image.height; i++)					src[i] = dat[i] ^ msk[i];				break;			case ROP_COPY:			default:				for (i = 0; i < s_pitch * cursor->image.height; i++)					src[i] = dat[i] & msk[i];				break;			}			fb_pad_aligned_buffer(data, d_pitch, src, s_pitch,						cursor->image.height);			bg = ((info->cmap.red[bg_idx] & 0xf8) << 7) |				((info->cmap.green[bg_idx] & 0xf8) << 2) |				((info->cmap.blue[bg_idx] & 0xf8) >> 3) |				1 << 15;			fg = ((info->cmap.red[fg_idx] & 0xf8) << 7) |				((info->cmap.green[fg_idx] & 0xf8) << 2) |				((info->cmap.blue[fg_idx] & 0xf8) >> 3) |				1 << 15;			par->riva.LockUnlock(&par->riva, 0);			rivafb_load_cursor_image(par, data, bg, fg,						 cursor->image.width,						 cursor->image.height);			kfree(src);		}	}	if (cursor->enable)		par->riva.ShowHideCursor(&par->riva, 1);	return 0;}static int rivafb_sync(struct fb_info *info){	struct riva_par *par = (struct riva_par *)info->par;

⌨️ 快捷键说明

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