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

📄 matroxfb_crtc2.c

📁 上传linux-jx2410的源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * * Hardware accelerated Matrox Millennium I, II, Mystique, G100, G200, G400 and G450. * * (c) 1998-2001 Petr Vandrovec <vandrove@vc.cvut.cz> * * Version: 1.52 2001/05/25 * */#include "matroxfb_maven.h"#include "matroxfb_crtc2.h"#include "matroxfb_misc.h"#include "matroxfb_DAC1064.h"#include <linux/matroxfb.h>#include <asm/uaccess.h>/* **************************************************** */static int mem = 8192;MODULE_PARM(mem, "i");MODULE_PARM_DESC(mem, "Memory size reserved for dualhead (default=8MB)");/* **************************************************** */static int matroxfb_dh_getcolreg(unsigned regno, unsigned *red, unsigned *green,		unsigned *blue, unsigned *transp, struct fb_info* info) {#define m2info ((struct matroxfb_dh_fb_info*)info)	if (regno > 16)		return 1;	*red = m2info->palette[regno].red;	*blue = m2info->palette[regno].blue;	*green = m2info->palette[regno].green;	*transp = m2info->palette[regno].transp;	return 0;#undef m2info}static int matroxfb_dh_setcolreg(unsigned regno, unsigned red, unsigned green,		unsigned blue, unsigned transp, struct fb_info* info) {#define m2info ((struct matroxfb_dh_fb_info*)info)	struct display* p;	if (regno > 16)		return 1;	m2info->palette[regno].red = red;	m2info->palette[regno].blue = blue;	m2info->palette[regno].green = green;	m2info->palette[regno].transp = transp;	p = m2info->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) {#ifdef FBCON_HAS_CFB16		case 16:			m2info->cmap.cfb16[regno] =				(red << p->var.red.offset)     |				(green << p->var.green.offset) |				(blue << p->var.blue.offset)   |				(transp << p->var.transp.offset);			break;#endif#ifdef FBCON_HAS_CFB32		case 32:			m2info->cmap.cfb32[regno] =				(red << p->var.red.offset)     |				(green << p->var.green.offset) |				(blue << p->var.blue.offset)   |				(transp << p->var.transp.offset);			break;#endif	}	return 0;#undef m2info}static void do_install_cmap(struct matroxfb_dh_fb_info* m2info, struct display* p) {	if (p->cmap.len)		fb_set_cmap(&p->cmap, 1, matroxfb_dh_setcolreg, &m2info->fbcon);	else		fb_set_cmap(fb_default_cmap(16), 1, matroxfb_dh_setcolreg, &m2info->fbcon);}static void matroxfb_dh_restore(struct matroxfb_dh_fb_info* m2info,		struct my_timming* mt,		struct display* p,		int mode,		unsigned int pos) {	u_int32_t tmp;	MINFO_FROM(m2info->primary_dev);	switch (mode) {		case 15:			tmp = 0x00200000;			break;		case 16:			tmp = 0x00400000;			break;/*		case 32: */		default:			tmp = 0x00800000;			break;	}	if (ACCESS_FBINFO(output.sh)) {		tmp |= 0x00000001;	/* enable CRTC2 */		if (ACCESS_FBINFO(output.sh) & MATROXFB_OUTPUT_CONN_SECONDARY) {			if (ACCESS_FBINFO(devflags.g450dac)) {				tmp |= 0x00000006; /* source from secondary pixel PLL */				/* no vidrst */			} else {				tmp |= 0x00000002; /* source from VDOCLK */				tmp |= 0xC0000000; /* enable vvidrst & hvidrst */				/* MGA TVO is our clock source */			}		} else if (ACCESS_FBINFO(output.sh) & MATROXFB_OUTPUT_CONN_PRIMARY) {			tmp |= 0x00000004; /* source from pixclock */			/* PIXPLL is our clock source */		}		if (ACCESS_FBINFO(output.sh) & MATROXFB_OUTPUT_CONN_PRIMARY)			tmp |= 0x00100000;	/* connect CRTC2 to DAC */	}	if (mt->interlaced) {		tmp |= 0x02000000;	/* interlaced, second field is bigger, as G450 apparently ignores it */		mt->VDisplay >>= 1;		mt->VSyncStart >>= 1;		mt->VSyncEnd >>= 1;		mt->VTotal >>= 1;	}	mga_outl(0x3C10, tmp | 0x10000000);	/* depth and so on... 0x10000000 is VIDRST polarity */	mga_outl(0x3C14, ((mt->HDisplay - 8) << 16) | (mt->HTotal - 8));	mga_outl(0x3C18, ((mt->HSyncEnd - 8) << 16) | (mt->HSyncStart - 8));	mga_outl(0x3C1C, ((mt->VDisplay - 1) << 16) | (mt->VTotal - 1));	mga_outl(0x3C20, ((mt->VSyncEnd - 1) << 16) | (mt->VSyncStart - 1));	mga_outl(0x3C24, ((mt->VSyncStart) << 16) | (mt->HSyncStart));	/* preload */	{		u_int32_t linelen = p->var.xres_virtual * (p->var.bits_per_pixel >> 3);		if (mt->interlaced) {			/* field #0 is smaller, so... */			mga_outl(0x3C2C, pos);			/* field #1 vmemory start */			mga_outl(0x3C28, pos + linelen);	/* field #0 vmemory start */			linelen <<= 1;		} else {			mga_outl(0x3C28, pos);		/* vmemory start */		}		mga_outl(0x3C40, linelen);	}	tmp = 0x0FFF0000;		/* line compare */	if (mt->sync & FB_SYNC_HOR_HIGH_ACT)		tmp |= 0x00000100;	if (mt->sync & FB_SYNC_VERT_HIGH_ACT)		tmp |= 0x00000200;	mga_outl(0x3C44, tmp);	mga_outl(0x3C4C, 0);		/* data control */}static void matroxfb_dh_cfbX_init(struct matroxfb_dh_fb_info* m2info,		struct display* p) {	/* no acceleration for secondary head... */}static void matroxfb_dh_pan_var(struct matroxfb_dh_fb_info* m2info,		struct fb_var_screeninfo* var) {	unsigned int pos;	unsigned int linelen;	unsigned int pixelsize;#define minfo (m2info->primary_dev)	pixelsize = var->bits_per_pixel >> 3;	linelen = var->xres_virtual * pixelsize;	pos = var->yoffset * linelen + var->xoffset * pixelsize;	pos += m2info->video.offbase;	if (var->vmode & FB_VMODE_INTERLACED) {		mga_outl(0x3C2C, pos);		mga_outl(0x3C28, pos + linelen);	} else {		mga_outl(0x3C28, pos);	}#undef minfo}static int matroxfb_dh_decode_var(struct matroxfb_dh_fb_info* m2info,		struct display* p,		struct fb_var_screeninfo* var,		int *visual,		int *video_cmap_len,		int *mode) {	unsigned int mask;	unsigned int memlen;	unsigned int vramlen;	switch (var->bits_per_pixel) {#ifdef FBCON_HAS_CFB16		case 16:	mask = 0x1F;				break;#endif#ifdef FBCON_HAS_CFB32		case 32:	mask = 0x0F;				break;#endif		default:	return -EINVAL;	}	vramlen = m2info->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 = (var->xres_virtual + mask) & ~mask;	if (var->yres_virtual > 32767)		return -EINVAL;	memlen = var->xres_virtual * var->yres_virtual * (var->bits_per_pixel >> 3);	if (memlen > vramlen)		return -EINVAL;	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;	var->xres &= ~7;	var->left_margin &= ~7;	var->right_margin &= ~7;	var->hsync_len &= ~7;	*mode = var->bits_per_pixel;	if (var->bits_per_pixel == 16) {		if (var->green.length == 5) {			var->red.offset = 10;			var->red.length = 5;			var->green.offset = 5;			var->green.length = 5;			var->blue.offset = 0;			var->blue.length = 5;			var->transp.offset = 15;			var->transp.length = 1;			*mode = 15;		} else {			var->red.offset = 11;			var->red.length = 5;			var->green.offset = 5;			var->green.length = 6;			var->blue.offset = 0;			var->blue.length = 5;			var->transp.offset = 0;			var->transp.length = 0;		}	} else {			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.offset = 24;			var->transp.length = 8;	}	*visual = FB_VISUAL_TRUECOLOR;	*video_cmap_len = 16;	return 0;}static void initMatroxDH(struct matroxfb_dh_fb_info* m2info, struct display* p) {	switch (p->var.bits_per_pixel) {#ifdef FBCON_HAS_CFB16		case 16:			p->dispsw_data = m2info->cmap.cfb16;			p->dispsw = &fbcon_cfb16;			break;#endif#ifdef FBCON_HAS_CFB32		case 32:			p->dispsw_data = m2info->cmap.cfb32;			p->dispsw = &fbcon_cfb32;			break;#endif		default:			p->dispsw_data = NULL;			p->dispsw = &fbcon_dummy;			break;	}}static int matroxfb_dh_open(struct fb_info* info, int user) {#define m2info ((struct matroxfb_dh_fb_info*)info)	MINFO_FROM(m2info->primary_dev);	if (MINFO) {		if (ACCESS_FBINFO(dead)) {			return -ENXIO;		}	}	return 0;#undef m2info}static int matroxfb_dh_release(struct fb_info* info, int user) {#define m2info ((struct matroxfb_dh_fb_info*)info)	MINFO_FROM(m2info->primary_dev);	if (MINFO) {	}	return 0;#undef m2info}static int matroxfb_dh_get_fix(struct fb_fix_screeninfo* fix, int con,		struct fb_info* info) {#define m2info ((struct matroxfb_dh_fb_info*)info)	struct display* p;	if (con >= 0)		p = fb_display + con;	else		p = m2info->fbcon.disp;	memset(fix, 0, sizeof(*fix));	strcpy(fix->id, "MATROX DH");	fix->smem_start = m2info->video.base;	fix->smem_len = m2info->video.len_usable;	fix->type = p->type;	fix->type_aux = p->type_aux;	fix->visual = p->visual;	fix->xpanstep = 8;	/* TBD */	fix->ypanstep = 1;	fix->ywrapstep = 0;	fix->line_length = p->line_length;	fix->mmio_start = m2info->mmio.base;	fix->mmio_len = m2info->mmio.len;	fix->accel = 0;		/* no accel... */	return 0;#undef m2info}static int matroxfb_dh_get_var(struct fb_var_screeninfo* var, int con,		struct fb_info* info) {#define m2info ((struct matroxfb_dh_fb_info*)info)	if (con < 0)		*var = m2info->fbcon.disp->var;	else		*var = fb_display[con].var;	return 0;#undef m2info}static int matroxfb_dh_set_var(struct fb_var_screeninfo* var, int con,		struct fb_info* info) {#define m2info ((struct matroxfb_dh_fb_info*)info)	struct display* p;	int chgvar;	int visual;	int cmap_len;	int mode;	int err;	MINFO_FROM(m2info->primary_dev);	if (con < 0)		p = m2info->fbcon.disp;	else		p = fb_display + con;	if ((err = matroxfb_dh_decode_var(m2info, p, var, &visual, &cmap_len, &mode)) != 0)		return err;	switch (var->activate & FB_ACTIVATE_MASK) {		case FB_ACTIVATE_TEST:	return 0;		case FB_ACTIVATE_NXTOPEN:		case FB_ACTIVATE_NOW:	break;		default:		return -EINVAL;	}	if (con >= 0) {		chgvar = (p->var.xres != var->xres) ||			(p->var.yres != var->yres) ||			(p->var.xres_virtual != var->xres_virtual) ||			(p->var.yres_virtual != var->yres_virtual) ||			(p->var.bits_per_pixel != var->bits_per_pixel) ||			memcmp(&p->var.red, &var->red, sizeof(var->red)) ||			memcmp(&p->var.green, &var->green, sizeof(var->green)) ||			memcmp(&p->var.blue, &var->blue, sizeof(var->blue));	} else		chgvar = 0;	p->var = *var;	/* cmap */	p->screen_base = vaddr_va(m2info->video.vbase);	p->visual = visual;	p->ypanstep = 1;	p->ywrapstep = 0;	p->type = FB_TYPE_PACKED_PIXELS;	p->type_aux = 0;	p->next_line = p->line_length = (var->xres_virtual * var->bits_per_pixel) >> 3;	p->can_soft_blank = 0;	p->inverse = 0;	/* TBD */	initMatroxDH(m2info, p);	if (chgvar && info && info->changevar)		info->changevar(con);	if (con == m2info->currcon) {		struct my_timming mt;		struct matrox_hw_state* hw;		struct matrox_hw_state* ohw;		unsigned int pos;		matroxfb_var2my(var, &mt);		/* CRTC2 delay */		mt.delay = 34;		hw = ACCESS_FBINFO(newhw);		ohw = ACCESS_FBINFO(currenthw);		/* copy last setting... */		memcpy(hw, ohw, sizeof(*hw));		pos = (var->yoffset * var->xres_virtual + var->xoffset) * var->bits_per_pixel >> 3;		pos += m2info->video.offbase;		DAC1064_global_init(PMINFO hw);		if (ACCESS_FBINFO(output.sh) & MATROXFB_OUTPUT_CONN_PRIMARY) {			if (ACCESS_FBINFO(primout))

⌨️ 快捷键说明

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