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

📄 matroxfb_base.c

📁 内核linux2.4.20,可跟rtlinux3.2打补丁 组成实时linux系统,编译内核
💻 C
📖 第 1 页 / 共 5 页
字号:
			hw->CRTC[0x0C] = (pos & 0xFF00) >> 8;			hw->CRTCEXT[0] = (hw->CRTCEXT[0] & 0xF0) | ((pos >> 16) & 0x0F) | ((pos >> 14) & 0x40);			hw->CRTCEXT[8] = pos >> 21;			if (ACCESS_FBINFO(output.ph) & (MATROXFB_OUTPUT_CONN_PRIMARY | MATROXFB_OUTPUT_CONN_DFP)) {				if (ACCESS_FBINFO(primout))					ACCESS_FBINFO(primout)->compute(MINFO, &mt, hw);			}			if (ACCESS_FBINFO(output.ph) & MATROXFB_OUTPUT_CONN_SECONDARY) {				down_read(&ACCESS_FBINFO(altout.lock));				if (ACCESS_FBINFO(altout.output))					ACCESS_FBINFO(altout.output)->compute(ACCESS_FBINFO(altout.device), &mt, hw);				up_read(&ACCESS_FBINFO(altout.lock));			}			ACCESS_FBINFO(hw_switch->restore(PMINFO hw, ohw, display));			if (ACCESS_FBINFO(output.ph) & (MATROXFB_OUTPUT_CONN_PRIMARY | MATROXFB_OUTPUT_CONN_DFP)) {				if (ACCESS_FBINFO(primout))					ACCESS_FBINFO(primout)->program(MINFO, hw);			}			if (ACCESS_FBINFO(output.ph) & MATROXFB_OUTPUT_CONN_SECONDARY) {				down_read(&ACCESS_FBINFO(altout.lock));				if (ACCESS_FBINFO(altout.output))					ACCESS_FBINFO(altout.output)->program(ACCESS_FBINFO(altout.device), hw);				up_read(&ACCESS_FBINFO(altout.lock));			}			ACCESS_FBINFO(cursor.redraw) = 1;			ACCESS_FBINFO(currenthw) = hw;			ACCESS_FBINFO(newhw) = ohw;			if (ACCESS_FBINFO(output.ph) & (MATROXFB_OUTPUT_CONN_PRIMARY | MATROXFB_OUTPUT_CONN_DFP)) {				if (ACCESS_FBINFO(primout))					ACCESS_FBINFO(primout)->start(MINFO);			}			if (ACCESS_FBINFO(output.ph) & MATROXFB_OUTPUT_CONN_SECONDARY) {				down_read(&ACCESS_FBINFO(altout.lock));				if (ACCESS_FBINFO(altout.output))					ACCESS_FBINFO(altout.output)->start(ACCESS_FBINFO(altout.device));				up_read(&ACCESS_FBINFO(altout.lock));			}			matrox_cfbX_init(PMINFO display);			do_install_cmap(PMINFO display);#if defined(CONFIG_FB_COMPAT_XPMAC)			if (console_fb_info == &ACCESS_FBINFO(fbcon)) {				int vmode, cmode;				display_info.width = var->xres;				display_info.height = var->yres;				display_info.depth = var->bits_per_pixel;				display_info.pitch = (var->xres_virtual)*(var->bits_per_pixel)/8;				if (mac_var_to_vmode(var, &vmode, &cmode))					display_info.mode = 0;				else					display_info.mode = vmode;				strcpy(display_info.name, ACCESS_FBINFO(matrox_name));				display_info.fb_address = ACCESS_FBINFO(video.base);				display_info.cmap_adr_address = 0;				display_info.cmap_data_address = 0;				display_info.disp_reg_address = ACCESS_FBINFO(mmio.base);			}#endif /* CONFIG_FB_COMPAT_XPMAC */		}	}	return 0;#undef minfo}static int matrox_getcolreg(unsigned regno, unsigned *red, unsigned *green,			    unsigned *blue, unsigned *transp,			    struct fb_info *info){	DBG("matrox_getcolreg")#define minfo ((struct matrox_fb_info*)info)	/*	 *  Read a single color register and split it into colors/transparent.	 *  Return != 0 for invalid regno.	 */	if (regno >= ACCESS_FBINFO(curr.cmap_len))		return 1;	*red   = ACCESS_FBINFO(palette[regno].red);	*green = ACCESS_FBINFO(palette[regno].green);	*blue  = ACCESS_FBINFO(palette[regno].blue);	*transp = ACCESS_FBINFO(palette[regno].transp);	return 0;#undef minfo}static int matroxfb_get_cmap(struct fb_cmap *cmap, int kspc, int con,			     struct fb_info *info){#define minfo ((struct matrox_fb_info*)info)	struct display* dsp = (con < 0) ? ACCESS_FBINFO(fbcon.disp)					: fb_display + con;	DBG("matroxfb_get_cmap")	if (ACCESS_FBINFO(dead)) {		return -ENXIO;	}	if (con == ACCESS_FBINFO(currcon)) /* current console? */		return fb_get_cmap(cmap, kspc, matrox_getcolreg, info);	else if (dsp->cmap.len) /* non default colormap? */		fb_copy_cmap(&dsp->cmap, cmap, kspc ? 0 : 2);	else		fb_copy_cmap(fb_default_cmap(matroxfb_get_cmap_len(&dsp->var)),			     cmap, kspc ? 0 : 2);	return 0;#undef minfo}static int matroxfb_set_cmap(struct fb_cmap *cmap, int kspc, int con,			     struct fb_info *info){	unsigned int cmap_len;	struct display* dsp = (con < 0) ? info->disp : (fb_display + con);#define minfo ((struct matrox_fb_info*)info)	DBG("matroxfb_set_cmap")	if (ACCESS_FBINFO(dead)) {		return -ENXIO;	}	cmap_len = matroxfb_get_cmap_len(&dsp->var);	if (dsp->cmap.len != cmap_len) {		int err;		err = fb_alloc_cmap(&dsp->cmap, cmap_len, 0);		if (err)			return err;	}	if (con == ACCESS_FBINFO(currcon)) {			/* current console? */		return fb_set_cmap(cmap, kspc, matrox_setcolreg, info);	} else		fb_copy_cmap(cmap, &dsp->cmap, kspc ? 0 : 1);	return 0;#undef minfo}static int matroxfb_get_vblank(CPMINFO struct fb_vblank *vblank){	unsigned int sts1;	memset(vblank, 0, sizeof(*vblank));	vblank->flags = FB_VBLANK_HAVE_VCOUNT | FB_VBLANK_HAVE_VSYNC |			FB_VBLANK_HAVE_VBLANK | FB_VBLANK_HAVE_HBLANK;	sts1 = mga_inb(M_INSTS1);	vblank->vcount = mga_inl(M_VCOUNT);	/* BTW, on my PIII/450 with G400, reading M_INSTS1	   byte makes this call about 12% slower (1.70 vs. 2.05 us	   per ioctl()) */	if (sts1 & 1)		vblank->flags |= FB_VBLANK_HBLANKING;	if (sts1 & 8)		vblank->flags |= FB_VBLANK_VSYNCING;	if (vblank->count >= ACCESS_FBINFO(currcon_display)->var.yres)		vblank->flags |= FB_VBLANK_VBLANKING;	vblank->hcount = 0;	vblank->count = 0;	return 0;}static int matroxfb_ioctl(struct inode *inode, struct file *file,			  unsigned int cmd, unsigned long arg, int con,			  struct fb_info *info){#define minfo ((struct matrox_fb_info*)info)	DBG("matroxfb_ioctl")	if (ACCESS_FBINFO(dead)) {		return -ENXIO;	}	switch (cmd) {		case FBIOGET_VBLANK:			{				struct fb_vblank vblank;				int err;				err = matroxfb_get_vblank(PMINFO &vblank);				if (err)					return err;				if (copy_to_user((struct fb_vblank*)arg, &vblank, sizeof(vblank)))					return -EFAULT;				return 0;			}		case MATROXFB_SET_OUTPUT_MODE:			{				struct matroxioc_output_mode mom;				int val;				if (copy_from_user(&mom, (struct matroxioc_output_mode*)arg, sizeof(mom)))					return -EFAULT;				if (mom.output >= sizeof(u_int32_t))					return -EINVAL;				switch (mom.output) {					case MATROXFB_OUTPUT_PRIMARY:						if (mom.mode != MATROXFB_OUTPUT_MODE_MONITOR)							return -EINVAL;						/* mode did not change... */						return 0;					case MATROXFB_OUTPUT_SECONDARY:						val = -EINVAL;						down_read(&ACCESS_FBINFO(altout.lock));						if (ACCESS_FBINFO(altout.output) && ACCESS_FBINFO(altout.device))							val = ACCESS_FBINFO(altout.output)->setmode(ACCESS_FBINFO(altout.device), mom.mode);						up_read(&ACCESS_FBINFO(altout.lock));						if (val != 1)							return val;						if (ACCESS_FBINFO(output.ph) & MATROXFB_OUTPUT_CONN_SECONDARY)							matroxfb_switch(ACCESS_FBINFO(currcon), info);						if (ACCESS_FBINFO(output.sh) & MATROXFB_OUTPUT_CONN_SECONDARY) {							struct matroxfb_dh_fb_info* crtc2;							down_read(&ACCESS_FBINFO(crtc2.lock));							crtc2 = (struct matroxfb_dh_fb_info*)(ACCESS_FBINFO(crtc2.info));							if (crtc2)								crtc2->fbcon.switch_con(crtc2->currcon, &crtc2->fbcon);							up_read(&ACCESS_FBINFO(crtc2.lock));						}						return 0;					case MATROXFB_OUTPUT_DFP:						if (!(ACCESS_FBINFO(output.all) & MATROXFB_OUTPUT_CONN_DFP))							return -ENXIO;						if (mom.mode!= MATROXFB_OUTPUT_MODE_MONITOR)							return -EINVAL;						/* mode did not change... */						return 0;					default:						return -EINVAL;				}				return 0;			}		case MATROXFB_GET_OUTPUT_MODE:			{				struct matroxioc_output_mode mom;				int val;				if (copy_from_user(&mom, (struct matroxioc_output_mode*)arg, sizeof(mom)))					return -EFAULT;				if (mom.output >= sizeof(u_int32_t))					return -EINVAL;				switch (mom.output) {					case MATROXFB_OUTPUT_PRIMARY:						mom.mode = MATROXFB_OUTPUT_MODE_MONITOR;						break;					case MATROXFB_OUTPUT_SECONDARY:						val = -EINVAL;						down_read(&ACCESS_FBINFO(altout.lock));						if (ACCESS_FBINFO(altout.output) && ACCESS_FBINFO(altout.device))							val = ACCESS_FBINFO(altout.output)->getmode(ACCESS_FBINFO(altout.device), &mom.mode);						up_read(&ACCESS_FBINFO(altout.lock));						if (val)							return val;						break;					case MATROXFB_OUTPUT_DFP:						if (!(ACCESS_FBINFO(output.all) & MATROXFB_OUTPUT_CONN_DFP))							return -ENXIO;						mom.mode = MATROXFB_OUTPUT_MODE_MONITOR;						break;					default:						return -EINVAL;				}				if (copy_to_user((struct matroxioc_output_mode*)arg, &mom, sizeof(mom)))					return -EFAULT;				return 0;			}		case MATROXFB_SET_OUTPUT_CONNECTION:			{				u_int32_t tmp;				if (copy_from_user(&tmp, (u_int32_t*)arg, sizeof(tmp)))					return -EFAULT;				if (tmp & ~ACCESS_FBINFO(output.all))					return -EINVAL;				if (tmp & ACCESS_FBINFO(output.sh))					return -EINVAL;				if (tmp & MATROXFB_OUTPUT_CONN_DFP) {					if (tmp & MATROXFB_OUTPUT_CONN_SECONDARY)						return -EINVAL;					if (ACCESS_FBINFO(output.sh))						return -EINVAL;				}				if (tmp == ACCESS_FBINFO(output.ph))					return 0;				ACCESS_FBINFO(output.ph) = tmp;				matroxfb_switch(ACCESS_FBINFO(currcon), info);				return 0;			}		case MATROXFB_GET_OUTPUT_CONNECTION:			{				if (put_user(ACCESS_FBINFO(output.ph), (u_int32_t*)arg))					return -EFAULT;				return 0;			}		case MATROXFB_GET_AVAILABLE_OUTPUTS:			{				u_int32_t tmp;				tmp = ACCESS_FBINFO(output.all) & ~ACCESS_FBINFO(output.sh);				if (ACCESS_FBINFO(output.ph) & MATROXFB_OUTPUT_CONN_DFP)					tmp &= ~MATROXFB_OUTPUT_CONN_SECONDARY;				if (ACCESS_FBINFO(output.ph) & MATROXFB_OUTPUT_CONN_SECONDARY)					tmp &= ~MATROXFB_OUTPUT_CONN_DFP;				if (put_user(tmp, (u_int32_t*)arg))					return -EFAULT;				return 0;			}		case MATROXFB_GET_ALL_OUTPUTS:			{				if (put_user(ACCESS_FBINFO(output.all), (u_int32_t*)arg))					return -EFAULT;				return 0;			}	}	return -EINVAL;#undef minfo}static struct fb_ops matroxfb_ops = {	owner:		THIS_MODULE,	fb_open:	matroxfb_open,	fb_release:	matroxfb_release,	fb_get_fix:	matroxfb_get_fix,	fb_get_var:	matroxfb_get_var,	fb_set_var:	matroxfb_set_var,	fb_get_cmap:	matroxfb_get_cmap,	fb_set_cmap:	matroxfb_set_cmap,	fb_pan_display:	matroxfb_pan_display,	fb_ioctl:	matroxfb_ioctl,};int matroxfb_switch(int con, struct fb_info *info){#define minfo ((struct matrox_fb_info*)info)	struct fb_cmap* cmap;	struct display *p;	DBG("matroxfb_switch");	if (ACCESS_FBINFO(currcon) >= 0) {		/* Do we have to save the colormap? */		cmap = &(ACCESS_FBINFO(currcon_display)->cmap);		dprintk(KERN_DEBUG "switch1: con = %d, cmap.len = %d\n", ACCESS_FBINFO(currcon), cmap->len);		if (cmap->len) {			dprintk(KERN_DEBUG "switch1a: %p %p %p %p\n", cmap->red, cmap->green, cmap->blue, cmap->transp);			fb_get_cmap(cmap, 1, matrox_getcolreg, info);#ifdef DEBUG			if (cmap->red) {				dprintk(KERN_DEBUG "switch1r: %X\n", cmap->red[0]);			}#endif		}	}	ACCESS_FBINFO(currcon) = con;	if (con < 0)		p = ACCESS_FBINFO(fbcon.disp);	else		p = fb_display + con;	ACCESS_FBINFO(currcon_display) = p;	p->var.activate = FB_ACTIVATE_NOW;#ifdef DEBUG	cmap = &p->cmap;	dprintk(KERN_DEBUG "switch2: con = %d, cmap.len = %d\n", con, cmap->len);	dprintk(KERN_DEBUG "switch2a: %p %p %p %p\n", cmap->red, cmap->green, cmap->blue, cmap->transp);	if (p->cmap.red) {		dprintk(KERN_DEBUG "switch2r: %X\n", cmap->red[0]);	}#endif	matroxfb_set_var(&p->var, con, info);#ifdef DEBUG	dprintk(KERN_DEBUG "switch3: con = %d, cmap.len = %d\n", con, cmap->len);	dprintk(KERN_DEBUG "switch3a: %p %p %p %p\n", cmap->red, cmap->green, cmap->blue, cmap->transp);	if (p->cmap.red) {		dprintk(KERN_DEBUG "switch3r: %X\n", cmap->red[0]);	}#endif	return 0;#undef minfo}/* 0 unblank, 1 blank, 2 no vsync, 3 no hsync, 4 off */static void matroxfb_blank(int blank, struct fb_info *info){#define minfo ((struct matrox_fb_info*)info)	int seq;	int crtc;	CRITFLAGS	DBG("matroxfb_blank")	if (ACCESS_FBINFO(dead))		return;	switch (blank) {		case 1:  seq = 0x20; crtc = 0x00; break; /* works ??? */		case 2:  seq = 0x20; crtc = 0x10; break;		case 3:  seq = 0x20; crtc = 0x20; break;		case 4:  seq = 0x20; crtc = 0x30; break;		default: seq = 0x00; crtc = 0x00; break;	}	CRITBEGIN	mga_outb(M_SEQ_INDEX, 1);	mga_outb(M_SEQ_DATA, (mga_inb(M_SEQ_DATA) & ~0x20) | seq);	mga_outb(M_EXTVGA_INDEX, 1);	mga_outb(M_EXTVGA_DATA, (mga_inb(M_EXTVGA_DATA) & ~0x30) | crtc);	CRITEND#undef minfo}#define RSDepth(X)	(((X) >> 8) & 0x0F)#define RS8bpp		0x1#define RS15bpp		0x2#define RS16bpp		0x3#define RS32bpp		0x4#define RS4bpp		0x5#define RS24bpp		0x6

⌨️ 快捷键说明

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