示例#1
0
static int ccu_mp_set_rate(struct clk_hw *hw, unsigned long rate,
			   unsigned long parent_rate)
{
	struct ccu_mp *cmp = hw_to_ccu_mp(hw);
	unsigned long flags;
	unsigned int max_m, max_p;
	unsigned int m, p;
	u32 reg;

	max_m = cmp->m.max ?: 1 << cmp->m.width;
	max_p = cmp->p.max ?: 1 << ((1 << cmp->p.width) - 1);

	ccu_mp_find_best(parent_rate, rate, max_m, max_p, &m, &p);

	spin_lock_irqsave(cmp->common.lock, flags);

	reg = readl(cmp->common.base + cmp->common.reg);
	reg &= ~GENMASK(cmp->m.width + cmp->m.shift - 1, cmp->m.shift);
	reg &= ~GENMASK(cmp->p.width + cmp->p.shift - 1, cmp->p.shift);
	reg |= (m - cmp->m.offset) << cmp->m.shift;
	reg |= ilog2(p) << cmp->p.shift;

	writel(reg, cmp->common.base + cmp->common.reg);

	spin_unlock_irqrestore(cmp->common.lock, flags);

	return 0;
}
示例#2
0
static int ccu_mp_determine_rate(struct clk_hw *hw,
				 struct clk_rate_request *req)
{
	struct ccu_mp *cmp = hw_to_ccu_mp(hw);

	return ccu_mux_helper_determine_rate(&cmp->common, &cmp->mux,
					     req, ccu_mp_round_rate, cmp);
}
示例#3
0
static unsigned long ccu_mp_recalc_rate(struct clk_hw *hw,
					unsigned long parent_rate)
{
	struct ccu_mp *cmp = hw_to_ccu_mp(hw);
	unsigned int m, p;
	u32 reg;

	reg = readl(cmp->common.base + cmp->common.reg);

	m = reg >> cmp->m.shift;
	m &= (1 << cmp->m.width) - 1;
	m += cmp->m.offset;
	if (!m)
		m++;

	p = reg >> cmp->p.shift;
	p &= (1 << cmp->p.width) - 1;

	return (parent_rate >> p) / m;
}
示例#4
0
static unsigned long ccu_mp_recalc_rate(struct clk_hw *hw,
					unsigned long parent_rate)
{
	struct ccu_mp *cmp = hw_to_ccu_mp(hw);
	unsigned int m, p;
	u32 reg;

	/* Adjust parent_rate according to pre-dividers */
	parent_rate = ccu_mux_helper_apply_prediv(&cmp->common, &cmp->mux, -1,
						  parent_rate);

	reg = readl(cmp->common.base + cmp->common.reg);

	m = reg >> cmp->m.shift;
	m &= (1 << cmp->m.width) - 1;
	m += cmp->m.offset;
	if (!m)
		m++;

	p = reg >> cmp->p.shift;
	p &= (1 << cmp->p.width) - 1;

	return (parent_rate >> p) / m;
}
示例#5
0
static int ccu_mp_is_enabled(struct clk_hw *hw)
{
	struct ccu_mp *cmp = hw_to_ccu_mp(hw);

	return ccu_gate_helper_is_enabled(&cmp->common, cmp->enable);
}
示例#6
0
static void ccu_mp_disable(struct clk_hw *hw)
{
	struct ccu_mp *cmp = hw_to_ccu_mp(hw);

	return ccu_gate_helper_disable(&cmp->common, cmp->enable);
}
示例#7
0
static int ccu_mp_set_parent(struct clk_hw *hw, u8 index)
{
	struct ccu_mp *cmp = hw_to_ccu_mp(hw);

	return ccu_mux_helper_set_parent(&cmp->common, &cmp->mux, index);
}
示例#8
0
static u8 ccu_mp_get_parent(struct clk_hw *hw)
{
	struct ccu_mp *cmp = hw_to_ccu_mp(hw);

	return ccu_mux_helper_get_parent(&cmp->common, &cmp->mux);
}