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

📄 fbdev.c

📁 linux-2.6.15.6
💻 C
📖 第 1 页 / 共 4 页
字号:
	for (i = 0; i < NUM_ATC_REGS; i++)		regs->attr[i] = ATTRin(par, i);	for (i = 0; i < NUM_GRC_REGS; i++)		regs->gra[i] = GRAin(par, i);	for (i = 0; i < NUM_SEQ_REGS; i++)		regs->seq[i] = SEQin(par, i);	NVTRACE_LEAVE();}/** * riva_load_state - loads current chip state * @par: pointer to riva_par object containing info for current riva board * @regs: pointer to riva_regs object * * DESCRIPTION: * Loads chip state from @regs. * * CALLED FROM: * riva_load_video_mode() * rivafb_probe() * rivafb_remove() *//* from GGI */static void riva_load_state(struct riva_par *par, struct riva_regs *regs){	RIVA_HW_STATE *state = &regs->ext;	int i;	NVTRACE_ENTER();	CRTCout(par, 0x11, 0x00);	par->riva.LockUnlock(&par->riva, 0);	par->riva.LoadStateExt(&par->riva, state);	MISCout(par, regs->misc_output);	for (i = 0; i < NUM_CRT_REGS; i++) {		switch (i) {		case 0x19:		case 0x20 ... 0x40:			break;		default:			CRTCout(par, i, regs->crtc[i]);		}	}	for (i = 0; i < NUM_ATC_REGS; i++)		ATTRout(par, i, regs->attr[i]);	for (i = 0; i < NUM_GRC_REGS; i++)		GRAout(par, i, regs->gra[i]);	for (i = 0; i < NUM_SEQ_REGS; i++)		SEQout(par, i, regs->seq[i]);	NVTRACE_LEAVE();}/** * riva_load_video_mode - calculate timings * @info: pointer to fb_info object containing info for current riva board * * DESCRIPTION: * Calculate some timings and then send em off to riva_load_state(). * * CALLED FROM: * rivafb_set_par() */static void riva_load_video_mode(struct fb_info *info){	int bpp, width, hDisplaySize, hDisplay, hStart,	    hEnd, hTotal, height, vDisplay, vStart, vEnd, vTotal, dotClock;	int hBlankStart, hBlankEnd, vBlankStart, vBlankEnd;	struct riva_par *par = (struct riva_par *) info->par;	struct riva_regs newmode;		NVTRACE_ENTER();	/* time to calculate */	rivafb_blank(1, info);	bpp = info->var.bits_per_pixel;	if (bpp == 16 && info->var.green.length == 5)		bpp = 15;	width = info->var.xres_virtual;	hDisplaySize = info->var.xres;	hDisplay = (hDisplaySize / 8) - 1;	hStart = (hDisplaySize + info->var.right_margin) / 8 - 1;	hEnd = (hDisplaySize + info->var.right_margin +		info->var.hsync_len) / 8 - 1;	hTotal = (hDisplaySize + info->var.right_margin +		  info->var.hsync_len + info->var.left_margin) / 8 - 5;	hBlankStart = hDisplay;	hBlankEnd = hTotal + 4;	height = info->var.yres_virtual;	vDisplay = info->var.yres - 1;	vStart = info->var.yres + info->var.lower_margin - 1;	vEnd = info->var.yres + info->var.lower_margin +	       info->var.vsync_len - 1;	vTotal = info->var.yres + info->var.lower_margin +		 info->var.vsync_len + info->var.upper_margin + 2;	vBlankStart = vDisplay;	vBlankEnd = vTotal + 1;	dotClock = 1000000000 / info->var.pixclock;	memcpy(&newmode, &reg_template, sizeof(struct riva_regs));	if ((info->var.vmode & FB_VMODE_MASK) == FB_VMODE_INTERLACED)		vTotal |= 1;	if (par->FlatPanel) {		vStart = vTotal - 3;		vEnd = vTotal - 2;		vBlankStart = vStart;		hStart = hTotal - 3;		hEnd = hTotal - 2;		hBlankEnd = hTotal + 4;	}	newmode.crtc[0x0] = Set8Bits (hTotal); 	newmode.crtc[0x1] = Set8Bits (hDisplay);	newmode.crtc[0x2] = Set8Bits (hBlankStart);	newmode.crtc[0x3] = SetBitField (hBlankEnd, 4: 0, 4:0) | SetBit (7);	newmode.crtc[0x4] = Set8Bits (hStart);	newmode.crtc[0x5] = SetBitField (hBlankEnd, 5: 5, 7:7)		| SetBitField (hEnd, 4: 0, 4:0);	newmode.crtc[0x6] = SetBitField (vTotal, 7: 0, 7:0);	newmode.crtc[0x7] = SetBitField (vTotal, 8: 8, 0:0)		| SetBitField (vDisplay, 8: 8, 1:1)		| SetBitField (vStart, 8: 8, 2:2)		| SetBitField (vBlankStart, 8: 8, 3:3)		| SetBit (4)		| SetBitField (vTotal, 9: 9, 5:5)		| SetBitField (vDisplay, 9: 9, 6:6)		| SetBitField (vStart, 9: 9, 7:7);	newmode.crtc[0x9] = SetBitField (vBlankStart, 9: 9, 5:5)		| SetBit (6);	newmode.crtc[0x10] = Set8Bits (vStart);	newmode.crtc[0x11] = SetBitField (vEnd, 3: 0, 3:0)		| SetBit (5);	newmode.crtc[0x12] = Set8Bits (vDisplay);	newmode.crtc[0x13] = (width / 8) * ((bpp + 1) / 8);	newmode.crtc[0x15] = Set8Bits (vBlankStart);	newmode.crtc[0x16] = Set8Bits (vBlankEnd);	newmode.ext.screen = SetBitField(hBlankEnd,6:6,4:4)		| SetBitField(vBlankStart,10:10,3:3)		| SetBitField(vStart,10:10,2:2)		| SetBitField(vDisplay,10:10,1:1)		| SetBitField(vTotal,10:10,0:0);	newmode.ext.horiz  = SetBitField(hTotal,8:8,0:0) 		| SetBitField(hDisplay,8:8,1:1)		| SetBitField(hBlankStart,8:8,2:2)		| SetBitField(hStart,8:8,3:3);	newmode.ext.extra  = SetBitField(vTotal,11:11,0:0)		| SetBitField(vDisplay,11:11,2:2)		| SetBitField(vStart,11:11,4:4)		| SetBitField(vBlankStart,11:11,6:6); 	if ((info->var.vmode & FB_VMODE_MASK) == FB_VMODE_INTERLACED) {		int tmp = (hTotal >> 1) & ~1;		newmode.ext.interlace = Set8Bits(tmp);		newmode.ext.horiz |= SetBitField(tmp, 8:8,4:4);	} else 		newmode.ext.interlace = 0xff; /* interlace off */	if (par->riva.Architecture >= NV_ARCH_10)		par->riva.CURSOR = (U032 __iomem *)(info->screen_base + par->riva.CursorStart);	if (info->var.sync & FB_SYNC_HOR_HIGH_ACT)		newmode.misc_output &= ~0x40;	else		newmode.misc_output |= 0x40;	if (info->var.sync & FB_SYNC_VERT_HIGH_ACT)		newmode.misc_output &= ~0x80;	else		newmode.misc_output |= 0x80;		par->riva.CalcStateExt(&par->riva, &newmode.ext, bpp, width,				  hDisplaySize, height, dotClock);	newmode.ext.scale = NV_RD32(par->riva.PRAMDAC, 0x00000848) &		0xfff000ff;	if (par->FlatPanel == 1) {		newmode.ext.pixel |= (1 << 7);		newmode.ext.scale |= (1 << 8);	}	if (par->SecondCRTC) {		newmode.ext.head  = NV_RD32(par->riva.PCRTC0, 0x00000860) &			~0x00001000;		newmode.ext.head2 = NV_RD32(par->riva.PCRTC0, 0x00002860) |			0x00001000;		newmode.ext.crtcOwner = 3;		newmode.ext.pllsel |= 0x20000800;		newmode.ext.vpll2 = newmode.ext.vpll;	} else if (par->riva.twoHeads) {		newmode.ext.head  =  NV_RD32(par->riva.PCRTC0, 0x00000860) |			0x00001000;		newmode.ext.head2 =  NV_RD32(par->riva.PCRTC0, 0x00002860) &			~0x00001000;		newmode.ext.crtcOwner = 0;		newmode.ext.vpll2 = NV_RD32(par->riva.PRAMDAC0, 0x00000520);	}	if (par->FlatPanel == 1) {		newmode.ext.pixel |= (1 << 7);		newmode.ext.scale |= (1 << 8);	}	newmode.ext.cursorConfig = 0x02000100;	par->current_state = newmode;	riva_load_state(par, &par->current_state);	par->riva.LockUnlock(&par->riva, 0); /* important for HW cursor */	rivafb_blank(0, info);	NVTRACE_LEAVE();}static void riva_update_var(struct fb_var_screeninfo *var, struct fb_videomode *modedb){	NVTRACE_ENTER();	var->xres = var->xres_virtual = modedb->xres;	var->yres = modedb->yres;        if (var->yres_virtual < var->yres)	    var->yres_virtual = var->yres;        var->xoffset = var->yoffset = 0;        var->pixclock = modedb->pixclock;        var->left_margin = modedb->left_margin;        var->right_margin = modedb->right_margin;        var->upper_margin = modedb->upper_margin;        var->lower_margin = modedb->lower_margin;        var->hsync_len = modedb->hsync_len;        var->vsync_len = modedb->vsync_len;        var->sync = modedb->sync;        var->vmode = modedb->vmode;	NVTRACE_LEAVE();}/** * rivafb_do_maximize -  * @info: pointer to fb_info object containing info for current riva board * @var: * @nom: * @den: * * DESCRIPTION: * . * * RETURNS: * -EINVAL on failure, 0 on success *  * * CALLED FROM: * rivafb_check_var() */static int rivafb_do_maximize(struct fb_info *info,			      struct fb_var_screeninfo *var,			      int nom, int den){	static struct {		int xres, yres;	} modes[] = {		{1600, 1280},		{1280, 1024},		{1024, 768},		{800, 600},		{640, 480},		{-1, -1}	};	int i;	NVTRACE_ENTER();	/* use highest possible virtual resolution */	if (var->xres_virtual == -1 && var->yres_virtual == -1) {		printk(KERN_WARNING PFX		       "using maximum available virtual resolution\n");		for (i = 0; modes[i].xres != -1; i++) {			if (modes[i].xres * nom / den * modes[i].yres <			    info->fix.smem_len)				break;		}		if (modes[i].xres == -1) {			printk(KERN_ERR PFX			       "could not find a virtual resolution that fits into video memory!!\n");			NVTRACE("EXIT - EINVAL error\n");			return -EINVAL;		}		var->xres_virtual = modes[i].xres;		var->yres_virtual = modes[i].yres;		printk(KERN_INFO PFX		       "virtual resolution set to maximum of %dx%d\n",		       var->xres_virtual, var->yres_virtual);	} else if (var->xres_virtual == -1) {		var->xres_virtual = (info->fix.smem_len * den /			(nom * var->yres_virtual)) & ~15;		printk(KERN_WARNING PFX		       "setting virtual X resolution to %d\n", var->xres_virtual);	} else if (var->yres_virtual == -1) {		var->xres_virtual = (var->xres_virtual + 15) & ~15;		var->yres_virtual = info->fix.smem_len * den /			(nom * var->xres_virtual);		printk(KERN_WARNING PFX		       "setting virtual Y resolution to %d\n", var->yres_virtual);	} else {		var->xres_virtual = (var->xres_virtual + 15) & ~15;		if (var->xres_virtual * nom / den * var->yres_virtual > info->fix.smem_len) {			printk(KERN_ERR PFX			       "mode %dx%dx%d rejected...resolution too high to fit into video memory!\n",			       var->xres, var->yres, var->bits_per_pixel);			NVTRACE("EXIT - EINVAL error\n");			return -EINVAL;		}	}		if (var->xres_virtual * nom / den >= 8192) {		printk(KERN_WARNING PFX		       "virtual X resolution (%d) is too high, lowering to %d\n",		       var->xres_virtual, 8192 * den / nom - 16);		var->xres_virtual = 8192 * den / nom - 16;	}		if (var->xres_virtual < var->xres) {		printk(KERN_ERR PFX		       "virtual X resolution (%d) is smaller than real\n", var->xres_virtual);		return -EINVAL;	}	if (var->yres_virtual < var->yres) {		printk(KERN_ERR PFX		       "virtual Y resolution (%d) is smaller than real\n", var->yres_virtual);		return -EINVAL;	}	if (var->yres_virtual > 0x7fff/nom)		var->yres_virtual = 0x7fff/nom;	if (var->xres_virtual > 0x7fff/nom)		var->xres_virtual = 0x7fff/nom;	NVTRACE_LEAVE();	return 0;}static voidriva_set_pattern(struct riva_par *par, int clr0, int clr1, int pat0, int pat1){	RIVA_FIFO_FREE(par->riva, Patt, 4);	NV_WR32(&par->riva.Patt->Color0, 0, clr0);	NV_WR32(&par->riva.Patt->Color1, 0, clr1);	NV_WR32(par->riva.Patt->Monochrome, 0, pat0);	NV_WR32(par->riva.Patt->Monochrome, 4, pat1);}/* acceleration routines */static inline void wait_for_idle(struct riva_par *par){	while (par->riva.Busy(&par->riva));}/* * Set ROP.  Translate X rop into ROP3.  Internal routine. */static voidriva_set_rop_solid(struct riva_par *par, int rop){	riva_set_pattern(par, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF);        RIVA_FIFO_FREE(par->riva, Rop, 1);        NV_WR32(&par->riva.Rop->Rop3, 0, rop);}static void riva_setup_accel(struct fb_info *info){	struct riva_par *par = (struct riva_par *) info->par;	RIVA_FIFO_FREE(par->riva, Clip, 2);	NV_WR32(&par->riva.Clip->TopLeft, 0, 0x0);	NV_WR32(&par->riva.Clip->WidthHeight, 0,		(info->var.xres_virtual & 0xffff) |		(info->var.yres_virtual << 16));	riva_set_rop_solid(par, 0xcc);	wait_for_idle(par);}/** * riva_get_cmap_len - query current color map length * @var: standard kernel fb changeable data * * DESCRIPTION: * Get current color map length. * * RETURNS: * Length of color map * * CALLED FROM: * rivafb_setcolreg() */static int riva_get_cmap_len(const struct fb_var_screeninfo *var){	int rc = 256;		/* reasonable default */	switch (var->green.length) {	case 8:		rc = 256;	/* 256 entries (2^8), 8 bpp and RGB8888 */		break;	case 5:		rc = 32;	/* 32 entries (2^5), 16 bpp, RGB555 */		break;	case 6:		rc = 64;	/* 64 entries (2^6), 16 bpp, RGB565 */		break;			default:		/* should not occur */		break;	}	return rc;}/* ------------------------------------------------------------------------- * * * Backlight operations * * ------------------------------------------------------------------------- */#ifdef CONFIG_PMAC_BACKLIGHTstatic int riva_set_backlight_enable(int on, int level, void *data){	struct riva_par *par = (struct riva_par *)data;	U032 tmp_pcrt, tmp_pmc;	tmp_pmc = par->riva.PMC[0x10F0/4] & 0x0000FFFF;	tmp_pcrt = par->riva.PCRTC0[0x081C/4] & 0xFFFFFFFC;	if(on && (level > BACKLIGHT_OFF)) {		tmp_pcrt |= 0x1;		tmp_pmc |= (1 << 31); // backlight bit		tmp_pmc |= riva_backlight_levels[level-1] << 16; // level	}	par->riva.PCRTC0[0x081C/4] = tmp_pcrt;	par->riva.PMC[0x10F0/4] = tmp_pmc;	return 0;}static int riva_set_backlight_level(int level, void *data){	return riva_set_backlight_enable(1, level, data);}#endif /* CONFIG_PMAC_BACKLIGHT *//* ------------------------------------------------------------------------- * * * framebuffer operations * * ------------------------------------------------------------------------- */static int rivafb_open(struct fb_info *info, int user){	struct riva_par *par = (struct riva_par *) info->par;	int cnt = atomic_read(&par->ref_count);	NVTRACE_ENTER();	if (!cnt) {#ifdef CONFIG_X86		memset(&par->state, 0, sizeof(struct vgastate));		par->state.flags = VGA_SAVE_MODE  | VGA_SAVE_FONTS;		/* save the DAC for Riva128 */		if (par->riva.Architecture == NV_ARCH_03)			par->state.flags |= VGA_SAVE_CMAP;		save_vga(&par->state);#endif		/* vgaHWunlock() + riva unlock (0x7F) */		CRTCout(par, 0x11, 0xFF);		par->riva.LockUnlock(&par->riva, 0);			riva_save_state(par, &par->initial_state);	}	atomic_inc(&par->ref_count);	NVTRACE_LEAVE();	return 0;}static int rivafb_release(struct fb_info *info, int user){	struct riva_par *par = (struct riva_par *) info->par;	int cnt = atomic_read(&par->ref_count);	NVTRACE_ENTER();	if (!cnt)		return -EINVAL;	if (cnt == 1) {		par->riva.LockUnlock(&par->riva, 0);		par->riva.LoadStateExt(&par->riva, &par->initial_state.ext);		riva_load_state(par, &par->initial_state);#ifdef CONFIG_X86		restore_vga(&par->state);#endif		par->riva.LockUnlock(&par->riva, 1);	}	atomic_dec(&par->ref_count);	NVTRACE_LEAVE();	return 0;}static int rivafb_check_var(struct fb_var_screeninfo *var, struct fb_info *info){	struct fb_videomode *mode;	struct riva_par *par = (struct riva_par *) info->par;	int nom, den;		/* translating from pixels->bytes */	int mode_valid = 0;		NVTRACE_ENTER();	switch (var->bits_per_pixel) {	case 1 ... 8:		var->red.offset = var->green.offset = var->blue.offset = 0;		var->red.length = var->green.length = var->blue.length = 8;		var->bits_per_pixel = 8;		nom = den = 1;		break;	case 9 ... 15:		var->green.length = 5;		/* fall through */	case 16:		var->bits_per_pixel = 16;		/* The Riva128 supports RGB555 only */		if (par->riva.Architecture == NV_ARCH_03)			var->green.length = 5;		if (var->green.length == 5) {			/* 0rrrrrgg gggbbbbb */			var->red.offset = 10;			var->green.offset = 5;			var->blue.offset = 0;			var->red.length = 5;			var->green.length = 5;			var->blue.length = 5;		} else {			/* rrrrrggg gggbbbbb */			var->red.offset = 11;			var->green.offset = 5;			var->blue.offset = 0;			var->red.length = 5;			var->green.length = 6;			var->blue.length = 5;		}		nom = 2;		den = 1;		break;	case 17 ... 32:		var->red.length = var->green.length = var->blue.length = 8;		var->bits_per_pixel = 32;		var->red.offset = 16;		var->green.offset = 8;		var->blue.offset = 0;		nom = 4;		den = 1;		break;	default:		printk(KERN_ERR PFX		       "mode %dx%dx%d rejected...color depth not supported.\n",		       var->xres, var->yres, var->bits_per_pixel);

⌨️ 快捷键说明

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