Lines Matching full:cgu
3 * Ingenic SoC CGU driver
23 #include "cgu.h"
30 return &clk->cgu->clock_info[clk->idx]; in to_clk_info()
35 * @cgu: reference to the CGU whose registers should be read
39 * caller must hold cgu->lock.
44 ingenic_cgu_gate_get(struct ingenic_cgu *cgu, in ingenic_cgu_gate_get() argument
47 return !!(readl(cgu->base + info->reg) & BIT(info->bit)) in ingenic_cgu_gate_get()
53 * @cgu: reference to the CGU whose registers should be modified
59 * The caller must hold cgu->lock.
62 ingenic_cgu_gate_set(struct ingenic_cgu *cgu, in ingenic_cgu_gate_set() argument
65 u32 clkgr = readl(cgu->base + info->reg); in ingenic_cgu_gate_set()
72 writel(clkgr, cgu->base + info->reg); in ingenic_cgu_gate_set()
84 struct ingenic_cgu *cgu = ingenic_clk->cgu; in ingenic_pll_recalc_rate() local
93 ctl = readl(cgu->base + pll_info->reg); in ingenic_pll_recalc_rate()
102 ctl = readl(cgu->base + pll_info->bypass_reg); in ingenic_pll_recalc_rate()
165 static inline int ingenic_pll_check_stable(struct ingenic_cgu *cgu, in ingenic_pll_check_stable() argument
170 return readl_poll_timeout(cgu->base + pll_info->reg, ctl, in ingenic_pll_check_stable()
180 struct ingenic_cgu *cgu = ingenic_clk->cgu; in ingenic_pll_set_rate() local
191 pr_info("ingenic-cgu: request '%s' rate %luHz, actual %luHz\n", in ingenic_pll_set_rate()
194 spin_lock_irqsave(&cgu->lock, flags); in ingenic_pll_set_rate()
195 ctl = readl(cgu->base + pll_info->reg); in ingenic_pll_set_rate()
206 writel(ctl, cgu->base + pll_info->reg); in ingenic_pll_set_rate()
210 ret = ingenic_pll_check_stable(cgu, pll_info); in ingenic_pll_set_rate()
212 spin_unlock_irqrestore(&cgu->lock, flags); in ingenic_pll_set_rate()
220 struct ingenic_cgu *cgu = ingenic_clk->cgu; in ingenic_pll_enable() local
227 spin_lock_irqsave(&cgu->lock, flags); in ingenic_pll_enable()
228 ctl = readl(cgu->base + pll_info->bypass_reg); in ingenic_pll_enable()
232 writel(ctl, cgu->base + pll_info->bypass_reg); in ingenic_pll_enable()
234 ctl = readl(cgu->base + pll_info->reg); in ingenic_pll_enable()
238 writel(ctl, cgu->base + pll_info->reg); in ingenic_pll_enable()
240 ret = ingenic_pll_check_stable(cgu, pll_info); in ingenic_pll_enable()
241 spin_unlock_irqrestore(&cgu->lock, flags); in ingenic_pll_enable()
249 struct ingenic_cgu *cgu = ingenic_clk->cgu; in ingenic_pll_disable() local
255 spin_lock_irqsave(&cgu->lock, flags); in ingenic_pll_disable()
256 ctl = readl(cgu->base + pll_info->reg); in ingenic_pll_disable()
260 writel(ctl, cgu->base + pll_info->reg); in ingenic_pll_disable()
261 spin_unlock_irqrestore(&cgu->lock, flags); in ingenic_pll_disable()
267 struct ingenic_cgu *cgu = ingenic_clk->cgu; in ingenic_pll_is_enabled() local
272 ctl = readl(cgu->base + pll_info->reg); in ingenic_pll_is_enabled()
295 struct ingenic_cgu *cgu = ingenic_clk->cgu; in ingenic_clk_get_parent() local
300 reg = readl(cgu->base + clk_info->mux.reg); in ingenic_clk_get_parent()
321 struct ingenic_cgu *cgu = ingenic_clk->cgu; in ingenic_clk_set_parent() local
349 spin_lock_irqsave(&cgu->lock, flags); in ingenic_clk_set_parent()
352 reg = readl(cgu->base + clk_info->mux.reg); in ingenic_clk_set_parent()
355 writel(reg, cgu->base + clk_info->mux.reg); in ingenic_clk_set_parent()
357 spin_unlock_irqrestore(&cgu->lock, flags); in ingenic_clk_set_parent()
369 struct ingenic_cgu *cgu = ingenic_clk->cgu; in ingenic_clk_recalc_rate() local
374 div_reg = readl(cgu->base + clk_info->div.reg); in ingenic_clk_recalc_rate()
460 static inline int ingenic_clk_check_stable(struct ingenic_cgu *cgu, in ingenic_clk_check_stable() argument
465 return readl_poll_timeout(cgu->base + clk_info->div.reg, reg, in ingenic_clk_check_stable()
476 struct ingenic_cgu *cgu = ingenic_clk->cgu; in ingenic_clk_set_rate() local
494 spin_lock_irqsave(&cgu->lock, flags); in ingenic_clk_set_rate()
495 reg = readl(cgu->base + clk_info->div.reg); in ingenic_clk_set_rate()
511 writel(reg, cgu->base + clk_info->div.reg); in ingenic_clk_set_rate()
515 ret = ingenic_clk_check_stable(cgu, clk_info); in ingenic_clk_set_rate()
517 spin_unlock_irqrestore(&cgu->lock, flags); in ingenic_clk_set_rate()
528 struct ingenic_cgu *cgu = ingenic_clk->cgu; in ingenic_clk_enable() local
533 spin_lock_irqsave(&cgu->lock, flags); in ingenic_clk_enable()
534 ingenic_cgu_gate_set(cgu, &clk_info->gate, false); in ingenic_clk_enable()
535 spin_unlock_irqrestore(&cgu->lock, flags); in ingenic_clk_enable()
548 struct ingenic_cgu *cgu = ingenic_clk->cgu; in ingenic_clk_disable() local
553 spin_lock_irqsave(&cgu->lock, flags); in ingenic_clk_disable()
554 ingenic_cgu_gate_set(cgu, &clk_info->gate, true); in ingenic_clk_disable()
555 spin_unlock_irqrestore(&cgu->lock, flags); in ingenic_clk_disable()
563 struct ingenic_cgu *cgu = ingenic_clk->cgu; in ingenic_clk_is_enabled() local
567 enabled = !ingenic_cgu_gate_get(cgu, &clk_info->gate); in ingenic_clk_is_enabled()
589 static int ingenic_register_clock(struct ingenic_cgu *cgu, unsigned idx) in ingenic_register_clock() argument
591 const struct ingenic_cgu_clk_info *clk_info = &cgu->clock_info[idx]; in ingenic_register_clock()
602 clk = of_clk_get_by_name(cgu->np, clk_info->name); in ingenic_register_clock()
614 cgu->clocks.clks[idx] = clk; in ingenic_register_clock()
631 ingenic_clk->cgu = cgu; in ingenic_register_clock()
659 parent = cgu->clocks.clks[clk_info->parents[i]]; in ingenic_register_clock()
670 parent = cgu->clocks.clks[clk_info->parents[0]]; in ingenic_register_clock()
725 cgu->clocks.clks[idx] = clk; in ingenic_register_clock()
736 struct ingenic_cgu *cgu; in ingenic_cgu_new() local
738 cgu = kzalloc(sizeof(*cgu), GFP_KERNEL); in ingenic_cgu_new()
739 if (!cgu) in ingenic_cgu_new()
742 cgu->base = of_iomap(np, 0); in ingenic_cgu_new()
743 if (!cgu->base) { in ingenic_cgu_new()
744 pr_err("%s: failed to map CGU registers\n", __func__); in ingenic_cgu_new()
748 cgu->np = np; in ingenic_cgu_new()
749 cgu->clock_info = clock_info; in ingenic_cgu_new()
750 cgu->clocks.clk_num = num_clocks; in ingenic_cgu_new()
752 spin_lock_init(&cgu->lock); in ingenic_cgu_new()
754 return cgu; in ingenic_cgu_new()
757 kfree(cgu); in ingenic_cgu_new()
762 int ingenic_cgu_register_clocks(struct ingenic_cgu *cgu) in ingenic_cgu_register_clocks() argument
767 cgu->clocks.clks = kcalloc(cgu->clocks.clk_num, sizeof(struct clk *), in ingenic_cgu_register_clocks()
769 if (!cgu->clocks.clks) { in ingenic_cgu_register_clocks()
774 for (i = 0; i < cgu->clocks.clk_num; i++) { in ingenic_cgu_register_clocks()
775 err = ingenic_register_clock(cgu, i); in ingenic_cgu_register_clocks()
780 err = of_clk_add_provider(cgu->np, of_clk_src_onecell_get, in ingenic_cgu_register_clocks()
781 &cgu->clocks); in ingenic_cgu_register_clocks()
788 for (i = 0; i < cgu->clocks.clk_num; i++) { in ingenic_cgu_register_clocks()
789 if (!cgu->clocks.clks[i]) in ingenic_cgu_register_clocks()
791 if (cgu->clock_info[i].type & CGU_CLK_EXT) in ingenic_cgu_register_clocks()
792 clk_put(cgu->clocks.clks[i]); in ingenic_cgu_register_clocks()
794 clk_unregister(cgu->clocks.clks[i]); in ingenic_cgu_register_clocks()
796 kfree(cgu->clocks.clks); in ingenic_cgu_register_clocks()