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()
106 ctl = readl(cgu->base + pll_info->bypass_reg); in ingenic_pll_recalc_rate()
187 static inline int ingenic_pll_check_stable(struct ingenic_cgu *cgu, in ingenic_pll_check_stable() argument
195 return readl_poll_timeout(cgu->base + pll_info->reg, ctl, in ingenic_pll_check_stable()
205 struct ingenic_cgu *cgu = ingenic_clk->cgu; in ingenic_pll_set_rate() local
216 pr_info("ingenic-cgu: request '%s' rate %luHz, actual %luHz\n", in ingenic_pll_set_rate()
219 spin_lock_irqsave(&cgu->lock, flags); in ingenic_pll_set_rate()
220 ctl = readl(cgu->base + pll_info->reg); in ingenic_pll_set_rate()
233 writel(ctl, cgu->base + pll_info->reg); in ingenic_pll_set_rate()
240 ret = ingenic_pll_check_stable(cgu, pll_info); in ingenic_pll_set_rate()
242 spin_unlock_irqrestore(&cgu->lock, flags); in ingenic_pll_set_rate()
250 struct ingenic_cgu *cgu = ingenic_clk->cgu; in ingenic_pll_enable() local
260 spin_lock_irqsave(&cgu->lock, flags); in ingenic_pll_enable()
262 ctl = readl(cgu->base + pll_info->bypass_reg); in ingenic_pll_enable()
266 writel(ctl, cgu->base + pll_info->bypass_reg); in ingenic_pll_enable()
269 ctl = readl(cgu->base + pll_info->reg); in ingenic_pll_enable()
273 writel(ctl, cgu->base + pll_info->reg); in ingenic_pll_enable()
275 ret = ingenic_pll_check_stable(cgu, pll_info); in ingenic_pll_enable()
276 spin_unlock_irqrestore(&cgu->lock, flags); in ingenic_pll_enable()
284 struct ingenic_cgu *cgu = ingenic_clk->cgu; in ingenic_pll_disable() local
293 spin_lock_irqsave(&cgu->lock, flags); in ingenic_pll_disable()
294 ctl = readl(cgu->base + pll_info->reg); in ingenic_pll_disable()
298 writel(ctl, cgu->base + pll_info->reg); in ingenic_pll_disable()
299 spin_unlock_irqrestore(&cgu->lock, flags); in ingenic_pll_disable()
305 struct ingenic_cgu *cgu = ingenic_clk->cgu; in ingenic_pll_is_enabled() local
313 ctl = readl(cgu->base + pll_info->reg); in ingenic_pll_is_enabled()
336 struct ingenic_cgu *cgu = ingenic_clk->cgu; in ingenic_clk_get_parent() local
341 reg = readl(cgu->base + clk_info->mux.reg); in ingenic_clk_get_parent()
362 struct ingenic_cgu *cgu = ingenic_clk->cgu; in ingenic_clk_set_parent() local
390 spin_lock_irqsave(&cgu->lock, flags); in ingenic_clk_set_parent()
393 reg = readl(cgu->base + clk_info->mux.reg); in ingenic_clk_set_parent()
396 writel(reg, cgu->base + clk_info->mux.reg); in ingenic_clk_set_parent()
398 spin_unlock_irqrestore(&cgu->lock, flags); in ingenic_clk_set_parent()
410 struct ingenic_cgu *cgu = ingenic_clk->cgu; in ingenic_clk_recalc_rate() local
419 div_reg = readl(cgu->base + clk_info->div.reg); in ingenic_clk_recalc_rate()
513 static inline int ingenic_clk_check_stable(struct ingenic_cgu *cgu, in ingenic_clk_check_stable() argument
518 return readl_poll_timeout(cgu->base + clk_info->div.reg, reg, in ingenic_clk_check_stable()
529 struct ingenic_cgu *cgu = ingenic_clk->cgu; in ingenic_clk_set_rate() local
547 spin_lock_irqsave(&cgu->lock, flags); in ingenic_clk_set_rate()
548 reg = readl(cgu->base + clk_info->div.reg); in ingenic_clk_set_rate()
564 writel(reg, cgu->base + clk_info->div.reg); in ingenic_clk_set_rate()
568 ret = ingenic_clk_check_stable(cgu, clk_info); in ingenic_clk_set_rate()
570 spin_unlock_irqrestore(&cgu->lock, flags); in ingenic_clk_set_rate()
581 struct ingenic_cgu *cgu = ingenic_clk->cgu; in ingenic_clk_enable() local
586 spin_lock_irqsave(&cgu->lock, flags); in ingenic_clk_enable()
587 ingenic_cgu_gate_set(cgu, &clk_info->gate, false); in ingenic_clk_enable()
588 spin_unlock_irqrestore(&cgu->lock, flags); in ingenic_clk_enable()
601 struct ingenic_cgu *cgu = ingenic_clk->cgu; in ingenic_clk_disable() local
606 spin_lock_irqsave(&cgu->lock, flags); in ingenic_clk_disable()
607 ingenic_cgu_gate_set(cgu, &clk_info->gate, true); in ingenic_clk_disable()
608 spin_unlock_irqrestore(&cgu->lock, flags); in ingenic_clk_disable()
616 struct ingenic_cgu *cgu = ingenic_clk->cgu; in ingenic_clk_is_enabled() local
620 enabled = !ingenic_cgu_gate_get(cgu, &clk_info->gate); in ingenic_clk_is_enabled()
642 static int ingenic_register_clock(struct ingenic_cgu *cgu, unsigned idx) in ingenic_register_clock() argument
644 const struct ingenic_cgu_clk_info *clk_info = &cgu->clock_info[idx]; in ingenic_register_clock()
655 clk = of_clk_get_by_name(cgu->np, clk_info->name); in ingenic_register_clock()
667 cgu->clocks.clks[idx] = clk; in ingenic_register_clock()
684 ingenic_clk->cgu = cgu; in ingenic_register_clock()
712 parent = cgu->clocks.clks[clk_info->parents[i]]; in ingenic_register_clock()
723 parent = cgu->clocks.clks[clk_info->parents[0]]; in ingenic_register_clock()
778 cgu->clocks.clks[idx] = clk; in ingenic_register_clock()
789 struct ingenic_cgu *cgu; in ingenic_cgu_new() local
791 cgu = kzalloc(sizeof(*cgu), GFP_KERNEL); in ingenic_cgu_new()
792 if (!cgu) in ingenic_cgu_new()
795 cgu->base = of_iomap(np, 0); in ingenic_cgu_new()
796 if (!cgu->base) { in ingenic_cgu_new()
797 pr_err("%s: failed to map CGU registers\n", __func__); in ingenic_cgu_new()
801 cgu->np = np; in ingenic_cgu_new()
802 cgu->clock_info = clock_info; in ingenic_cgu_new()
803 cgu->clocks.clk_num = num_clocks; in ingenic_cgu_new()
805 spin_lock_init(&cgu->lock); in ingenic_cgu_new()
807 return cgu; in ingenic_cgu_new()
810 kfree(cgu); in ingenic_cgu_new()
815 int ingenic_cgu_register_clocks(struct ingenic_cgu *cgu) in ingenic_cgu_register_clocks() argument
820 cgu->clocks.clks = kcalloc(cgu->clocks.clk_num, sizeof(struct clk *), in ingenic_cgu_register_clocks()
822 if (!cgu->clocks.clks) { in ingenic_cgu_register_clocks()
827 for (i = 0; i < cgu->clocks.clk_num; i++) { in ingenic_cgu_register_clocks()
828 err = ingenic_register_clock(cgu, i); in ingenic_cgu_register_clocks()
833 err = of_clk_add_provider(cgu->np, of_clk_src_onecell_get, in ingenic_cgu_register_clocks()
834 &cgu->clocks); in ingenic_cgu_register_clocks()
841 for (i = 0; i < cgu->clocks.clk_num; i++) { in ingenic_cgu_register_clocks()
842 if (!cgu->clocks.clks[i]) in ingenic_cgu_register_clocks()
844 if (cgu->clock_info[i].type & CGU_CLK_EXT) in ingenic_cgu_register_clocks()
845 clk_put(cgu->clocks.clks[i]); in ingenic_cgu_register_clocks()
847 clk_unregister(cgu->clocks.clks[i]); in ingenic_cgu_register_clocks()
849 kfree(cgu->clocks.clks); in ingenic_cgu_register_clocks()