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)
;
}
示例#3
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");
}