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()
454 static inline int ingenic_clk_check_stable(struct ingenic_cgu *cgu, in ingenic_clk_check_stable() argument
459 return readl_poll_timeout(cgu->base + clk_info->div.reg, reg, in ingenic_clk_check_stable()
470 struct ingenic_cgu *cgu = ingenic_clk->cgu; in ingenic_clk_set_rate() local
488 spin_lock_irqsave(&cgu->lock, flags); in ingenic_clk_set_rate()
489 reg = readl(cgu->base + clk_info->div.reg); in ingenic_clk_set_rate()
505 writel(reg, cgu->base + clk_info->div.reg); in ingenic_clk_set_rate()
509 ret = ingenic_clk_check_stable(cgu, clk_info); in ingenic_clk_set_rate()
511 spin_unlock_irqrestore(&cgu->lock, flags); in ingenic_clk_set_rate()
522 struct ingenic_cgu *cgu = ingenic_clk->cgu; in ingenic_clk_enable() local
527 spin_lock_irqsave(&cgu->lock, flags); in ingenic_clk_enable()
528 ingenic_cgu_gate_set(cgu, &clk_info->gate, false); in ingenic_clk_enable()
529 spin_unlock_irqrestore(&cgu->lock, flags); in ingenic_clk_enable()
542 struct ingenic_cgu *cgu = ingenic_clk->cgu; in ingenic_clk_disable() local
547 spin_lock_irqsave(&cgu->lock, flags); in ingenic_clk_disable()
548 ingenic_cgu_gate_set(cgu, &clk_info->gate, true); in ingenic_clk_disable()
549 spin_unlock_irqrestore(&cgu->lock, flags); in ingenic_clk_disable()
557 struct ingenic_cgu *cgu = ingenic_clk->cgu; in ingenic_clk_is_enabled() local
561 enabled = !ingenic_cgu_gate_get(cgu, &clk_info->gate); in ingenic_clk_is_enabled()
583 static int ingenic_register_clock(struct ingenic_cgu *cgu, unsigned idx) in ingenic_register_clock() argument
585 const struct ingenic_cgu_clk_info *clk_info = &cgu->clock_info[idx]; in ingenic_register_clock()
596 clk = of_clk_get_by_name(cgu->np, clk_info->name); in ingenic_register_clock()
608 cgu->clocks.clks[idx] = clk; in ingenic_register_clock()
625 ingenic_clk->cgu = cgu; in ingenic_register_clock()
653 parent = cgu->clocks.clks[clk_info->parents[i]]; in ingenic_register_clock()
664 parent = cgu->clocks.clks[clk_info->parents[0]]; in ingenic_register_clock()
719 cgu->clocks.clks[idx] = clk; in ingenic_register_clock()
730 struct ingenic_cgu *cgu; in ingenic_cgu_new() local
732 cgu = kzalloc(sizeof(*cgu), GFP_KERNEL); in ingenic_cgu_new()
733 if (!cgu) in ingenic_cgu_new()
736 cgu->base = of_iomap(np, 0); in ingenic_cgu_new()
737 if (!cgu->base) { in ingenic_cgu_new()
738 pr_err("%s: failed to map CGU registers\n", __func__); in ingenic_cgu_new()
742 cgu->np = np; in ingenic_cgu_new()
743 cgu->clock_info = clock_info; in ingenic_cgu_new()
744 cgu->clocks.clk_num = num_clocks; in ingenic_cgu_new()
746 spin_lock_init(&cgu->lock); in ingenic_cgu_new()
748 return cgu; in ingenic_cgu_new()
751 kfree(cgu); in ingenic_cgu_new()
756 int ingenic_cgu_register_clocks(struct ingenic_cgu *cgu) in ingenic_cgu_register_clocks() argument
761 cgu->clocks.clks = kcalloc(cgu->clocks.clk_num, sizeof(struct clk *), in ingenic_cgu_register_clocks()
763 if (!cgu->clocks.clks) { in ingenic_cgu_register_clocks()
768 for (i = 0; i < cgu->clocks.clk_num; i++) { in ingenic_cgu_register_clocks()
769 err = ingenic_register_clock(cgu, i); in ingenic_cgu_register_clocks()
774 err = of_clk_add_provider(cgu->np, of_clk_src_onecell_get, in ingenic_cgu_register_clocks()
775 &cgu->clocks); in ingenic_cgu_register_clocks()
782 for (i = 0; i < cgu->clocks.clk_num; i++) { in ingenic_cgu_register_clocks()
783 if (!cgu->clocks.clks[i]) in ingenic_cgu_register_clocks()
785 if (cgu->clock_info[i].type & CGU_CLK_EXT) in ingenic_cgu_register_clocks()
786 clk_put(cgu->clocks.clks[i]); in ingenic_cgu_register_clocks()
788 clk_unregister(cgu->clocks.clks[i]); in ingenic_cgu_register_clocks()
790 kfree(cgu->clocks.clks); in ingenic_cgu_register_clocks()