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)
;
}
Example #2
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(__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");
}