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

📄 matroxfb_base.c

📁 linux-2.6.15.6
💻 C
📖 第 1 页 / 共 5 页
字号:
	if (!bppshft2) {		return 8;	}	if (isInterleave(MINFO))		bppshft2 >>= 1;	if (ACCESS_FBINFO(devflags.video64bits))		bppshft2 >>= 1;	return bppshft2;}static int matroxfb_test_and_set_rounding(CPMINFO int xres, int bpp) {	int over;	int rounding;	DBG(__FUNCTION__)	switch (bpp) {		case 0:		return xres;		case 4:		rounding = 128;				break;		case 8:		rounding = 64;	/* doc says 64; 32 is OK for G400 */				break;		case 16:	rounding = 32;				break;		case 24:	rounding = 64;	/* doc says 64; 32 is OK for G400 */				break;		default:	rounding = 16;				/* on G400, 16 really does not work */				if (ACCESS_FBINFO(devflags.accelerator) == FB_ACCEL_MATROX_MGAG400)					rounding = 32;				break;	}	if (isInterleave(MINFO)) {		rounding *= 2;	}	over = xres % rounding;	if (over)		xres += rounding-over;	return xres;}static int matroxfb_pitch_adjust(CPMINFO int xres, int bpp) {	const int* width;	int xres_new;	DBG(__FUNCTION__)	if (!bpp) return xres;	width = ACCESS_FBINFO(capable.vxres);	if (ACCESS_FBINFO(devflags.precise_width)) {		while (*width) {			if ((*width >= xres) && (matroxfb_test_and_set_rounding(PMINFO *width, bpp) == *width)) {				break;			}			width++;		}		xres_new = *width;	} else {		xres_new = matroxfb_test_and_set_rounding(PMINFO xres, bpp);	}	return xres_new;}static int matroxfb_get_cmap_len(struct fb_var_screeninfo *var) {	DBG(__FUNCTION__)	switch (var->bits_per_pixel) {		case 4:			return 16;	/* pseudocolor... 16 entries HW palette */		case 8:			return 256;	/* pseudocolor... 256 entries HW palette */		case 16:			return 16;	/* directcolor... 16 entries SW palette */					/* Mystique: truecolor, 16 entries SW palette, HW palette hardwired into 1:1 mapping */		case 24:			return 16;	/* directcolor... 16 entries SW palette */					/* Mystique: truecolor, 16 entries SW palette, HW palette hardwired into 1:1 mapping */		case 32:			return 16;	/* directcolor... 16 entries SW palette */					/* Mystique: truecolor, 16 entries SW palette, HW palette hardwired into 1:1 mapping */	}	return 16;	/* return something reasonable... or panic()? */}static int matroxfb_decode_var(CPMINFO struct fb_var_screeninfo *var, int *visual, int *video_cmap_len, unsigned int* ydstorg) {	struct RGBT {		unsigned char bpp;		struct {			unsigned char offset,				      length;		} red,		  green,		  blue,		  transp;		signed char visual;	};	static const struct RGBT table[]= {		{ 8,{ 0,8},{0,8},{0,8},{ 0,0},MX_VISUAL_PSEUDOCOLOR},		{15,{10,5},{5,5},{0,5},{15,1},MX_VISUAL_DIRECTCOLOR},		{16,{11,5},{5,6},{0,5},{ 0,0},MX_VISUAL_DIRECTCOLOR},		{24,{16,8},{8,8},{0,8},{ 0,0},MX_VISUAL_DIRECTCOLOR},		{32,{16,8},{8,8},{0,8},{24,8},MX_VISUAL_DIRECTCOLOR}	};	struct RGBT const *rgbt;	unsigned int bpp = var->bits_per_pixel;	unsigned int vramlen;	unsigned int memlen;	DBG(__FUNCTION__)	switch (bpp) {		case 4:	 if (!ACCESS_FBINFO(capable.cfb4)) return -EINVAL;			 break;		case 8:	 break;		case 16: break;		case 24: break;		case 32: break;		default: return -EINVAL;	}	*ydstorg = 0;	vramlen = ACCESS_FBINFO(video.len_usable);	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 = matroxfb_pitch_adjust(PMINFO var->xres_virtual, bpp);	memlen = var->xres_virtual * bpp * var->yres_virtual / 8;	if (memlen > vramlen) {		var->yres_virtual = vramlen * 8 / (var->xres_virtual * bpp);		memlen = var->xres_virtual * bpp * var->yres_virtual / 8;	}	/* There is hardware bug that no line can cross 4MB boundary */	/* give up for CFB24, it is impossible to easy workaround it */	/* for other try to do something */	if (!ACCESS_FBINFO(capable.cross4MB) && (memlen > 0x400000)) {		if (bpp == 24) {			/* sorry */		} else {			unsigned int linelen;			unsigned int m1 = linelen = var->xres_virtual * bpp / 8;			unsigned int m2 = PAGE_SIZE;	/* or 128 if you do not need PAGE ALIGNED address */			unsigned int max_yres;			while (m1) {				int t;				while (m2 >= m1) m2 -= m1;				t = m1;				m1 = m2;				m2 = t;			}			m2 = linelen * PAGE_SIZE / m2;			*ydstorg = m2 = 0x400000 % m2;			max_yres = (vramlen - m2) / linelen;			if (var->yres_virtual > max_yres)				var->yres_virtual = max_yres;		}	}	/* YDSTLEN contains only signed 16bit value */	if (var->yres_virtual > 32767)		var->yres_virtual = 32767;	/* we must round yres/xres down, we already rounded y/xres_virtual up	   if it was possible. We should return -EINVAL, but I disagree */	if (var->yres_virtual < var->yres)		var->yres = var->yres_virtual;	if (var->xres_virtual < var->xres)		var->xres = var->xres_virtual;	if (var->xoffset + var->xres > var->xres_virtual)		var->xoffset = var->xres_virtual - var->xres;	if (var->yoffset + var->yres > var->yres_virtual)		var->yoffset = var->yres_virtual - var->yres;	if (bpp == 16 && var->green.length == 5) {		bpp--; /* an artifical value - 15 */	}	for (rgbt = table; rgbt->bpp < bpp; rgbt++);#define	SETCLR(clr)\	var->clr.offset = rgbt->clr.offset;\	var->clr.length = rgbt->clr.length	SETCLR(red);	SETCLR(green);	SETCLR(blue);	SETCLR(transp);#undef	SETCLR	*visual = rgbt->visual;	if (bpp > 8)		dprintk("matroxfb: truecolor: "			"size=%d:%d:%d:%d, shift=%d:%d:%d:%d\n",			var->transp.length, var->red.length, var->green.length, var->blue.length,			var->transp.offset, var->red.offset, var->green.offset, var->blue.offset);	*video_cmap_len = matroxfb_get_cmap_len(var);	dprintk(KERN_INFO "requested %d*%d/%dbpp (%d*%d)\n", var->xres, var->yres, var->bits_per_pixel,				var->xres_virtual, var->yres_virtual);	return 0;}static int matroxfb_setcolreg(unsigned regno, unsigned red, unsigned green,			      unsigned blue, unsigned transp,			      struct fb_info *fb_info){#ifdef CONFIG_FB_MATROX_MULTIHEAD	struct matrox_fb_info* minfo = container_of(fb_info, struct matrox_fb_info, fbcon);#endif	DBG(__FUNCTION__)	/*	 *  Set a single color register. The values supplied are	 *  already rounded down to the hardware's capabilities	 *  (according to the entries in the `var' structure). Return	 *  != 0 for invalid regno.	 */	if (regno >= ACCESS_FBINFO(curr.cmap_len))		return 1;	if (ACCESS_FBINFO(fbcon).var.grayscale) {		/* gray = 0.30*R + 0.59*G + 0.11*B */		red = green = blue = (red * 77 + green * 151 + blue * 28) >> 8;	}	red = CNVT_TOHW(red, ACCESS_FBINFO(fbcon).var.red.length);	green = CNVT_TOHW(green, ACCESS_FBINFO(fbcon).var.green.length);	blue = CNVT_TOHW(blue, ACCESS_FBINFO(fbcon).var.blue.length);	transp = CNVT_TOHW(transp, ACCESS_FBINFO(fbcon).var.transp.length);	switch (ACCESS_FBINFO(fbcon).var.bits_per_pixel) {	case 4:	case 8:		mga_outb(M_DAC_REG, regno);		mga_outb(M_DAC_VAL, red);		mga_outb(M_DAC_VAL, green);		mga_outb(M_DAC_VAL, blue);		break;	case 16:		{			u_int16_t col =				(red << ACCESS_FBINFO(fbcon).var.red.offset)     |				(green << ACCESS_FBINFO(fbcon).var.green.offset) |				(blue << ACCESS_FBINFO(fbcon).var.blue.offset)   |				(transp << ACCESS_FBINFO(fbcon).var.transp.offset); /* for 1:5:5:5 */			ACCESS_FBINFO(cmap[regno]) = col | (col << 16);		}		break;	case 24:	case 32:		ACCESS_FBINFO(cmap[regno]) =			(red   << ACCESS_FBINFO(fbcon).var.red.offset)   |			(green << ACCESS_FBINFO(fbcon).var.green.offset) |			(blue  << ACCESS_FBINFO(fbcon).var.blue.offset)  |			(transp << ACCESS_FBINFO(fbcon).var.transp.offset);	/* 8:8:8:8 */		break;	}	return 0;}static void matroxfb_init_fix(WPMINFO2){	struct fb_fix_screeninfo *fix = &ACCESS_FBINFO(fbcon).fix;	DBG(__FUNCTION__)	strcpy(fix->id,"MATROX");	fix->xpanstep = 8;	/* 8 for 8bpp, 4 for 16bpp, 2 for 32bpp */	fix->ypanstep = 1;	fix->ywrapstep = 0;	fix->mmio_start = ACCESS_FBINFO(mmio.base);	fix->mmio_len = ACCESS_FBINFO(mmio.len);	fix->accel = ACCESS_FBINFO(devflags.accelerator);}static void matroxfb_update_fix(WPMINFO2){	struct fb_fix_screeninfo *fix = &ACCESS_FBINFO(fbcon).fix;	DBG(__FUNCTION__)	fix->smem_start = ACCESS_FBINFO(video.base) + ACCESS_FBINFO(curr.ydstorg.bytes);	fix->smem_len = ACCESS_FBINFO(video.len_usable) - ACCESS_FBINFO(curr.ydstorg.bytes);}static int matroxfb_check_var(struct fb_var_screeninfo *var, struct fb_info *info){	int err;	int visual;	int cmap_len;	unsigned int ydstorg;	MINFO_FROM_INFO(info);	if (ACCESS_FBINFO(dead)) {		return -ENXIO;	}	if ((err = matroxfb_decode_var(PMINFO var, &visual, &cmap_len, &ydstorg)) != 0)		return err;	return 0;}static int matroxfb_set_par(struct fb_info *info){	int err;	int visual;	int cmap_len;	unsigned int ydstorg;	struct fb_var_screeninfo *var;	MINFO_FROM_INFO(info);	DBG(__FUNCTION__)	if (ACCESS_FBINFO(dead)) {		return -ENXIO;	}	var = &info->var;	if ((err = matroxfb_decode_var(PMINFO var, &visual, &cmap_len, &ydstorg)) != 0)		return err;	ACCESS_FBINFO(fbcon.screen_base) = vaddr_va(ACCESS_FBINFO(video.vbase)) + ydstorg;	matroxfb_update_fix(PMINFO2);	ACCESS_FBINFO(fbcon).fix.visual = visual;	ACCESS_FBINFO(fbcon).fix.type = FB_TYPE_PACKED_PIXELS;	ACCESS_FBINFO(fbcon).fix.type_aux = 0;	ACCESS_FBINFO(fbcon).fix.line_length = (var->xres_virtual * var->bits_per_pixel) >> 3;	{		unsigned int pos;		ACCESS_FBINFO(curr.cmap_len) = cmap_len;		ydstorg += ACCESS_FBINFO(devflags.ydstorg);		ACCESS_FBINFO(curr.ydstorg.bytes) = ydstorg;		ACCESS_FBINFO(curr.ydstorg.chunks) = ydstorg >> (isInterleave(MINFO)?3:2);		if (var->bits_per_pixel == 4)			ACCESS_FBINFO(curr.ydstorg.pixels) = ydstorg;		else			ACCESS_FBINFO(curr.ydstorg.pixels) = (ydstorg * 8) / var->bits_per_pixel;		ACCESS_FBINFO(curr.final_bppShift) = matroxfb_get_final_bppShift(PMINFO var->bits_per_pixel);		{	struct my_timming mt;			struct matrox_hw_state* hw;			int out;			matroxfb_var2my(var, &mt);			mt.crtc = MATROXFB_SRC_CRTC1;			/* CRTC1 delays */			switch (var->bits_per_pixel) {				case  0:	mt.delay = 31 + 0; break;				case 16:	mt.delay = 21 + 8; break;				case 24:	mt.delay = 17 + 8; break;				case 32:	mt.delay = 16 + 8; break;				default:	mt.delay = 31 + 8; break;			}			hw = &ACCESS_FBINFO(hw);			down_read(&ACCESS_FBINFO(altout).lock);			for (out = 0; out < MATROXFB_MAX_OUTPUTS; out++) {				if (ACCESS_FBINFO(outputs[out]).src == MATROXFB_SRC_CRTC1 &&				    ACCESS_FBINFO(outputs[out]).output->compute) {					ACCESS_FBINFO(outputs[out]).output->compute(ACCESS_FBINFO(outputs[out]).data, &mt);				}			}			up_read(&ACCESS_FBINFO(altout).lock);			ACCESS_FBINFO(crtc1).pixclock = mt.pixclock;			ACCESS_FBINFO(crtc1).mnp = mt.mnp;			ACCESS_FBINFO(hw_switch->init(PMINFO &mt));			pos = (var->yoffset * var->xres_virtual + var->xoffset) * ACCESS_FBINFO(curr.final_bppShift) / 32;			pos += ACCESS_FBINFO(curr.ydstorg.chunks);			hw->CRTC[0x0D] = pos & 0xFF;			hw->CRTC[0x0C] = (pos & 0xFF00) >> 8;			hw->CRTCEXT[0] = (hw->CRTCEXT[0] & 0xF0) | ((pos >> 16) & 0x0F) | ((pos >> 14) & 0x40);			hw->CRTCEXT[8] = pos >> 21;			ACCESS_FBINFO(hw_switch->restore(PMINFO2));			update_crtc2(PMINFO pos);			down_read(&ACCESS_FBINFO(altout).lock);			for (out = 0; out < MATROXFB_MAX_OUTPUTS; out++) {				if (ACCESS_FBINFO(outputs[out]).src == MATROXFB_SRC_CRTC1 &&				    ACCESS_FBINFO(outputs[out]).output->program) {					ACCESS_FBINFO(outputs[out]).output->program(ACCESS_FBINFO(outputs[out]).data);				}			}			for (out = 0; out < MATROXFB_MAX_OUTPUTS; out++) {				if (ACCESS_FBINFO(outputs[out]).src == MATROXFB_SRC_CRTC1 &&				    ACCESS_FBINFO(outputs[out]).output->start) {					ACCESS_FBINFO(outputs[out]).output->start(ACCESS_FBINFO(outputs[out]).data);				}			}			up_read(&ACCESS_FBINFO(altout).lock);			matrox_cfbX_init(PMINFO2);		}	}	ACCESS_FBINFO(initialized) = 1;	return 0;}static int matroxfb_get_vblank(WPMINFO struct fb_vblank *vblank){	unsigned int sts1;	matroxfb_enable_irq(PMINFO 0);	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->vcount >= ACCESS_FBINFO(fbcon).var.yres)		vblank->flags |= FB_VBLANK_VBLANKING;	if (test_bit(0, &ACCESS_FBINFO(irq_flags))) {		vblank->flags |= FB_VBLANK_HAVE_COUNT;		/* Only one writer, aligned int value... 		   it should work without lock and without atomic_t */		vblank->count = ACCESS_FBINFO(crtc1).vsync.cnt;	}	return 0;}static struct matrox_altout panellink_output = {	.name	 = "Panellink output",};static int matroxfb_ioctl(struct inode *inode, struct file *file,			  unsigned int cmd, unsigned long arg,			  struct fb_info *info){	void __user *argp = (void __user *)arg;	MINFO_FROM_INFO(info);		DBG(__FUNCTION__)

⌨️ 快捷键说明

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