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

📄 nvidia.c

📁 LINUX 2.6.17.4的源码
💻 C
📖 第 1 页 / 共 4 页
字号:
	if (par->cursor_reset) {		set = FB_CUR_SETALL;		par->cursor_reset = 0;	}	if (set & FB_CUR_SETSIZE)		memset_io(par->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->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;			NVLockUnlock(par, 0);			nvidiafb_load_cursor_image(par, data, bg, fg,						   cursor->image.width,						   cursor->image.height);			kfree(src);		}	}	if (cursor->enable)		NVShowHideCursor(par, 1);	return 0;}static int nvidiafb_set_par(struct fb_info *info){	struct nvidia_par *par = info->par;	NVTRACE_ENTER();	NVLockUnlock(par, 1);	if (!par->FlatPanel || !par->twoHeads)		par->FPDither = 0;	if (par->FPDither < 0) {		if ((par->Chipset & 0x0ff0) == 0x0110)			par->FPDither = !!(NV_RD32(par->PRAMDAC, 0x0528)					   & 0x00010000);		else			par->FPDither = !!(NV_RD32(par->PRAMDAC, 0x083C) & 1);		printk(KERN_INFO PFX "Flat panel dithering %s\n",		       par->FPDither ? "enabled" : "disabled");	}	info->fix.visual = (info->var.bits_per_pixel == 8) ?	    FB_VISUAL_PSEUDOCOLOR : FB_VISUAL_DIRECTCOLOR;	nvidia_init_vga(info);	nvidia_calc_regs(info);	NVLockUnlock(par, 0);	if (par->twoHeads) {		VGA_WR08(par->PCIO, 0x03D4, 0x44);		VGA_WR08(par->PCIO, 0x03D5, par->ModeReg.crtcOwner);		NVLockUnlock(par, 0);	}	nvidia_vga_protect(par, 1);	nvidia_write_regs(par, &par->ModeReg);	NVSetStartAddress(par, 0);#if defined (__BIG_ENDIAN)	/* turn on LFB swapping */	{		unsigned char tmp;		VGA_WR08(par->PCIO, 0x3d4, 0x46);		tmp = VGA_RD08(par->PCIO, 0x3d5);		tmp |= (1 << 7);		VGA_WR08(par->PCIO, 0x3d5, tmp);    }#endif	info->fix.line_length = (info->var.xres_virtual *				 info->var.bits_per_pixel) >> 3;	if (info->var.accel_flags) {		info->fbops->fb_imageblit = nvidiafb_imageblit;		info->fbops->fb_fillrect = nvidiafb_fillrect;		info->fbops->fb_copyarea = nvidiafb_copyarea;		info->fbops->fb_sync = nvidiafb_sync;		info->pixmap.scan_align = 4;		info->flags &= ~FBINFO_HWACCEL_DISABLED;		NVResetGraphics(info);	} else {		info->fbops->fb_imageblit = cfb_imageblit;		info->fbops->fb_fillrect = cfb_fillrect;		info->fbops->fb_copyarea = cfb_copyarea;		info->fbops->fb_sync = NULL;		info->pixmap.scan_align = 1;		info->flags |= FBINFO_HWACCEL_DISABLED;	}	par->cursor_reset = 1;	nvidia_vga_protect(par, 0);	NVTRACE_LEAVE();	return 0;}static int nvidiafb_setcolreg(unsigned regno, unsigned red, unsigned green,			      unsigned blue, unsigned transp,			      struct fb_info *info){	struct nvidia_par *par = info->par;	int i;	NVTRACE_ENTER();	if (regno >= (1 << info->var.green.length))		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);	}	switch (info->var.bits_per_pixel) {	case 8:		/* "transparent" stuff is completely ignored. */		nvidia_write_clut(par, regno, red >> 8, green >> 8, blue >> 8);		break;	case 16:		if (info->var.green.length == 5) {			for (i = 0; i < 8; i++) {				nvidia_write_clut(par, regno * 8 + i, red >> 8,						  green >> 8, blue >> 8);			}		} else {			u8 r, g, b;			if (regno < 32) {				for (i = 0; i < 8; i++) {					nvidia_write_clut(par, regno * 8 + i,							  red >> 8, green >> 8,							  blue >> 8);				}			}			nvidia_read_clut(par, regno * 4, &r, &g, &b);			for (i = 0; i < 4; i++)				nvidia_write_clut(par, regno * 4 + i, r,						  green >> 8, b);		}		break;	case 32:		nvidia_write_clut(par, regno, red >> 8, green >> 8, blue >> 8);		break;	default:		/* do nothing */		break;	}	NVTRACE_LEAVE();	return 0;}static int nvidiafb_check_var(struct fb_var_screeninfo *var,			      struct fb_info *info){	struct nvidia_par *par = info->par;	int memlen, vramlen, mode_valid = 0;	int pitch, err = 0;	NVTRACE_ENTER();	var->transp.offset = 0;	var->transp.length = 0;	var->xres &= ~7;	if (var->bits_per_pixel <= 8)		var->bits_per_pixel = 8;	else if (var->bits_per_pixel <= 16)		var->bits_per_pixel = 16;	else		var->bits_per_pixel = 32;	switch (var->bits_per_pixel) {	case 8:		var->red.offset = 0;		var->red.length = 8;		var->green.offset = 0;		var->green.length = 8;		var->blue.offset = 0;		var->blue.length = 8;		var->transp.offset = 0;		var->transp.length = 0;		break;	case 16:		var->green.length = (var->green.length < 6) ? 5 : 6;		var->red.length = 5;		var->blue.length = 5;		var->transp.length = 6 - var->green.length;		var->blue.offset = 0;		var->green.offset = 5;		var->red.offset = 5 + var->green.length;		var->transp.offset = (5 + var->red.offset) & 15;		break;	case 32:		/* RGBA 8888 */		var->red.offset = 16;		var->red.length = 8;		var->green.offset = 8;		var->green.length = 8;		var->blue.offset = 0;		var->blue.length = 8;		var->transp.length = 8;		var->transp.offset = 24;		break;	}	var->red.msb_right = 0;	var->green.msb_right = 0;	var->blue.msb_right = 0;	var->transp.msb_right = 0;	if (!info->monspecs.hfmax || !info->monspecs.vfmax ||	    !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) {		struct fb_videomode *mode;		mode = fb_find_best_mode(var, &info->modelist);		if (mode) {			fb_videomode_to_var(var, mode);			mode_valid = 1;		}	}	if (!mode_valid && info->monspecs.modedb_len)		return -EINVAL;	if (par->fpWidth && par->fpHeight && (par->fpWidth < var->xres ||					      par->fpHeight < var->yres))		return -EINVAL;	if (var->yres_virtual < var->yres)		var->yres_virtual = var->yres;	if (var->xres_virtual < var->xres)		var->xres_virtual = var->xres;	var->xres_virtual = (var->xres_virtual + 63) & ~63;	vramlen = info->screen_size;	pitch = ((var->xres_virtual * var->bits_per_pixel) + 7) / 8;	memlen = pitch * var->yres_virtual;	if (memlen > vramlen) {		var->yres_virtual = vramlen / pitch;		if (var->yres_virtual < var->yres) {			var->yres_virtual = var->yres;			var->xres_virtual = vramlen / var->yres_virtual;			var->xres_virtual /= var->bits_per_pixel / 8;			var->xres_virtual &= ~63;			pitch = (var->xres_virtual *				 var->bits_per_pixel + 7) / 8;			memlen = pitch * var->yres;			if (var->xres_virtual < var->xres) {				printk("nvidiafb: required video memory, "				       "%d bytes, for %dx%d-%d (virtual) "				       "is out of range\n",				       memlen, var->xres_virtual,				       var->yres_virtual, var->bits_per_pixel);				err = -ENOMEM;			}		}	}	if (var->accel_flags) {		if (var->yres_virtual > 0x7fff)			var->yres_virtual = 0x7fff;		if (var->xres_virtual > 0x7fff)			var->xres_virtual = 0x7fff;	}	var->xres_virtual &= ~63;	NVTRACE_LEAVE();	return err;}static int nvidiafb_pan_display(struct fb_var_screeninfo *var,				struct fb_info *info){	struct nvidia_par *par = info->par;	u32 total;	total = var->yoffset * info->fix.line_length + var->xoffset;	NVSetStartAddress(par, total);	return 0;}static int nvidiafb_blank(int blank, struct fb_info *info){	struct nvidia_par *par = info->par;	unsigned char tmp, vesa;	tmp = NVReadSeq(par, 0x01) & ~0x20;	/* screen on/off */	vesa = NVReadCrtc(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;	}	NVWriteSeq(par, 0x01, tmp);	NVWriteCrtc(par, 0x1a, vesa);#ifdef CONFIG_PMAC_BACKLIGHT	if (par->FlatPanel && machine_is(powermac)) {		set_backlight_enable(!blank);	}#endif	NVTRACE_LEAVE();	return 0;}static struct fb_ops nvidia_fb_ops = {	.owner          = THIS_MODULE,	.fb_check_var   = nvidiafb_check_var,	.fb_set_par     = nvidiafb_set_par,	.fb_setcolreg   = nvidiafb_setcolreg,	.fb_pan_display = nvidiafb_pan_display,	.fb_blank       = nvidiafb_blank,	.fb_fillrect    = nvidiafb_fillrect,	.fb_copyarea    = nvidiafb_copyarea,	.fb_imageblit   = nvidiafb_imageblit,	.fb_cursor      = nvidiafb_cursor,	.fb_sync        = nvidiafb_sync,};#ifdef CONFIG_PMstatic int nvidiafb_suspend(struct pci_dev *dev, pm_message_t state){	struct fb_info *info = pci_get_drvdata(dev);	struct nvidia_par *par = info->par;	acquire_console_sem();	par->pm_state = state.event;	if (state.event == PM_EVENT_FREEZE) {		dev->dev.power.power_state = state;	} else {		fb_set_suspend(info, 1);		nvidiafb_blank(FB_BLANK_POWERDOWN, info);		nvidia_write_regs(par, &par->SavedReg);		pci_save_state(dev);		pci_disable_device(dev);		pci_set_power_state(dev, pci_choose_state(dev, state));	}	release_console_sem();	return 0;}static int nvidiafb_resume(struct pci_dev *dev){	struct fb_info *info = pci_get_drvdata(dev);	struct nvidia_par *par = info->par;	acquire_console_sem();	pci_set_power_state(dev, PCI_D0);	if (par->pm_state != PM_EVENT_FREEZE) {		pci_restore_state(dev);		pci_enable_device(dev);		pci_set_master(dev);	}	par->pm_state = PM_EVENT_ON;	nvidiafb_set_par(info);	fb_set_suspend (info, 0);	nvidiafb_blank(FB_BLANK_UNBLANK, info);	release_console_sem();	return 0;}#else#define nvidiafb_suspend NULL#define nvidiafb_resume NULL#endifstatic int __devinit nvidia_set_fbinfo(struct fb_info *info){	struct fb_monspecs *specs = &info->monspecs;	struct fb_videomode modedb;	struct nvidia_par *par = info->par;	int lpitch;	NVTRACE_ENTER();	info->flags = FBINFO_DEFAULT	    | FBINFO_HWACCEL_IMAGEBLIT	    | FBINFO_HWACCEL_FILLRECT	    | FBINFO_HWACCEL_COPYAREA	    | FBINFO_HWACCEL_YPAN;	fb_videomode_to_modelist(info->monspecs.modedb,				 info->monspecs.modedb_len, &info->modelist);	fb_var_to_videomode(&modedb, &nvidiafb_default_var);	switch (bpp) {

⌨️ 快捷键说明

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