static struct clk * __init meson_clk_register_fixed_rate(const struct clk_conf *clk_conf, void __iomem *clk_base) { struct clk *clk; const struct fixed_rate_conf *fixed_rate_conf; const struct parm *r; unsigned long rate; u32 reg; fixed_rate_conf = &clk_conf->conf.fixed_rate; rate = fixed_rate_conf->rate; if (!rate) { r = &fixed_rate_conf->rate_parm; reg = readl(clk_base + clk_conf->reg_off + r->reg_off); rate = PARM_GET(r->width, r->shift, reg); } rate *= 1000000; clk = clk_register_fixed_rate(NULL, clk_conf->clk_name, clk_conf->num_parents ? clk_conf->clks_parent[0] : NULL, clk_conf->flags, rate); return clk; }
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; }
static unsigned long meson_clk_cpu_recalc_rate(struct clk_hw *hw, unsigned long parent_rate) { struct meson_clk_cpu *clk_cpu = to_meson_clk_cpu_hw(hw); unsigned int N, sel; unsigned int div = 1; u32 reg; reg = readl(clk_cpu->base + clk_cpu->reg_off + MESON_CPU_CLK_CNTL1); N = PARM_GET(MESON_N_WIDTH, MESON_N_SHIFT, reg); reg = readl(clk_cpu->base + clk_cpu->reg_off + MESON_CPU_CLK_CNTL); sel = PARM_GET(MESON_SEL_WIDTH, MESON_SEL_SHIFT, reg); if (sel < 3) div = sel + 1; else div = 2 * N; return parent_rate / div; }