📄 matroxfb_ti3026.c
字号:
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("ti3026_ramdac_init") 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(WPMINFO struct display* p) { int i; unsigned char progdac[6]; struct matrox_hw_state* hw = &ACCESS_FBINFO(hw); CRITFLAGS DBG("Ti3026_restore")#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); } } matrox_init_putc(PMINFO p, matroxfb_ti3026_createcursor);#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("Ti3026_reset") matroxfb_fastfont_init(MINFO); ti3026_ramdac_init(PMINFO2);}static struct matrox_altout ti3026_output = { .owner = THIS_MODULE, .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("Ti3026_preinit") 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(cursor.timer.function) = matroxfb_ti3026_flashcursor; ACCESS_FBINFO(outputs[0]).data = MINFO; ACCESS_FBINFO(outputs[0]).output = &ti3026_output; ACCESS_FBINFO(outputs[0]).src = MATROXFB_SRC_CRTC1; 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, matroxfb_ti3026_selhwcursor};EXPORT_SYMBOL(matrox_millennium);#endifMODULE_LICENSE("GPL");
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -