static void ti3026_setMCLK(struct matrox_fb_info *minfo, 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(__func__) f_pll = Ti3026_calcclock(minfo, fout, minfo->max_pixel_clock, &mclk_n, &mclk_m, &mclk_p); /* save pclk */ outTi3026(minfo, TVP3026_XPLLADDR, 0xFC); pclk_n = inTi3026(minfo, TVP3026_XPIXPLLDATA); outTi3026(minfo, TVP3026_XPLLADDR, 0xFD); pclk_m = inTi3026(minfo, TVP3026_XPIXPLLDATA); outTi3026(minfo, TVP3026_XPLLADDR, 0xFE); pclk_p = inTi3026(minfo, TVP3026_XPIXPLLDATA); /* stop pclk */ outTi3026(minfo, TVP3026_XPLLADDR, 0xFE); outTi3026(minfo, TVP3026_XPIXPLLDATA, 0x00); /* set pclk to new mclk */ outTi3026(minfo, TVP3026_XPLLADDR, 0xFC); outTi3026(minfo, TVP3026_XPIXPLLDATA, mclk_n | 0xC0); outTi3026(minfo, TVP3026_XPIXPLLDATA, mclk_m); outTi3026(minfo, TVP3026_XPIXPLLDATA, mclk_p | 0xB0); /* wait for PLL to lock */ for (tmout = 500000; tmout; tmout--) { if (inTi3026(minfo, TVP3026_XPIXPLLDATA) & 0x40) break; udelay(10); }; if (!tmout) ; /* output pclk on mclk pin */ mclk_ctl = inTi3026(minfo, TVP3026_XMEMPLLCTRL); outTi3026(minfo, TVP3026_XMEMPLLCTRL, mclk_ctl & 0xE7); outTi3026(minfo, TVP3026_XMEMPLLCTRL, (mclk_ctl & 0xE7) | TVP3026_XMEMPLLCTRL_STROBEMKC4); /* stop MCLK */ outTi3026(minfo, TVP3026_XPLLADDR, 0xFB); outTi3026(minfo, TVP3026_XMEMPLLDATA, 0x00); /* set mclk to new freq */ outTi3026(minfo, TVP3026_XPLLADDR, 0xF3); outTi3026(minfo, TVP3026_XMEMPLLDATA, mclk_n | 0xC0); outTi3026(minfo, TVP3026_XMEMPLLDATA, mclk_m); outTi3026(minfo, TVP3026_XMEMPLLDATA, mclk_p | 0xB0); /* wait for PLL to lock */ for (tmout = 500000; tmout; tmout--) { if (inTi3026(minfo, TVP3026_XMEMPLLDATA) & 0x40) break; udelay(10); } if (!tmout) ; 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; } minfo->hw.MXoptionReg = (minfo->hw.MXoptionReg & ~0x000F0000) | (rfhcnt << 16); pci_write_config_dword(minfo->pcidev, PCI_OPTION_REG, minfo->hw.MXoptionReg); /* output MCLK to MCLK pin */ outTi3026(minfo, TVP3026_XMEMPLLCTRL, (mclk_ctl & 0xE7) | TVP3026_XMEMPLLCTRL_MCLK_MCLKPLL); outTi3026(minfo, TVP3026_XMEMPLLCTRL, (mclk_ctl ) | TVP3026_XMEMPLLCTRL_MCLK_MCLKPLL | TVP3026_XMEMPLLCTRL_STROBEMKC4); /* stop PCLK */ outTi3026(minfo, TVP3026_XPLLADDR, 0xFE); outTi3026(minfo, TVP3026_XPIXPLLDATA, 0x00); /* restore pclk */ outTi3026(minfo, TVP3026_XPLLADDR, 0xFC); outTi3026(minfo, TVP3026_XPIXPLLDATA, pclk_n); outTi3026(minfo, TVP3026_XPIXPLLDATA, pclk_m); outTi3026(minfo, TVP3026_XPIXPLLDATA, pclk_p); /* wait for PLL to lock */ for (tmout = 500000; tmout; tmout--) { if (inTi3026(minfo, TVP3026_XPIXPLLDATA) & 0x40) break; udelay(10); } if (!tmout) ; }
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(__func__) 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"); }