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

📄 matroxfb_base.c

📁 linux-2.4.29操作系统的源码
💻 C
📖 第 1 页 / 共 5 页
字号:
		dsp = info->disp;	} else {		dsp = fb_display + con;	}	if (var->vmode & FB_VMODE_YWRAP) {		return -EINVAL;	} else {		if (var->xoffset+dsp->var.xres > dsp->var.xres_virtual ||		    var->yoffset+dsp->var.yres > dsp->var.yres_virtual)			return -EINVAL;	}	if (con == ACCESS_FBINFO(currcon))		matrox_pan_var(PMINFO var);	dsp->var.xoffset = var->xoffset;	dsp->var.yoffset = var->yoffset;	dsp->var.vmode &= ~FB_VMODE_YWRAP;	return 0;}static int matroxfb_updatevar(int con, struct fb_info *info){#define minfo (list_entry(info, struct matrox_fb_info, fbcon))	DBG("matroxfb_updatevar");	matrox_pan_var(PMINFO &fb_display[con].var);	return 0;#undef minfo}static int matroxfb_get_final_bppShift(CPMINFO int bpp) {	int bppshft2;	DBG("matroxfb_get_final_bppShift")	bppshft2 = bpp;	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("matroxfb_test_and_set_rounding")	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("matroxfb_pitch_adjust")	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);	}	if (!xres_new) return 0;	if (xres != xres_new) {		printk(KERN_INFO "matroxfb: cannot set xres to %d, rounded up to %d\n", xres, xres_new);	}	return xres_new;}static int matroxfb_get_cmap_len(struct fb_var_screeninfo *var) {	DBG("matroxfb_get_cmap_len")	switch (var->bits_per_pixel) {#ifdef FBCON_HAS_VGATEXT		case 0:			return 16;	/* pseudocolor... 16 entries HW palette */#endif#ifdef FBCON_HAS_CFB4		case 4:			return 16;	/* pseudocolor... 16 entries HW palette */#endif#ifdef FBCON_HAS_CFB8		case 8:			return 256;	/* pseudocolor... 256 entries HW palette */#endif#ifdef FBCON_HAS_CFB16		case 16:			return 16;	/* directcolor... 16 entries SW palette */					/* Mystique: truecolor, 16 entries SW palette, HW palette hardwired into 1:1 mapping */#endif#ifdef FBCON_HAS_CFB24		case 24:			return 16;	/* directcolor... 16 entries SW palette */					/* Mystique: truecolor, 16 entries SW palette, HW palette hardwired into 1:1 mapping */#endif#ifdef FBCON_HAS_CFB32		case 32:			return 16;	/* directcolor... 16 entries SW palette */					/* Mystique: truecolor, 16 entries SW palette, HW palette hardwired into 1:1 mapping */#endif	}	return 16;	/* return something reasonable... or panic()? */}static int matroxfb_decode_var(CPMINFO struct display* p, 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[]= {#if defined FBCON_HAS_VGATEXT		{ 0,{ 0,6},{0,6},{0,6},{ 0,0},MX_VISUAL_PSEUDOCOLOR},#endif#if defined FBCON_HAS_CFB4 || defined FBCON_HAS_CFB8		{ 8,{ 0,8},{0,8},{0,8},{ 0,0},MX_VISUAL_PSEUDOCOLOR},#endif#if defined FBCON_HAS_CFB16		{15,{10,5},{5,5},{0,5},{15,1},MX_VISUAL_DIRECTCOLOR},		{16,{11,5},{5,6},{0,5},{ 0,0},MX_VISUAL_DIRECTCOLOR},#endif#if defined FBCON_HAS_CFB24		{24,{16,8},{8,8},{0,8},{ 0,0},MX_VISUAL_DIRECTCOLOR},#endif#if defined FBCON_HAS_CFB32		{32,{16,8},{8,8},{0,8},{24,8},MX_VISUAL_DIRECTCOLOR}#endif	};	struct RGBT const *rgbt;	unsigned int bpp = var->bits_per_pixel;	unsigned int vramlen;	unsigned int memlen;	DBG("matroxfb_decode_var")	switch (bpp) {#ifdef FBCON_HAS_VGATEXT		case 0:	 if (!ACCESS_FBINFO(capable.text)) return -EINVAL;			 break;#endif#ifdef FBCON_HAS_CFB4		case 4:	 if (!ACCESS_FBINFO(capable.cfb4)) return -EINVAL;			 break;#endif#ifdef FBCON_HAS_CFB8		case 8:	 break;#endif#ifdef FBCON_HAS_CFB16		case 16: break;#endif#ifdef FBCON_HAS_CFB24		case 24: break;#endif#ifdef FBCON_HAS_CFB32		case 32: break;#endif		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;	if (bpp) {		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;			}		}	} else {		matrox_text_round(PMINFO var, p);#if 0/* we must limit pixclock by mclk...   Millennium I:    66 MHz = 15000   Millennium II:   61 MHz = 16300   Millennium G200: 83 MHz = 12000 */		if (var->pixclock < 15000)			var->pixclock = 15000;	/* limit for "normal" gclk & mclk */#endif	}	/* 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){	struct display* p;#ifdef CONFIG_FB_MATROX_MULTIHEAD	struct matrox_fb_info* minfo = list_entry(fb_info, struct matrox_fb_info, fbcon);#endif	DBG("matroxfb_setcolreg")	/*	 *  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;	ACCESS_FBINFO(palette[regno].red)   = red;	ACCESS_FBINFO(palette[regno].green) = green;	ACCESS_FBINFO(palette[regno].blue)  = blue;	ACCESS_FBINFO(palette[regno].transp) = transp;	p = ACCESS_FBINFO(currcon_display);	if (p->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, p->var.red.length);	green = CNVT_TOHW(green, p->var.green.length);	blue = CNVT_TOHW(blue, p->var.blue.length);	transp = CNVT_TOHW(transp, p->var.transp.length);	switch (p->var.bits_per_pixel) {#if defined(FBCON_HAS_CFB8) || defined(FBCON_HAS_CFB4) || defined(FBCON_HAS_VGATEXT)#ifdef FBCON_HAS_VGATEXT	case 0:#endif#ifdef FBCON_HAS_CFB4	case 4:#endif#ifdef FBCON_HAS_CFB8	case 8:#endif		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;#endif#ifdef FBCON_HAS_CFB16	case 16:		ACCESS_FBINFO(cmap.cfb16[regno]) =			(red << p->var.red.offset)     |			(green << p->var.green.offset) |			(blue << p->var.blue.offset)   |			(transp << p->var.transp.offset); /* for 1:5:5:5 */		break;#endif#ifdef FBCON_HAS_CFB24	case 24:		ACCESS_FBINFO(cmap.cfb24[regno]) =			(red   << p->var.red.offset)   |			(green << p->var.green.offset) |			(blue  << p->var.blue.offset);		break;#endif#ifdef FBCON_HAS_CFB32	case 32:		ACCESS_FBINFO(cmap.cfb32[regno]) =			(red   << p->var.red.offset)   |			(green << p->var.green.offset) |			(blue  << p->var.blue.offset)  |			(transp << p->var.transp.offset);	/* 8:8:8:8 */		break;#endif	}	return 0;}static inline void my_install_cmap(WPMINFO2){	/* Do not touch this code if you do not understand what it does! */	/* Never try to use do_install_cmap() instead. It is crap. */	struct fb_cmap* cmap = &ACCESS_FBINFO(currcon_display)->cmap;	if (cmap->len)		fb_set_cmap(cmap, 1, matroxfb_setcolreg, &ACCESS_FBINFO(fbcon));	else		fb_set_cmap(fb_default_cmap(ACCESS_FBINFO(curr.cmap_len)),			    1, matroxfb_setcolreg, &ACCESS_FBINFO(fbcon));}static int matroxfb_get_fix(struct fb_fix_screeninfo *fix, int con,			 struct fb_info *info){	struct display* p;	DBG("matroxfb_get_fix")#define minfo (list_entry(info, struct matrox_fb_info, fbcon))	if (ACCESS_FBINFO(dead)) {		return -ENXIO;	}	if (con >= 0)		p = fb_display + con;	else		p = ACCESS_FBINFO(fbcon.disp);	memset(fix, 0, sizeof(*fix));	strcpy(fix->id,"MATROX");	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);	fix->type = p->type;	fix->type_aux = p->type_aux;	fix->visual = p->visual;	fix->xpanstep = 8; /* 8 for 8bpp, 4 for 16bpp, 2 for 32bpp */	fix->ypanstep = 1;	fix->ywrapstep = 0;	fix->line_length = p->line_length;	fix->mmio_start = ACCESS_FBINFO(mmio.base);	fix->mmio_len = ACCESS_FBINFO(mmio.len);	fix->accel = ACCESS_FBINFO(devflags.accelerator);	return 0;#undef minfo}static int matroxfb_get_var(struct fb_var_screeninfo *var, int con,			 struct fb_info *info){#define minfo (list_entry(info, struct matrox_fb_info, fbcon))	DBG("matroxfb_get_var")	if(con < 0)		*var=ACCESS_FBINFO(fbcon.disp)->var;	else		*var=fb_display[con].var;	return 0;#undef minfo}static int matroxfb_set_var(struct fb_var_screeninfo *var, int con,			 struct fb_info *info){#define minfo (list_entry(info, struct matrox_fb_info, fbcon))	int err;

⌨️ 快捷键说明

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