コード例 #1
0
ファイル: clock.c プロジェクト: hugh-smtl/linux-2.6
static int pll1_set_rate(struct clk *clk, u32 rate)
{
#if 0 /* doesn't work on some boards, probably a HW BUG */
	if (rate) {
		clk_reg_disable(clk);	/*enable bit is inverted */
		if (!clk_wait_for_pll_lock(clk)) {
			clk->rate = CLK_RATE_13MHZ;
		} else {
			clk_reg_enable(clk);
			clk->rate = 0;
		}

	} else {
		clk_reg_enable(clk);
		clk->rate = 0;
	}
#endif
	return 0;
}
コード例 #2
0
ファイル: clock.c プロジェクト: 1703011/asuswrt-merlin
static int on_off_inv_set_rate(struct clk *clk, u32 rate)
{
	if (rate) {
		clk_reg_disable(clk);	/*enable bit is inverted */
		clk->rate = 1;
	} else {
		clk_reg_enable(clk);
		clk->rate = 0;
	}
	return 0;
}
コード例 #3
0
ファイル: clock.c プロジェクト: 1703011/asuswrt-merlin
static int on_off_set_rate(struct clk *clk, u32 rate)
{
	if (rate) {
		clk_reg_enable(clk);
		clk->rate = 1;
	} else {
		clk_reg_disable(clk);
		clk->rate = 0;
	}
	return 0;
}
コード例 #4
0
ファイル: clock.c プロジェクト: 1703011/asuswrt-merlin
static int ck_13MHz_set_rate(struct clk *clk, u32 rate)
{
	if (rate) {
		clk_reg_disable(clk);	/*enable bit is inverted */
		udelay(500);
		clk->rate = CLK_RATE_13MHZ;
		ck_1MHz.rate = CLK_RATE_1MHZ;
	} else {
		clk_reg_enable(clk);
		clk->rate = 0;
		ck_1MHz.rate = 0;
	}
	return 0;
}
コード例 #5
0
ファイル: clock.c プロジェクト: 1703011/asuswrt-merlin
static int pll160_set_rate(struct clk *clk, u32 rate)
{
	u32 tmp_reg, tmp_m, tmp_2p, i;
	u32 parent_rate;
	int ret = -EINVAL;

	parent_rate = clk->parent->rate;

	if (!parent_rate)
		goto out;

	/* set direct run for ARM or disable output for others  */
	clk_reg_disable(clk);

	/* disable source input as well (ignored for ARM) */
	clk_reg_disable1(clk);

	tmp_reg = __raw_readl(clk->scale_reg);
	tmp_reg &= ~0x1ffff;	/*clear all settings, power down */
	__raw_writel(tmp_reg, clk->scale_reg);

	rate -= rate % parent_rate;	/*round down the input */

	if (rate > PLL160_MAX_FCCO)
		rate = PLL160_MAX_FCCO;

	if (!rate) {
		clk->rate = 0;
		ret = 0;
		goto out;
	}

	clk_reg_enable1(clk);
	tmp_reg = __raw_readl(clk->scale_reg);

	if (rate == parent_rate) {
		/*enter direct bypass mode */
		tmp_reg |= ((1 << 14) | (1 << 15));
		__raw_writel(tmp_reg, clk->scale_reg);
		clk->rate = parent_rate;
		clk_reg_enable(clk);
		ret = 0;
		goto out;
	}

	i = 0;
	for (tmp_2p = 1; tmp_2p < 16; tmp_2p <<= 1) {
		if (rate * tmp_2p >= PLL160_MIN_FCCO)
			break;
		i++;
	}

	if (tmp_2p > 1)
		tmp_reg |= ((i - 1) << 11);
	else
		tmp_reg |= (1 << 14);	/*direct mode, no divide */

	tmp_m = rate * tmp_2p;
	tmp_m /= parent_rate;

	tmp_reg |= (tmp_m - 1) << 1;	/*calculate M */
	tmp_reg |= (1 << 16);	/*power up PLL */
	__raw_writel(tmp_reg, clk->scale_reg);

	if (clk_wait_for_pll_lock(clk) < 0) {
		clk_reg_disable(clk);
		clk_reg_disable1(clk);

		tmp_reg = __raw_readl(clk->scale_reg);
		tmp_reg &= ~0x1ffff;	/*clear all settings, power down */
		__raw_writel(tmp_reg, clk->scale_reg);
		clk->rate = 0;
		ret = -EFAULT;
		goto out;
	}

	clk->rate = (tmp_m * parent_rate) / tmp_2p;

	if (clk->flags & RATE_PROPAGATES)
		propagate_rate(clk);

	clk_reg_enable(clk);
	ret = 0;

out:
	return ret;
}