Ejemplo n.º 1
0
static struct clk * __init
meson_clk_register_fixed_factor(const struct clk_conf *clk_conf,
				void __iomem *clk_base)
{
	struct clk *clk;
	const struct fixed_fact_conf *fixed_fact_conf;
	const struct parm *p;
	unsigned int mult, div;
	u32 reg;

	fixed_fact_conf = &clk_conf->conf.fixed_fact;

	mult = clk_conf->conf.fixed_fact.mult;
	div = clk_conf->conf.fixed_fact.div;

	if (!mult) {
		mult = 1;
		p = &fixed_fact_conf->mult_parm;
		if (MESON_PARM_APPLICABLE(p)) {
			reg = readl(clk_base + clk_conf->reg_off + p->reg_off);
			mult = PARM_GET(p->width, p->shift, reg);
		}
	}

	if (!div) {
		div = 1;
		p = &fixed_fact_conf->div_parm;
		if (MESON_PARM_APPLICABLE(p)) {
			reg = readl(clk_base + clk_conf->reg_off + p->reg_off);
			mult = PARM_GET(p->width, p->shift, reg);
		}
	}

	clk = clk_register_fixed_factor(NULL,
			clk_conf->clk_name,
			clk_conf->clks_parent[0],
			clk_conf->flags,
			mult, div);

	return clk;
}
Ejemplo n.º 2
0
static void mpll_init(struct clk_hw *hw)
{
	struct clk_regmap *clk = to_clk_regmap(hw);
	struct meson_clk_mpll_data *mpll = meson_clk_mpll_data(clk);

	if (mpll->init_count)
		regmap_multi_reg_write(clk->map, mpll->init_regs,
				       mpll->init_count);

	/* Enable the fractional part */
	meson_parm_write(clk->map, &mpll->sdm_en, 1);

	/* Set spread spectrum if possible */
	if (MESON_PARM_APPLICABLE(&mpll->ssen)) {
		unsigned int ss =
			mpll->flags & CLK_MESON_MPLL_SPREAD_SPECTRUM ? 1 : 0;
		meson_parm_write(clk->map, &mpll->ssen, ss);
	}

	/* Set the magic misc bit if required */
	if (MESON_PARM_APPLICABLE(&mpll->misc))
		meson_parm_write(clk->map, &mpll->misc, 1);
}
Ejemplo n.º 3
0
static struct clk * __init
meson_clk_register_composite(const struct clk_conf *clk_conf,
			     void __iomem *clk_base)
{
	struct clk *clk;
	struct clk_mux *mux = NULL;
	struct clk_divider *div = NULL;
	struct clk_gate *gate = NULL;
	const struct clk_ops *mux_ops = NULL;
	const struct composite_conf *composite_conf;

	composite_conf = clk_conf->conf.composite;

	if (clk_conf->num_parents > 1) {
		mux = kzalloc(sizeof(*mux), GFP_KERNEL);
		if (!mux)
			return ERR_PTR(-ENOMEM);

		mux->reg = clk_base + clk_conf->reg_off
				+ composite_conf->mux_parm.reg_off;
		mux->shift = composite_conf->mux_parm.shift;
		mux->mask = BIT(composite_conf->mux_parm.width) - 1;
		mux->flags = composite_conf->mux_flags;
		mux->lock = &clk_lock;
		mux->table = composite_conf->mux_table;
		mux_ops = (composite_conf->mux_flags & CLK_MUX_READ_ONLY) ?
			  &clk_mux_ro_ops : &clk_mux_ops;
	}

	if (MESON_PARM_APPLICABLE(&composite_conf->div_parm)) {
		div = kzalloc(sizeof(*div), GFP_KERNEL);
		if (!div) {
			clk = ERR_PTR(-ENOMEM);
			goto error;
		}

		div->reg = clk_base + clk_conf->reg_off
				+ composite_conf->div_parm.reg_off;
		div->shift = composite_conf->div_parm.shift;
		div->width = composite_conf->div_parm.width;
		div->lock = &clk_lock;
		div->flags = composite_conf->div_flags;
		div->table = composite_conf->div_table;
	}

	if (MESON_PARM_APPLICABLE(&composite_conf->gate_parm)) {
		gate = kzalloc(sizeof(*gate), GFP_KERNEL);
		if (!gate) {
			clk = ERR_PTR(-ENOMEM);
			goto error;
		}

		gate->reg = clk_base + clk_conf->reg_off
				+ composite_conf->div_parm.reg_off;
		gate->bit_idx = composite_conf->gate_parm.shift;
		gate->flags = composite_conf->gate_flags;
		gate->lock = &clk_lock;
	}

	clk = clk_register_composite(NULL, clk_conf->clk_name,
				    clk_conf->clks_parent,
				    clk_conf->num_parents,
				    mux ? &mux->hw : NULL, mux_ops,
				    div ? &div->hw : NULL, &clk_divider_ops,
				    gate ? &gate->hw : NULL, &clk_gate_ops,
				    clk_conf->flags);
	if (IS_ERR(clk))
		goto error;

	return clk;

error:
	kfree(gate);
	kfree(div);
	kfree(mux);

	return clk;
}