Lines Matching +full:clk +full:- +full:source
1 // SPDX-License-Identifier: GPL-2.0
10 #include <linux/clk.h>
11 #include <linux/clk-provider.h>
21 #include <dt-bindings/clock/r9a06g032-sysctrl.h>
33 uint32_t source : 8; /* source index + 1 (0 == none) */ member
42 /* For fixed-factor ones */
62 .source = 1 + R9A06G032_##_src, .name = _n, \
69 .source = 1 + R9A06G032_##_src, .name = _n, \
73 .source = 1 + R9A06G032_##_src, .name = _n, \
78 .source = 1 + R9A06G032_##_src, .name = _n, \
279 .source = 1 + R9A06G032_DIV_UART,
288 .source = 1 + R9A06G032_DIV_P2_PG,
314 u32 __iomem *reg = clocks->reg + (4 * (one >> 5)); in clk_rdesc_set()
325 u32 __iomem *reg = clocks->reg + (4 * (one >> 5)); in clk_rdesc_get()
352 WARN_ON(!g->gate); in r9a06g032_clk_gate_set()
354 spin_lock_irqsave(&clocks->lock, flags); in r9a06g032_clk_gate_set()
355 clk_rdesc_set(clocks, g->gate, on); in r9a06g032_clk_gate_set()
356 /* De-assert reset */ in r9a06g032_clk_gate_set()
357 if (g->reset) in r9a06g032_clk_gate_set()
358 clk_rdesc_set(clocks, g->reset, 1); in r9a06g032_clk_gate_set()
359 spin_unlock_irqrestore(&clocks->lock, flags); in r9a06g032_clk_gate_set()
368 if (g->ready || g->midle) { in r9a06g032_clk_gate_set()
369 spin_lock_irqsave(&clocks->lock, flags); in r9a06g032_clk_gate_set()
370 if (g->ready) in r9a06g032_clk_gate_set()
371 clk_rdesc_set(clocks, g->ready, on); in r9a06g032_clk_gate_set()
373 if (g->midle) in r9a06g032_clk_gate_set()
374 clk_rdesc_set(clocks, g->midle, !on); in r9a06g032_clk_gate_set()
375 spin_unlock_irqrestore(&clocks->lock, flags); in r9a06g032_clk_gate_set()
384 r9a06g032_clk_gate_set(g->clocks, &g->gate, 1); in r9a06g032_clk_gate_enable()
392 r9a06g032_clk_gate_set(g->clocks, &g->gate, 0); in r9a06g032_clk_gate_disable()
400 if (g->gate.reset && !clk_rdesc_get(g->clocks, g->gate.reset)) in r9a06g032_clk_gate_is_enabled()
403 return clk_rdesc_get(g->clocks, g->gate.gate); in r9a06g032_clk_gate_is_enabled()
412 static struct clk *
417 struct clk *clk; in r9a06g032_register_gate() local
425 init.name = desc->name; in r9a06g032_register_gate()
431 g->clocks = clocks; in r9a06g032_register_gate()
432 g->index = desc->index; in r9a06g032_register_gate()
433 g->gate = desc->gate; in r9a06g032_register_gate()
434 g->hw.init = &init; in r9a06g032_register_gate()
441 if (r9a06g032_clk_gate_is_enabled(&g->hw)) { in r9a06g032_register_gate()
443 pr_debug("%s was enabled, making read-only\n", desc->name); in r9a06g032_register_gate()
446 clk = clk_register(NULL, &g->hw); in r9a06g032_register_gate()
447 if (IS_ERR(clk)) { in r9a06g032_register_gate()
451 return clk; in r9a06g032_register_gate()
471 struct r9a06g032_clk_div *clk = to_r9a06g032_div(hw); in r9a06g032_div_recalc_rate() local
472 u32 __iomem *reg = clk->clocks->reg + (4 * clk->reg); in r9a06g032_div_recalc_rate()
475 if (div < clk->min) in r9a06g032_div_recalc_rate()
476 div = clk->min; in r9a06g032_div_recalc_rate()
477 else if (div > clk->max) in r9a06g032_div_recalc_rate()
478 div = clk->max; in r9a06g032_div_recalc_rate()
489 r9a06g032_div_clamp_div(struct r9a06g032_clk_div *clk, in r9a06g032_div_clamp_div() argument
496 if (div <= clk->min) in r9a06g032_div_clamp_div()
497 return clk->min; in r9a06g032_div_clamp_div()
498 if (div >= clk->max) in r9a06g032_div_clamp_div()
499 return clk->max; in r9a06g032_div_clamp_div()
501 for (i = 0; clk->table_size && i < clk->table_size - 1; i++) { in r9a06g032_div_clamp_div()
502 if (div >= clk->table[i] && div <= clk->table[i + 1]) { in r9a06g032_div_clamp_div()
503 unsigned long m = rate - in r9a06g032_div_clamp_div()
504 DIV_ROUND_UP(prate, clk->table[i]); in r9a06g032_div_clamp_div()
506 DIV_ROUND_UP(prate, clk->table[i + 1]) - in r9a06g032_div_clamp_div()
512 div = p >= m ? clk->table[i] : clk->table[i + 1]; in r9a06g032_div_clamp_div()
523 struct r9a06g032_clk_div *clk = to_r9a06g032_div(hw); in r9a06g032_div_round_rate() local
527 hw->clk, rate, *prate, div); in r9a06g032_div_round_rate()
529 clk->min, DIV_ROUND_UP(*prate, clk->min), in r9a06g032_div_round_rate()
530 clk->max, DIV_ROUND_UP(*prate, clk->max)); in r9a06g032_div_round_rate()
532 div = r9a06g032_div_clamp_div(clk, rate, *prate); in r9a06g032_div_round_rate()
535 * that is 16 times the baud rate -- and that is wildly outside the in r9a06g032_div_round_rate()
542 if (clk->index == R9A06G032_DIV_UART || in r9a06g032_div_round_rate()
543 clk->index == R9A06G032_DIV_P2_PG) { in r9a06g032_div_round_rate()
545 return clk_get_rate(hw->clk); in r9a06g032_div_round_rate()
547 pr_devel("%s %pC %ld / %u = %ld\n", __func__, hw->clk, in r9a06g032_div_round_rate()
556 struct r9a06g032_clk_div *clk = to_r9a06g032_div(hw); in r9a06g032_div_set_rate() local
559 u32 __iomem *reg = clk->clocks->reg + (4 * clk->reg); in r9a06g032_div_set_rate()
561 pr_devel("%s %pC rate %ld parent %ld div %d\n", __func__, hw->clk, in r9a06g032_div_set_rate()
582 static struct clk *
588 struct clk *clk; in r9a06g032_register_div() local
596 init.name = desc->name; in r9a06g032_register_div()
602 div->clocks = clocks; in r9a06g032_register_div()
603 div->index = desc->index; in r9a06g032_register_div()
604 div->reg = desc->reg; in r9a06g032_register_div()
605 div->hw.init = &init; in r9a06g032_register_div()
606 div->min = desc->div_min; in r9a06g032_register_div()
607 div->max = desc->div_max; in r9a06g032_register_div()
609 for (i = 0; i < ARRAY_SIZE(div->table) && in r9a06g032_register_div()
610 i < ARRAY_SIZE(desc->div_table) && desc->div_table[i]; i++) { in r9a06g032_register_div()
611 div->table[div->table_size++] = desc->div_table[i]; in r9a06g032_register_div()
614 clk = clk_register(NULL, &div->hw); in r9a06g032_register_div()
615 if (IS_ERR(clk)) { in r9a06g032_register_div()
619 return clk; in r9a06g032_register_div()
624 * peripherals that have two potential clock source and two gates, one for
625 * each of the clock source - the used clock source (for all sub clocks)
627 * That single bit affects all sub-clocks, and therefore needs to change the
648 return clk_rdesc_get(set->clocks, set->selector); in r9a06g032_clk_mux_get_parent()
656 clk_rdesc_set(set->clocks, set->selector, !!index); in r9a06g032_clk_mux_set_parent()
666 static struct clk *
671 struct clk *clk; in r9a06g032_register_bitsel() local
684 init.name = desc->name; in r9a06g032_register_bitsel()
690 g->clocks = clocks; in r9a06g032_register_bitsel()
691 g->index = desc->index; in r9a06g032_register_bitsel()
692 g->selector = desc->dual.sel; in r9a06g032_register_bitsel()
693 g->hw.init = &init; in r9a06g032_register_bitsel()
695 clk = clk_register(NULL, &g->hw); in r9a06g032_register_bitsel()
696 if (IS_ERR(clk)) { in r9a06g032_register_bitsel()
700 return clk; in r9a06g032_register_bitsel()
717 u8 sel_bit = clk_rdesc_get(g->clocks, g->selector); in r9a06g032_clk_dualgate_setenable()
720 r9a06g032_clk_gate_set(g->clocks, &g->gate[!sel_bit], 0); in r9a06g032_clk_dualgate_setenable()
721 r9a06g032_clk_gate_set(g->clocks, &g->gate[sel_bit], enable); in r9a06g032_clk_dualgate_setenable()
745 u8 sel_bit = clk_rdesc_get(g->clocks, g->selector); in r9a06g032_clk_dualgate_is_enabled()
747 return clk_rdesc_get(g->clocks, g->gate[sel_bit].gate); in r9a06g032_clk_dualgate_is_enabled()
756 static struct clk *
763 struct clk *clk; in r9a06g032_register_dualgate() local
770 g->clocks = clocks; in r9a06g032_register_dualgate()
771 g->index = desc->index; in r9a06g032_register_dualgate()
772 g->selector = sel; in r9a06g032_register_dualgate()
773 g->gate[0].gate = desc->dual.g1; in r9a06g032_register_dualgate()
774 g->gate[0].reset = desc->dual.r1; in r9a06g032_register_dualgate()
775 g->gate[1].gate = desc->dual.g2; in r9a06g032_register_dualgate()
776 g->gate[1].reset = desc->dual.r2; in r9a06g032_register_dualgate()
778 init.name = desc->name; in r9a06g032_register_dualgate()
783 g->hw.init = &init; in r9a06g032_register_dualgate()
789 if (r9a06g032_clk_dualgate_is_enabled(&g->hw)) { in r9a06g032_register_dualgate()
791 pr_debug("%s was enabled, making read-only\n", desc->name); in r9a06g032_register_dualgate()
794 clk = clk_register(NULL, &g->hw); in r9a06g032_register_dualgate()
795 if (IS_ERR(clk)) { in r9a06g032_register_dualgate()
799 return clk; in r9a06g032_register_dualgate()
809 struct device *dev = &pdev->dev; in r9a06g032_clocks_probe()
810 struct device_node *np = dev->of_node; in r9a06g032_clocks_probe()
812 struct clk **clks; in r9a06g032_clocks_probe()
813 struct clk *mclk; in r9a06g032_clocks_probe()
819 clks = devm_kcalloc(dev, R9A06G032_CLOCK_COUNT, sizeof(struct clk *), in r9a06g032_clocks_probe()
822 return -ENOMEM; in r9a06g032_clocks_probe()
824 spin_lock_init(&clocks->lock); in r9a06g032_clocks_probe()
826 clocks->data.clks = clks; in r9a06g032_clocks_probe()
827 clocks->data.clk_num = R9A06G032_CLOCK_COUNT; in r9a06g032_clocks_probe()
833 clocks->reg = of_iomap(np, 0); in r9a06g032_clocks_probe()
834 if (WARN_ON(!clocks->reg)) in r9a06g032_clocks_probe()
835 return -ENOMEM; in r9a06g032_clocks_probe()
838 const char *parent_name = d->source ? in r9a06g032_clocks_probe()
839 __clk_get_name(clocks->data.clks[d->source - 1]) : in r9a06g032_clocks_probe()
841 struct clk *clk = NULL; in r9a06g032_clocks_probe() local
843 switch (d->type) { in r9a06g032_clocks_probe()
845 clk = clk_register_fixed_factor(NULL, d->name, in r9a06g032_clocks_probe()
847 d->mul, d->div); in r9a06g032_clocks_probe()
850 clk = r9a06g032_register_gate(clocks, parent_name, d); in r9a06g032_clocks_probe()
853 clk = r9a06g032_register_div(clocks, parent_name, d); in r9a06g032_clocks_probe()
857 uart_group_sel[d->dual.group] = d->dual.sel; in r9a06g032_clocks_probe()
858 clk = r9a06g032_register_bitsel(clocks, parent_name, d); in r9a06g032_clocks_probe()
861 clk = r9a06g032_register_dualgate(clocks, parent_name, in r9a06g032_clocks_probe()
863 uart_group_sel[d->dual.group]); in r9a06g032_clocks_probe()
866 clocks->data.clks[d->index] = clk; in r9a06g032_clocks_probe()
868 error = of_clk_add_provider(np, of_clk_src_onecell_get, &clocks->data); in r9a06g032_clocks_probe()
877 { .compatible = "renesas,r9a06g032-sysctrl" },
883 .name = "renesas,r9a06g032-sysctrl",