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

📄 matroxfb_dac1064.c

📁 内核linux2.4.20,可跟rtlinux3.2打补丁 组成实时linux系统,编译内核
💻 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.54 2001/09/09 * * See matroxfb_base.c for contributors. * *//* make checkconfig does not walk through include tree :-( */#include <linux/config.h>#include "matroxfb_DAC1064.h"#include "matroxfb_misc.h"#include "matroxfb_accel.h"#include <linux/matroxfb.h>#ifdef NEED_DAC1064#define outDAC1064 matroxfb_DAC_out#define inDAC1064 matroxfb_DAC_in#define DAC1064_OPT_SCLK_PCI	0x00#define DAC1064_OPT_SCLK_PLL	0x01#define DAC1064_OPT_SCLK_EXT	0x02#define DAC1064_OPT_SCLK_MASK	0x03#define DAC1064_OPT_GDIV1	0x04	/* maybe it is GDIV2 on G100 ?! */#define DAC1064_OPT_GDIV3	0x00#define DAC1064_OPT_MDIV1	0x08#define DAC1064_OPT_MDIV2	0x00#define DAC1064_OPT_RESERVED	0x10static void matroxfb_DAC1064_flashcursor(unsigned long ptr) {	unsigned long flags;#define minfo ((struct matrox_fb_info*)ptr)	matroxfb_DAC_lock_irqsave(flags);	outDAC1064(PMINFO M1064_XCURCTRL, inDAC1064(PMINFO M1064_XCURCTRL) ^ M1064_XCURCTRL_DIS ^ M1064_XCURCTRL_XGA);	ACCESS_FBINFO(cursor.timer.expires) = jiffies + HZ/2;	add_timer(&ACCESS_FBINFO(cursor.timer));	matroxfb_DAC_unlock_irqrestore(flags);#undef minfo}static void matroxfb_DAC1064_createcursor(WPMINFO struct display* p) {	vaddr_t cursorbase;	u_int32_t xline;	unsigned int i;	unsigned int h, to;	CRITFLAGS	if (ACCESS_FBINFO(currcon_display) != p)		return;	matroxfb_createcursorshape(PMINFO p, p->var.vmode);	xline = (~0) << (32 - ACCESS_FBINFO(cursor.w));	cursorbase = ACCESS_FBINFO(video.vbase);	h = ACCESS_FBINFO(features.DAC1064.cursorimage);	CRITBEGIN#ifdef __BIG_ENDIAN	WaitTillIdle();	mga_outl(M_OPMODE, M_OPMODE_32BPP);#endif	to = ACCESS_FBINFO(cursor.u);	for (i = 0; i < to; i++) {		mga_writel(cursorbase, h, 0);		mga_writel(cursorbase, h+4, 0);		mga_writel(cursorbase, h+8, ~0);		mga_writel(cursorbase, h+12, ~0);		h += 16;	}	to = ACCESS_FBINFO(cursor.d);	for (; i < to; i++) {		mga_writel(cursorbase, h, 0);		mga_writel(cursorbase, h+4, xline);		mga_writel(cursorbase, h+8, ~0);		mga_writel(cursorbase, h+12, ~0);		h += 16;	}	for (; i < 64; i++) {		mga_writel(cursorbase, h, 0);		mga_writel(cursorbase, h+4, 0);		mga_writel(cursorbase, h+8, ~0);		mga_writel(cursorbase, h+12, ~0);		h += 16;	}#ifdef __BIG_ENDIAN	mga_outl(M_OPMODE, ACCESS_FBINFO(accel.m_opmode));#endif	CRITEND}static void matroxfb_DAC1064_cursor(struct display* p, int mode, int x, int y) {	unsigned long flags;	MINFO_FROM_DISP(p);	if (ACCESS_FBINFO(currcon_display) != p)		return;	if (mode == CM_ERASE) {		if (ACCESS_FBINFO(cursor.state) != CM_ERASE) {			del_timer_sync(&ACCESS_FBINFO(cursor.timer));			matroxfb_DAC_lock_irqsave(flags);			ACCESS_FBINFO(cursor.state) = CM_ERASE;			outDAC1064(PMINFO M1064_XCURCTRL, M1064_XCURCTRL_DIS);			matroxfb_DAC_unlock_irqrestore(flags);		}		return;	}	if ((p->conp->vc_cursor_type & CUR_HWMASK) != ACCESS_FBINFO(cursor.type))		matroxfb_DAC1064_createcursor(PMINFO p);	x *= fontwidth(p);	y *= fontheight(p);	y -= p->var.yoffset;	if (p->var.vmode & FB_VMODE_DOUBLE)		y *= 2;	del_timer_sync(&ACCESS_FBINFO(cursor.timer));	matroxfb_DAC_lock_irqsave(flags);	if ((x != ACCESS_FBINFO(cursor.x)) || (y != ACCESS_FBINFO(cursor.y)) || ACCESS_FBINFO(cursor.redraw)) {		ACCESS_FBINFO(cursor.redraw) = 0;		ACCESS_FBINFO(cursor.x) = x;		ACCESS_FBINFO(cursor.y) = y;		x += 64;		y += 64;		outDAC1064(PMINFO M1064_XCURCTRL, M1064_XCURCTRL_DIS);		mga_outb(M_RAMDAC_BASE+M1064_CURPOSXL, x);		mga_outb(M_RAMDAC_BASE+M1064_CURPOSXH, x >> 8);		mga_outb(M_RAMDAC_BASE+M1064_CURPOSYL, y);		mga_outb(M_RAMDAC_BASE+M1064_CURPOSYH, y >> 8);	}	ACCESS_FBINFO(cursor.state) = CM_DRAW;	if (ACCESS_FBINFO(devflags.blink))		mod_timer(&ACCESS_FBINFO(cursor.timer), jiffies + HZ/2);	outDAC1064(PMINFO M1064_XCURCTRL, M1064_XCURCTRL_XGA);	matroxfb_DAC_unlock_irqrestore(flags);}static int matroxfb_DAC1064_setfont(struct display* p, int width, int height) {	if (p && p->conp)		matroxfb_DAC1064_createcursor(PMXINFO(p) p);	return 0;}static int DAC1064_selhwcursor(WPMINFO struct display* p) {	ACCESS_FBINFO(dispsw.cursor) = matroxfb_DAC1064_cursor;	ACCESS_FBINFO(dispsw.set_font) = matroxfb_DAC1064_setfont;	return 0;}static void DAC1064_calcclock(CPMINFO unsigned int freq, unsigned int fmax, unsigned int* in, unsigned int* feed, unsigned int* post) {	unsigned int fvco;	unsigned int p;	DBG("DAC1064_calcclock")	fvco = PLL_calcclock(PMINFO freq, fmax, in, feed, &p);		if (ACCESS_FBINFO(devflags.g450dac)) {		if (fvco <= 300000)		/* 276-324 */			;		else if (fvco <= 400000)	/* 378-438 */			p |= 0x08;		else if (fvco <= 550000)	/* 540-567 */			p |= 0x10;		else if (fvco <= 690000)	/* 675-695 */			p |= 0x18;		else if (fvco <= 800000)	/* 776-803 */			p |= 0x20;		else if (fvco <= 891000)	/* 891-891 */			p |= 0x28;		else if (fvco <= 940000)	/* 931-945 */			p |= 0x30;		else				/* <959 */			p |= 0x38;	} else {		p = (1 << p) - 1;		if (fvco <= 100000)			;		else if (fvco <= 140000)			p |= 0x08;		else if (fvco <= 180000)			p |= 0x10;		else			p |= 0x18;	}	*post = p;}/* they must be in POS order */static const unsigned char MGA1064_DAC_regs[] = {		M1064_XCURADDL, M1064_XCURADDH, M1064_XCURCTRL,		M1064_XCURCOL0RED, M1064_XCURCOL0GREEN, M1064_XCURCOL0BLUE,		M1064_XCURCOL1RED, M1064_XCURCOL1GREEN, M1064_XCURCOL1BLUE,		M1064_XCURCOL2RED, M1064_XCURCOL2GREEN, M1064_XCURCOL2BLUE,		DAC1064_XVREFCTRL, M1064_XMULCTRL, M1064_XPIXCLKCTRL, M1064_XGENCTRL,		M1064_XMISCCTRL,		M1064_XGENIOCTRL, M1064_XGENIODATA, M1064_XZOOMCTRL, M1064_XSENSETEST,		M1064_XCRCBITSEL,		M1064_XCOLKEYMASKL, M1064_XCOLKEYMASKH, M1064_XCOLKEYL, M1064_XCOLKEYH };static const unsigned char MGA1064_DAC[] = {		0x00, 0x00, M1064_XCURCTRL_DIS,		0x00, 0x00, 0x00, 	/* black */		0xFF, 0xFF, 0xFF,	/* white */		0xFF, 0x00, 0x00,	/* red */		0x00, 0,		M1064_XPIXCLKCTRL_PLL_UP | M1064_XPIXCLKCTRL_EN | M1064_XPIXCLKCTRL_SRC_PLL,		M1064_XGENCTRL_VS_0 | M1064_XGENCTRL_ALPHA_DIS | M1064_XGENCTRL_BLACK_0IRE | M1064_XGENCTRL_NO_SYNC_ON_GREEN,		M1064_XMISCCTRL_DAC_8BIT,		0x00, 0x00, M1064_XZOOMCTRL_1, M1064_XSENSETEST_BCOMP | M1064_XSENSETEST_GCOMP | M1064_XSENSETEST_RCOMP | M1064_XSENSETEST_PDOWN,		0x00,		0x00, 0x00, 0xFF, 0xFF};static void DAC1064_setpclk(CPMINFO struct matrox_hw_state* hw, unsigned long fout) {	unsigned int m, n, p;	DBG("DAC1064_setpclk")	DAC1064_calcclock(PMINFO fout, ACCESS_FBINFO(max_pixel_clock), &m, &n, &p);	hw->DACclk[0] = m;	hw->DACclk[1] = n;	hw->DACclk[2] = p;}static void DAC1064_setmclk(CPMINFO struct matrox_hw_state* hw, int oscinfo, unsigned long fmem){	u_int32_t mx;	DBG("DAC1064_setmclk")	if (ACCESS_FBINFO(devflags.noinit)) {		/* read MCLK and give up... */		hw->DACclk[3] = inDAC1064(PMINFO DAC1064_XSYSPLLM);		hw->DACclk[4] = inDAC1064(PMINFO DAC1064_XSYSPLLN);		hw->DACclk[5] = inDAC1064(PMINFO DAC1064_XSYSPLLP);		return;	}	mx = hw->MXoptionReg | 0x00000004;	pci_write_config_dword(ACCESS_FBINFO(pcidev), PCI_OPTION_REG, mx);	mx &= ~0x000000BB;	if (oscinfo & DAC1064_OPT_GDIV1)		mx |= 0x00000008;	if (oscinfo & DAC1064_OPT_MDIV1)		mx |= 0x00000010;	if (oscinfo & DAC1064_OPT_RESERVED)		mx |= 0x00000080;	if ((oscinfo & DAC1064_OPT_SCLK_MASK) == DAC1064_OPT_SCLK_PLL) {		/* select PCI clock until we have setup oscilator... */		int clk;		unsigned int m, n, p;		/* powerup system PLL, select PCI clock */		mx |= 0x00000020;		pci_write_config_dword(ACCESS_FBINFO(pcidev), PCI_OPTION_REG, mx);		mx &= ~0x00000004;		pci_write_config_dword(ACCESS_FBINFO(pcidev), PCI_OPTION_REG, mx);		/* !!! you must not access device if MCLK is not running !!!		   Doing so cause immediate PCI lockup :-( Maybe they should		   generate ABORT or I/O (parity...) error and Linux should		   recover from this... (kill driver/process). But world is not		   perfect... */		/* (bit 2 of PCI_OPTION_REG must be 0... and bits 0,1 must not		   select PLL... because of PLL can be stopped at this time) */		DAC1064_calcclock(PMINFO fmem, ACCESS_FBINFO(max_pixel_clock), &m, &n, &p);		outDAC1064(PMINFO DAC1064_XSYSPLLM, hw->DACclk[3] = m);		outDAC1064(PMINFO DAC1064_XSYSPLLN, hw->DACclk[4] = n);		outDAC1064(PMINFO DAC1064_XSYSPLLP, hw->DACclk[5] = p);		for (clk = 65536; clk; --clk) {			if (inDAC1064(PMINFO DAC1064_XSYSPLLSTAT) & 0x40)				break;		}		if (!clk)			printk(KERN_ERR "matroxfb: aiee, SYSPLL not locked\n");		/* select PLL */		mx |= 0x00000005;	} else {		/* select specified system clock source */		mx |= oscinfo & DAC1064_OPT_SCLK_MASK;	}	pci_write_config_dword(ACCESS_FBINFO(pcidev), PCI_OPTION_REG, mx);	mx &= ~0x00000004;	pci_write_config_dword(ACCESS_FBINFO(pcidev), PCI_OPTION_REG, mx);	hw->MXoptionReg = mx;}void DAC1064_global_init(CPMINFO struct matrox_hw_state* hw) {	hw->DACreg[POS1064_XMISCCTRL] &= M1064_XMISCCTRL_DAC_WIDTHMASK;	hw->DACreg[POS1064_XMISCCTRL] |= M1064_XMISCCTRL_LUT_EN;	hw->DACreg[POS1064_XPIXCLKCTRL] = M1064_XPIXCLKCTRL_PLL_UP | M1064_XPIXCLKCTRL_EN | M1064_XPIXCLKCTRL_SRC_PLL;	hw->DACreg[POS1064_XOUTPUTCONN] = 0x01;	/* output #1 enabled */	if (ACCESS_FBINFO(output.ph) & MATROXFB_OUTPUT_CONN_SECONDARY) {		if (ACCESS_FBINFO(devflags.g450dac)) {			hw->DACreg[POS1064_XPIXCLKCTRL] = M1064_XPIXCLKCTRL_PLL_UP | M1064_XPIXCLKCTRL_EN | M1064_XPIXCLKCTRL_SRC_PLL2;			hw->DACreg[POS1064_XOUTPUTCONN] = 0x05;	/* output #1 enabled; CRTC1 connected to output #2 */		} else {			hw->DACreg[POS1064_XPIXCLKCTRL] = M1064_XPIXCLKCTRL_PLL_UP | M1064_XPIXCLKCTRL_EN | M1064_XPIXCLKCTRL_SRC_EXT;			hw->DACreg[POS1064_XMISCCTRL] |= GX00_XMISCCTRL_MFC_MAFC | G400_XMISCCTRL_VDO_MAFC12;		}	} else if (ACCESS_FBINFO(output.sh) & MATROXFB_OUTPUT_CONN_SECONDARY) {		hw->DACreg[POS1064_XMISCCTRL] |= GX00_XMISCCTRL_MFC_MAFC | G400_XMISCCTRL_VDO_C2_MAFC12;		hw->DACreg[POS1064_XOUTPUTCONN] = 0x09; /* output #1 enabled; CRTC2 connected to output #2 */	} else if (ACCESS_FBINFO(output.ph) & MATROXFB_OUTPUT_CONN_DFP)		hw->DACreg[POS1064_XMISCCTRL] |= GX00_XMISCCTRL_MFC_PANELLINK | G400_XMISCCTRL_VDO_MAFC12;	else		hw->DACreg[POS1064_XMISCCTRL] |= GX00_XMISCCTRL_MFC_DIS;	if ((ACCESS_FBINFO(output.ph) | ACCESS_FBINFO(output.sh)) & MATROXFB_OUTPUT_CONN_PRIMARY)		hw->DACreg[POS1064_XMISCCTRL] |= M1064_XMISCCTRL_DAC_EN;}void DAC1064_global_restore(CPMINFO const struct matrox_hw_state* hw) {	outDAC1064(PMINFO M1064_XPIXCLKCTRL, hw->DACreg[POS1064_XPIXCLKCTRL]);	outDAC1064(PMINFO M1064_XMISCCTRL, hw->DACreg[POS1064_XMISCCTRL]);	if (ACCESS_FBINFO(devflags.accelerator) == FB_ACCEL_MATROX_MGAG400) {		outDAC1064(PMINFO 0x20, 0x04);		outDAC1064(PMINFO 0x1F, ACCESS_FBINFO(devflags.dfp_type));		if (ACCESS_FBINFO(devflags.g450dac)) {			outDAC1064(PMINFO M1064_XSYNCCTRL, 0xCC);	/* only matrox know... */			outDAC1064(PMINFO M1064_XPWRCTRL, 0x1F);	/* powerup everything */			outDAC1064(PMINFO M1064_XOUTPUTCONN, hw->DACreg[POS1064_XOUTPUTCONN]);		}	}}static int DAC1064_init_1(CPMINFO struct matrox_hw_state* hw, struct my_timming* m, struct display *p) {	DBG("DAC1064_init_1")	memcpy(hw->DACreg, MGA1064_DAC, sizeof(MGA1064_DAC_regs));	if (p->type == FB_TYPE_TEXT) {		hw->DACreg[POS1064_XMISCCTRL] = M1064_XMISCCTRL_DAC_6BIT;		hw->DACreg[POS1064_XMULCTRL] = M1064_XMULCTRL_DEPTH_8BPP					     | M1064_XMULCTRL_GRAPHICS_PALETIZED;	} else {		switch (p->var.bits_per_pixel) {		/* case 4: not supported by MGA1064 DAC */		case 8:			hw->DACreg[POS1064_XMULCTRL] = M1064_XMULCTRL_DEPTH_8BPP | M1064_XMULCTRL_GRAPHICS_PALETIZED;			break;		case 16:			if (p->var.green.length == 5)				hw->DACreg[POS1064_XMULCTRL] = M1064_XMULCTRL_DEPTH_15BPP_1BPP | M1064_XMULCTRL_GRAPHICS_PALETIZED;			else				hw->DACreg[POS1064_XMULCTRL] = M1064_XMULCTRL_DEPTH_16BPP | M1064_XMULCTRL_GRAPHICS_PALETIZED;			break;		case 24:			hw->DACreg[POS1064_XMULCTRL] = M1064_XMULCTRL_DEPTH_24BPP | M1064_XMULCTRL_GRAPHICS_PALETIZED;			break;		case 32:			hw->DACreg[POS1064_XMULCTRL] = M1064_XMULCTRL_DEPTH_32BPP | M1064_XMULCTRL_GRAPHICS_PALETIZED;			break;		default:			return 1;	/* unsupported depth */		}	}	DAC1064_global_init(PMINFO hw);	hw->DACreg[POS1064_XVREFCTRL] = ACCESS_FBINFO(features.DAC1064.xvrefctrl);	hw->DACreg[POS1064_XGENCTRL] &= ~M1064_XGENCTRL_SYNC_ON_GREEN_MASK;	hw->DACreg[POS1064_XGENCTRL] |= (m->sync & FB_SYNC_ON_GREEN)?M1064_XGENCTRL_SYNC_ON_GREEN:M1064_XGENCTRL_NO_SYNC_ON_GREEN;	hw->DACreg[POS1064_XCURADDL] = ACCESS_FBINFO(features.DAC1064.cursorimage) >> 10;	hw->DACreg[POS1064_XCURADDH] = ACCESS_FBINFO(features.DAC1064.cursorimage) >> 18;	return 0;}static int DAC1064_init_2(CPMINFO struct matrox_hw_state* hw, struct my_timming* m, struct display* p) {	DBG("DAC1064_init_2")	if (p->var.bits_per_pixel > 16) {	/* 256 entries */		int i;		for (i = 0; i < 256; i++) {			hw->DACpal[i * 3 + 0] = i;			hw->DACpal[i * 3 + 1] = i;			hw->DACpal[i * 3 + 2] = i;		}	} else if (p->var.bits_per_pixel > 8) {		if (p->var.green.length == 5) {	/* 0..31, 128..159 */			int i;			for (i = 0; i < 32; i++) {				/* with p15 == 0 */				hw->DACpal[i * 3 + 0] = i << 3;				hw->DACpal[i * 3 + 1] = i << 3;				hw->DACpal[i * 3 + 2] = i << 3;				/* with p15 == 1 */				hw->DACpal[(i + 128) * 3 + 0] = i << 3;				hw->DACpal[(i + 128) * 3 + 1] = i << 3;				hw->DACpal[(i + 128) * 3 + 2] = i << 3;			}		} else {			int i;			for (i = 0; i < 64; i++) {		/* 0..63 */				hw->DACpal[i * 3 + 0] = i << 3;				hw->DACpal[i * 3 + 1] = i << 2;				hw->DACpal[i * 3 + 2] = i << 3;			}		}	} else {		memset(hw->DACpal, 0, 768);	}	return 0;}static void DAC1064_restore_1(WPMINFO const struct matrox_hw_state* hw, const struct matrox_hw_state* oldhw) {	CRITFLAGS	DBG("DAC1064_restore_1")	CRITBEGIN	outDAC1064(PMINFO DAC1064_XSYSPLLM, hw->DACclk[3]);	outDAC1064(PMINFO DAC1064_XSYSPLLN, hw->DACclk[4]);	outDAC1064(PMINFO DAC1064_XSYSPLLP, hw->DACclk[5]);	/*	 * We must ALWAYS reprogram hardware due to broken XF4 matrox drivers...	 *	 * if (!oldhw || memcmp(hw->DACreg, oldhw->DACreg, sizeof(MGA1064_DAC_regs))) 	 */	{		unsigned int i;		for (i = 0; i < sizeof(MGA1064_DAC_regs); i++) {			if ((i != POS1064_XPIXCLKCTRL) && (i != POS1064_XMISCCTRL))				outDAC1064(PMINFO MGA1064_DAC_regs[i], hw->DACreg[i]);		}	}	DAC1064_global_restore(PMINFO hw);	CRITEND};static void DAC1064_restore_2(WPMINFO const struct matrox_hw_state* hw, const struct matrox_hw_state* oldhw, struct display* p) {#ifdef DEBUG	unsigned int i;#endif	DBG("DAC1064_restore_2")	matrox_init_putc(PMINFO p, matroxfb_DAC1064_createcursor);#ifdef DEBUG	dprintk(KERN_DEBUG "DAC1064regs ");	for (i = 0; i < sizeof(MGA1064_DAC_regs); i++) {		dprintk("R%02X=%02X ", MGA1064_DAC_regs[i], hw->DACreg[i]);		if ((i & 0x7) == 0x7) dprintk("\n" KERN_DEBUG "continuing... ");	}	dprintk("\n" KERN_DEBUG "DAC1064clk ");	for (i = 0; i < 6; i++)		dprintk("C%02X=%02X ", i, hw->DACclk[i]);	dprintk("\n");#endif}static int m1064_compute(void* outdev, struct my_timming* m, struct matrox_hw_state* hw) {#define minfo ((struct matrox_fb_info*)outdev)	DAC1064_setpclk(PMINFO hw, m->pixclock);#undef minfo	return 0;}static int m1064_program(void* outdev, const struct matrox_hw_state* hw) {#define minfo ((struct matrox_fb_info*)outdev)

⌨️ 快捷键说明

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