static int Ti3026_setpclk(struct matrox_fb_info *minfo, int clk) { unsigned int f_pll; unsigned int pixfeed, pixin, pixpost; struct matrox_hw_state *hw = &minfo->hw; DBG(__func__) f_pll = Ti3026_calcclock(minfo, clk, minfo->max_pixel_clock, &pixin, &pixfeed, &pixpost); hw->DACclk[0] = pixin | 0xC0; hw->DACclk[1] = pixfeed; hw->DACclk[2] = pixpost | 0xB0; { unsigned int loopfeed, loopin, looppost, loopdiv, z; unsigned int Bpp; Bpp = minfo->curr.final_bppShift; if (minfo->fbcon.var.bits_per_pixel == 24) { loopfeed = 3; /* set lm to any possible value */ loopin = 3 * 32 / Bpp; } else { loopfeed = 4; loopin = 4 * 32 / Bpp; } z = (110000 * loopin) / (f_pll * loopfeed); loopdiv = 0; /* div 2 */ if (z < 2) looppost = 0; else if (z < 4) looppost = 1; else if (z < 8) looppost = 2; else { looppost = 3; loopdiv = z/16; } if (minfo->fbcon.var.bits_per_pixel == 24) { hw->DACclk[3] = ((65 - loopin) & 0x3F) | 0xC0; hw->DACclk[4] = (65 - loopfeed) | 0x80; if (minfo->accel.ramdac_rev > 0x20) { if (isInterleave(minfo)) hw->DACreg[POS3026_XLATCHCTRL] = TVP3026B_XLATCHCTRL_8_3; else { hw->DACclk[4] &= ~0xC0; hw->DACreg[POS3026_XLATCHCTRL] = TVP3026B_XLATCHCTRL_4_3; } } else { if (isInterleave(minfo)) ; /* default... */ else { hw->DACclk[4] ^= 0xC0; /* change from 0x80 to 0x40 */ hw->DACreg[POS3026_XLATCHCTRL] = TVP3026A_XLATCHCTRL_4_3; } } hw->DACclk[5] = looppost | 0xF8; if (minfo->devflags.mga_24bpp_fix) hw->DACclk[5] ^= 0x40; } else { hw->DACclk[3] = ((65 - loopin) & 0x3F) | 0xC0; hw->DACclk[4] = 65 - loopfeed; hw->DACclk[5] = looppost | 0xF0; } hw->DACreg[POS3026_XMEMPLLCTRL] = loopdiv | TVP3026_XMEMPLLCTRL_MCLK_MCLKPLL | TVP3026_XMEMPLLCTRL_RCLK_LOOPPLL; } return 0; }
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"); }