예제 #1
0
파일: clk-core.c 프로젝트: OpenNoah/u-boot
/* Get the CCU clock rate */
static unsigned long ccu_clk_get_rate(struct clk *c)
{
	struct ccu_clock *ccu_clk = to_ccu_clk(c);
	debug("%s: %s\n", __func__, c->name);
	c->rate = ccu_clk->freq_tbl[ccu_clk->freq_id];
	return c->rate;
}
예제 #2
0
파일: clk-core.c 프로젝트: OpenNoah/u-boot
/* Get the rate of a bus clock */
static unsigned long bus_clk_get_rate(struct clk *c)
{
	struct bus_clock *bus_clk = to_bus_clk(c);
	struct ccu_clock *ccu_clk;

	debug("%s: %s\n", __func__, c->name);
	ccu_clk = to_ccu_clk(c->parent);

	c->rate = bus_clk->freq_tbl[ccu_clk->freq_id];
	c->div = ccu_clk->freq_tbl[ccu_clk->freq_id] / c->rate;
	return c->rate;
}
static int switch_arm_pll(int freq_id, int policy)
{
	struct opp_info opp_info;
	struct clk *clk;
	struct ccu_clk *ccu_clk;

	clk = clk_get(NULL, KPROC_CCU_CLK_NAME_STR);
	if (IS_ERR_OR_NULL(clk))
		return -EINVAL;

	ccu_clk = to_ccu_clk(clk);
	opp_info.freq_id = freq_id;

	return ccu_set_freq_policy(ccu_clk, CCU_POLICY(policy),
				&opp_info);
}
static int switch_arm_pll(int freq_id, int policy)
{
	int ret = 0;
	struct opp_info opp_info;
	struct clk *clk;
	struct ccu_clk *ccu_clk;

	clk = clk_get(NULL, KPROC_CCU_CLK_NAME_STR);
	if (IS_ERR_OR_NULL(clk)) {
		ret = -EINVAL;
		goto out;
	}
	ccu_clk = to_ccu_clk(clk);

	opp_info.freq_id = freq_id;
	opp_info.ctrl_prms = CCU_POLICY_FREQ_REG_INIT;
	ret = ccu_set_freq_policy(ccu_clk, CCU_POLICY(policy),
				&opp_info);
out:
	return ret;
}
예제 #5
0
파일: clk-core.c 프로젝트: OpenNoah/u-boot
/* Enable a CCU clock */
static int ccu_clk_enable(struct clk *c, int enable)
{
	struct ccu_clock *ccu_clk = to_ccu_clk(c);
	void *base = (void *)c->ccu_clk_mgr_base;
	int ret = 0;
	u32 reg;

	debug("%s: %s\n", __func__, c->name);
	if (!enable)
		return -EINVAL;	/* CCU clock cannot shutdown */

	/* enable access */
	writel(CLK_WR_ACCESS_PASSWORD, base + WR_ACCESS_OFFSET);

	/* config enable for policy engine */
	writel(1, base + ccu_clk->lvm_en_offset);

	/* wait for bit to go to 0 */
	ret = wait_bit(base, ccu_clk->lvm_en_offset, 0, 0);
	if (ret)
		return ret;

	/* freq ID */
	if (!ccu_clk->freq_bit_shift)
		ccu_clk->freq_bit_shift = 8;

	/* Set frequency id for each of the 4 policies */
	reg = ccu_clk->freq_id |
	    (ccu_clk->freq_id << (ccu_clk->freq_bit_shift)) |
	    (ccu_clk->freq_id << (ccu_clk->freq_bit_shift * 2)) |
	    (ccu_clk->freq_id << (ccu_clk->freq_bit_shift * 3));
	writel(reg, base + ccu_clk->policy_freq_offset);

	/* enable all clock mask */
	writel(0x7fffffff, base + ccu_clk->policy0_mask_offset);
	writel(0x7fffffff, base + ccu_clk->policy1_mask_offset);
	writel(0x7fffffff, base + ccu_clk->policy2_mask_offset);
	writel(0x7fffffff, base + ccu_clk->policy3_mask_offset);

	if (ccu_clk->num_policy_masks == 2) {
		writel(0x7fffffff, base + ccu_clk->policy0_mask2_offset);
		writel(0x7fffffff, base + ccu_clk->policy1_mask2_offset);
		writel(0x7fffffff, base + ccu_clk->policy2_mask2_offset);
		writel(0x7fffffff, base + ccu_clk->policy3_mask2_offset);
	}

	/* start policy engine */
	reg = readl(base + ccu_clk->policy_ctl_offset);
	reg |= (POLICY_CTL_GO + POLICY_CTL_GO_ATL);
	writel(reg, base + ccu_clk->policy_ctl_offset);

	/* wait till started */
	ret = wait_bit(base, ccu_clk->policy_ctl_offset, 0, 0);
	if (ret)
		return ret;

	/* disable access */
	writel(0, base + WR_ACCESS_OFFSET);

	return ret;
}