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; }
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; }
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; }
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; }
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; }