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

📄 matroxfb_ti3026.c

📁 linux-2.6.15.6
💻 C
📖 第 1 页 / 共 2 页
字号:
	memcpy(hw->DACreg, MGADACbpp32, sizeof(hw->DACreg));	switch (ACCESS_FBINFO(fbcon).var.bits_per_pixel) {		case 4:	hw->DACreg[POS3026_XLATCHCTRL] = TVP3026_XLATCHCTRL_16_1;	/* or _8_1, they are same */			hw->DACreg[POS3026_XTRUECOLORCTRL] = TVP3026_XTRUECOLORCTRL_PSEUDOCOLOR;			hw->DACreg[POS3026_XMUXCTRL] = muxctrl | TVP3026_XMUXCTRL_PIXEL_4BIT;			hw->DACreg[POS3026_XCLKCTRL] = TVP3026_XCLKCTRL_SRC_PLL | TVP3026_XCLKCTRL_DIV8;			hw->DACreg[POS3026_XMISCCTRL] = TVP3026_XMISCCTRL_DAC_PUP | TVP3026_XMISCCTRL_DAC_8BIT | TVP3026_XMISCCTRL_PSEL_DIS | TVP3026_XMISCCTRL_PSEL_LOW;			break;		case 8: hw->DACreg[POS3026_XLATCHCTRL] = TVP3026_XLATCHCTRL_8_1;	/* or _4_1, they are same */			hw->DACreg[POS3026_XTRUECOLORCTRL] = TVP3026_XTRUECOLORCTRL_PSEUDOCOLOR;			hw->DACreg[POS3026_XMUXCTRL] = muxctrl | TVP3026_XMUXCTRL_PIXEL_8BIT;			hw->DACreg[POS3026_XCLKCTRL] = TVP3026_XCLKCTRL_SRC_PLL | TVP3026_XCLKCTRL_DIV4;			hw->DACreg[POS3026_XMISCCTRL] = TVP3026_XMISCCTRL_DAC_PUP | TVP3026_XMISCCTRL_DAC_8BIT | TVP3026_XMISCCTRL_PSEL_DIS | TVP3026_XMISCCTRL_PSEL_LOW;			break;		case 16:			/* XLATCHCTRL should be _4_1 / _2_1... Why is not? (_2_1 is used everytime) */			hw->DACreg[POS3026_XTRUECOLORCTRL] = (ACCESS_FBINFO(fbcon).var.green.length == 5)? (TVP3026_XTRUECOLORCTRL_DIRECTCOLOR | TVP3026_XTRUECOLORCTRL_ORGB_1555 ) : (TVP3026_XTRUECOLORCTRL_DIRECTCOLOR | TVP3026_XTRUECOLORCTRL_RGB_565);			hw->DACreg[POS3026_XMUXCTRL] = muxctrl | TVP3026_XMUXCTRL_PIXEL_16BIT;			hw->DACreg[POS3026_XCLKCTRL] = TVP3026_XCLKCTRL_SRC_PLL | TVP3026_XCLKCTRL_DIV2;			break;		case 24:			/* XLATCHCTRL is: for (A) use _4_3 (?_8_3 is same? TBD), for (B) it is set in setpclk */			hw->DACreg[POS3026_XTRUECOLORCTRL] = TVP3026_XTRUECOLORCTRL_DIRECTCOLOR | TVP3026_XTRUECOLORCTRL_RGB_888;			hw->DACreg[POS3026_XMUXCTRL] = muxctrl | TVP3026_XMUXCTRL_PIXEL_32BIT;			hw->DACreg[POS3026_XCLKCTRL] = TVP3026_XCLKCTRL_SRC_PLL | TVP3026_XCLKCTRL_DIV4;			break;		case 32:			/* XLATCHCTRL should be _2_1 / _1_1... Why is not? (_2_1 is used everytime) */			hw->DACreg[POS3026_XMUXCTRL] = muxctrl | TVP3026_XMUXCTRL_PIXEL_32BIT;			break;		default:			return 1;	/* TODO: failed */	}	if (matroxfb_vgaHWinit(PMINFO m)) return 1;	/* set SYNC */	hw->MiscOutReg = 0xCB;	if (m->sync & FB_SYNC_HOR_HIGH_ACT)		hw->DACreg[POS3026_XGENCTRL] |= TVP3026_XGENCTRL_HSYNC_NEG;	if (m->sync & FB_SYNC_VERT_HIGH_ACT)		hw->DACreg[POS3026_XGENCTRL] |= TVP3026_XGENCTRL_VSYNC_NEG;	if (m->sync & FB_SYNC_ON_GREEN)		hw->DACreg[POS3026_XGENCTRL] |= TVP3026_XGENCTRL_SYNC_ON_GREEN;	/* set DELAY */	if (ACCESS_FBINFO(video.len) < 0x400000)		hw->CRTCEXT[3] |= 0x08;	else if (ACCESS_FBINFO(video.len) > 0x400000)		hw->CRTCEXT[3] |= 0x10;	/* set HWCURSOR */	if (m->interlaced) {		hw->DACreg[POS3026_XCURCTRL] |= TVP3026_XCURCTRL_INTERLACED;	}	if (m->HTotal >= 1536)		hw->DACreg[POS3026_XCURCTRL] |= TVP3026_XCURCTRL_BLANK4096;	/* set interleaving */	hw->MXoptionReg &= ~0x00001000;	if (isInterleave(MINFO)) hw->MXoptionReg |= 0x00001000;	/* set DAC */	Ti3026_setpclk(PMINFO m->pixclock);	return 0;}static void ti3026_setMCLK(WPMINFO int fout){	unsigned int f_pll;	unsigned int pclk_m, pclk_n, pclk_p;	unsigned int mclk_m, mclk_n, mclk_p;	unsigned int rfhcnt, mclk_ctl;	int tmout;	DBG(__FUNCTION__)	f_pll = Ti3026_calcclock(PMINFO fout, ACCESS_FBINFO(max_pixel_clock), &mclk_n, &mclk_m, &mclk_p);	/* save pclk */	outTi3026(PMINFO TVP3026_XPLLADDR, 0xFC);	pclk_n = inTi3026(PMINFO TVP3026_XPIXPLLDATA);	outTi3026(PMINFO TVP3026_XPLLADDR, 0xFD);	pclk_m = inTi3026(PMINFO TVP3026_XPIXPLLDATA);	outTi3026(PMINFO TVP3026_XPLLADDR, 0xFE);	pclk_p = inTi3026(PMINFO TVP3026_XPIXPLLDATA);	/* stop pclk */	outTi3026(PMINFO TVP3026_XPLLADDR, 0xFE);	outTi3026(PMINFO TVP3026_XPIXPLLDATA, 0x00);	/* set pclk to new mclk */	outTi3026(PMINFO TVP3026_XPLLADDR, 0xFC);	outTi3026(PMINFO TVP3026_XPIXPLLDATA, mclk_n | 0xC0);	outTi3026(PMINFO TVP3026_XPIXPLLDATA, mclk_m);	outTi3026(PMINFO TVP3026_XPIXPLLDATA, mclk_p | 0xB0);	/* wait for PLL to lock */	for (tmout = 500000; tmout; tmout--) {		if (inTi3026(PMINFO TVP3026_XPIXPLLDATA) & 0x40)			break;		udelay(10);	};	if (!tmout)		printk(KERN_ERR "matroxfb: Temporary pixel PLL not locked after 5 secs\n");	/* output pclk on mclk pin */	mclk_ctl = inTi3026(PMINFO TVP3026_XMEMPLLCTRL);	outTi3026(PMINFO TVP3026_XMEMPLLCTRL, mclk_ctl & 0xE7);	outTi3026(PMINFO TVP3026_XMEMPLLCTRL, (mclk_ctl & 0xE7) | TVP3026_XMEMPLLCTRL_STROBEMKC4);	/* stop MCLK */	outTi3026(PMINFO TVP3026_XPLLADDR, 0xFB);	outTi3026(PMINFO TVP3026_XMEMPLLDATA, 0x00);	/* set mclk to new freq */	outTi3026(PMINFO TVP3026_XPLLADDR, 0xF3);	outTi3026(PMINFO TVP3026_XMEMPLLDATA, mclk_n | 0xC0);	outTi3026(PMINFO TVP3026_XMEMPLLDATA, mclk_m);	outTi3026(PMINFO TVP3026_XMEMPLLDATA, mclk_p | 0xB0);	/* wait for PLL to lock */	for (tmout = 500000; tmout; tmout--) {		if (inTi3026(PMINFO TVP3026_XMEMPLLDATA) & 0x40)			break;		udelay(10);	}	if (!tmout)		printk(KERN_ERR "matroxfb: Memory PLL not locked after 5 secs\n");	f_pll = f_pll * 333 / (10000 << mclk_p);	if (isMilleniumII(MINFO)) {		rfhcnt = (f_pll - 128) / 256;		if (rfhcnt > 15)			rfhcnt = 15;	} else {		rfhcnt = (f_pll - 64) / 128;		if (rfhcnt > 15)			rfhcnt = 0;	}	ACCESS_FBINFO(hw).MXoptionReg = (ACCESS_FBINFO(hw).MXoptionReg & ~0x000F0000) | (rfhcnt << 16);	pci_write_config_dword(ACCESS_FBINFO(pcidev), PCI_OPTION_REG, ACCESS_FBINFO(hw).MXoptionReg);	/* output MCLK to MCLK pin */	outTi3026(PMINFO TVP3026_XMEMPLLCTRL, (mclk_ctl & 0xE7) | TVP3026_XMEMPLLCTRL_MCLK_MCLKPLL);	outTi3026(PMINFO TVP3026_XMEMPLLCTRL, (mclk_ctl       ) | TVP3026_XMEMPLLCTRL_MCLK_MCLKPLL | TVP3026_XMEMPLLCTRL_STROBEMKC4);	/* stop PCLK */	outTi3026(PMINFO TVP3026_XPLLADDR, 0xFE);	outTi3026(PMINFO TVP3026_XPIXPLLDATA, 0x00);	/* restore pclk */	outTi3026(PMINFO TVP3026_XPLLADDR, 0xFC);	outTi3026(PMINFO TVP3026_XPIXPLLDATA, pclk_n);	outTi3026(PMINFO TVP3026_XPIXPLLDATA, pclk_m);	outTi3026(PMINFO TVP3026_XPIXPLLDATA, pclk_p);	/* wait for PLL to lock */	for (tmout = 500000; tmout; tmout--) {		if (inTi3026(PMINFO TVP3026_XPIXPLLDATA) & 0x40)			break;		udelay(10);	}	if (!tmout)		printk(KERN_ERR "matroxfb: Pixel PLL not locked after 5 secs\n");}static void ti3026_ramdac_init(WPMINFO2) {	DBG(__FUNCTION__)	ACCESS_FBINFO(features.pll.vco_freq_min) = 110000;	ACCESS_FBINFO(features.pll.ref_freq)	 = 114545;	ACCESS_FBINFO(features.pll.feed_div_min) = 2;	ACCESS_FBINFO(features.pll.feed_div_max) = 24;	ACCESS_FBINFO(features.pll.in_div_min)	 = 2;	ACCESS_FBINFO(features.pll.in_div_max)	 = 63;	ACCESS_FBINFO(features.pll.post_shift_max) = 3;	if (ACCESS_FBINFO(devflags.noinit))		return;	ti3026_setMCLK(PMINFO 60000);}static void Ti3026_restore(WPMINFO2) {	int i;	unsigned char progdac[6];	struct matrox_hw_state* hw = &ACCESS_FBINFO(hw);	CRITFLAGS	DBG(__FUNCTION__)#ifdef DEBUG	dprintk(KERN_INFO "EXTVGA regs: ");	for (i = 0; i < 6; i++)		dprintk("%02X:", hw->CRTCEXT[i]);	dprintk("\n");#endif	CRITBEGIN	pci_write_config_dword(ACCESS_FBINFO(pcidev), PCI_OPTION_REG, hw->MXoptionReg);	CRITEND	matroxfb_vgaHWrestore(PMINFO2);	CRITBEGIN	ACCESS_FBINFO(crtc1.panpos) = -1;	for (i = 0; i < 6; i++)		mga_setr(M_EXTVGA_INDEX, i, hw->CRTCEXT[i]);	for (i = 0; i < 21; i++) {		outTi3026(PMINFO DACseq[i], hw->DACreg[i]);	}	outTi3026(PMINFO TVP3026_XPLLADDR, 0x00);	progdac[0] = inTi3026(PMINFO TVP3026_XPIXPLLDATA);	progdac[3] = inTi3026(PMINFO TVP3026_XLOOPPLLDATA);	outTi3026(PMINFO TVP3026_XPLLADDR, 0x15);	progdac[1] = inTi3026(PMINFO TVP3026_XPIXPLLDATA);	progdac[4] = inTi3026(PMINFO TVP3026_XLOOPPLLDATA);	outTi3026(PMINFO TVP3026_XPLLADDR, 0x2A);	progdac[2] = inTi3026(PMINFO TVP3026_XPIXPLLDATA);	progdac[5] = inTi3026(PMINFO TVP3026_XLOOPPLLDATA);	CRITEND	if (memcmp(hw->DACclk, progdac, 6)) {		/* agrhh... setting up PLL is very slow on Millennium... */		/* Mystique PLL is locked in few ms, but Millennium PLL lock takes about 0.15 s... */		/* Maybe even we should call schedule() ? */		CRITBEGIN		outTi3026(PMINFO TVP3026_XCLKCTRL, hw->DACreg[POS3026_XCLKCTRL]);		outTi3026(PMINFO TVP3026_XPLLADDR, 0x2A);		outTi3026(PMINFO TVP3026_XLOOPPLLDATA, 0);		outTi3026(PMINFO TVP3026_XPIXPLLDATA, 0);		outTi3026(PMINFO TVP3026_XPLLADDR, 0x00);		for (i = 0; i < 3; i++)			outTi3026(PMINFO TVP3026_XPIXPLLDATA, hw->DACclk[i]);		/* wait for PLL only if PLL clock requested (always for PowerMode, never for VGA) */		if (hw->MiscOutReg & 0x08) {			int tmout;			outTi3026(PMINFO TVP3026_XPLLADDR, 0x3F);			for (tmout = 500000; tmout; --tmout) {				if (inTi3026(PMINFO TVP3026_XPIXPLLDATA) & 0x40)					break;				udelay(10);			}			CRITEND			if (!tmout)				printk(KERN_ERR "matroxfb: Pixel PLL not locked after 5 secs\n");			else				dprintk(KERN_INFO "PixelPLL: %d\n", 500000-tmout);			CRITBEGIN		}		outTi3026(PMINFO TVP3026_XMEMPLLCTRL, hw->DACreg[POS3026_XMEMPLLCTRL]);		outTi3026(PMINFO TVP3026_XPLLADDR, 0x00);		for (i = 3; i < 6; i++)			outTi3026(PMINFO TVP3026_XLOOPPLLDATA, hw->DACclk[i]);		CRITEND		if ((hw->MiscOutReg & 0x08) && ((hw->DACclk[5] & 0x80) == 0x80)) {			int tmout;			CRITBEGIN			outTi3026(PMINFO TVP3026_XPLLADDR, 0x3F);			for (tmout = 500000; tmout; --tmout) {				if (inTi3026(PMINFO TVP3026_XLOOPPLLDATA) & 0x40)					break;				udelay(10);			}			CRITEND			if (!tmout)				printk(KERN_ERR "matroxfb: Loop PLL not locked after 5 secs\n");			else				dprintk(KERN_INFO "LoopPLL: %d\n", 500000-tmout);		}	}#ifdef DEBUG	dprintk(KERN_DEBUG "3026DACregs ");	for (i = 0; i < 21; i++) {		dprintk("R%02X=%02X ", DACseq[i], hw->DACreg[i]);		if ((i & 0x7) == 0x7) dprintk("\n" KERN_DEBUG "continuing... ");	}	dprintk("\n" KERN_DEBUG "DACclk ");	for (i = 0; i < 6; i++)		dprintk("C%02X=%02X ", i, hw->DACclk[i]);	dprintk("\n");#endif}static void Ti3026_reset(WPMINFO2) {	DBG(__FUNCTION__)	ti3026_ramdac_init(PMINFO2);}static struct matrox_altout ti3026_output = {	.name	 = "Primary output",};static int Ti3026_preinit(WPMINFO2) {	static const int vxres_mill2[] = { 512,        640, 768,  800,  832,  960,					  1024, 1152, 1280,      1600, 1664, 1920,					  2048, 0};	static const int vxres_mill1[] = {             640, 768,  800,        960,					  1024, 1152, 1280,      1600,       1920,					  2048, 0};	struct matrox_hw_state* hw = &ACCESS_FBINFO(hw);	DBG(__FUNCTION__)	ACCESS_FBINFO(millenium) = 1;	ACCESS_FBINFO(milleniumII) = (ACCESS_FBINFO(pcidev)->device != PCI_DEVICE_ID_MATROX_MIL);	ACCESS_FBINFO(capable.cfb4) = 1;	ACCESS_FBINFO(capable.text) = 1; /* isMilleniumII(MINFO); */	ACCESS_FBINFO(capable.vxres) = isMilleniumII(MINFO)?vxres_mill2:vxres_mill1;	ACCESS_FBINFO(outputs[0]).data = MINFO;	ACCESS_FBINFO(outputs[0]).output = &ti3026_output;	ACCESS_FBINFO(outputs[0]).src = ACCESS_FBINFO(outputs[0]).default_src;	ACCESS_FBINFO(outputs[0]).mode = MATROXFB_OUTPUT_MODE_MONITOR;	if (ACCESS_FBINFO(devflags.noinit))		return 0;	/* preserve VGA I/O, BIOS and PPC */	hw->MXoptionReg &= 0xC0000100;	hw->MXoptionReg |= 0x002C0000;	if (ACCESS_FBINFO(devflags.novga))		hw->MXoptionReg &= ~0x00000100;	if (ACCESS_FBINFO(devflags.nobios))		hw->MXoptionReg &= ~0x40000000;	if (ACCESS_FBINFO(devflags.nopciretry))		hw->MXoptionReg |=  0x20000000;	pci_write_config_dword(ACCESS_FBINFO(pcidev), PCI_OPTION_REG, hw->MXoptionReg);	ACCESS_FBINFO(accel.ramdac_rev) = inTi3026(PMINFO TVP3026_XSILICONREV);	outTi3026(PMINFO TVP3026_XCLKCTRL, TVP3026_XCLKCTRL_SRC_CLK0VGA | TVP3026_XCLKCTRL_CLKSTOPPED);	outTi3026(PMINFO TVP3026_XTRUECOLORCTRL, TVP3026_XTRUECOLORCTRL_PSEUDOCOLOR);	outTi3026(PMINFO TVP3026_XMUXCTRL, TVP3026_XMUXCTRL_VGA);	outTi3026(PMINFO TVP3026_XPLLADDR, 0x2A);	outTi3026(PMINFO TVP3026_XLOOPPLLDATA, 0x00);	outTi3026(PMINFO TVP3026_XPIXPLLDATA, 0x00);	mga_outb(M_MISC_REG, 0x67);	outTi3026(PMINFO TVP3026_XMEMPLLCTRL, TVP3026_XMEMPLLCTRL_STROBEMKC4 | TVP3026_XMEMPLLCTRL_MCLK_MCLKPLL);	mga_outl(M_RESET, 1);	udelay(250);	mga_outl(M_RESET, 0);	udelay(250);	mga_outl(M_MACCESS, 0x00008000);	udelay(10);	return 0;}struct matrox_switch matrox_millennium = {	Ti3026_preinit, Ti3026_reset, Ti3026_init, Ti3026_restore};EXPORT_SYMBOL(matrox_millennium);#endifMODULE_LICENSE("GPL");

⌨️ 快捷键说明

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