Lines Matching +full:ideal +full:- +full:factor +full:- +full:value

1 // SPDX-License-Identifier: GPL-2.0
11 #include <linux/clk-provider.h>
24 #include <linux/soc/renesas/r9a06g032-sysctrl.h>
26 #include <dt-bindings/clock/r9a06g032-sysctrl.h>
33 * struct regbit - describe one bit in a register
35 * expressed in units of 32-bit words (not bytes),
43 * Since registers are aligned on 32-bit boundaries, the
44 * offset will be specified in 32-bit words rather than bytes.
48 * offset from bytes to 32-bit words.
61 * struct r9a06g032_gate - clock-related control bits
74 * de-asserted to bring the module out of reset.
89 K_FFC, /* fixed factor clock */
96 * struct r9a06g032_clkdesc - describe a single clock
108 * @div.reg: clock divider register offset, in 32-bit words
111 * @ffc: substructure for fixed-factor clocks
112 * @ffc.div: divisor for fixed-factor clock
113 * @ffc.mul: multiplier for fixed-factor clock
684 return -EPROBE_DEFER; in r9a06g032_sysctrl_set_dmamux()
686 spin_lock_irqsave(&sysctrl_priv->lock, flags); in r9a06g032_sysctrl_set_dmamux()
688 dmamux = readl(sysctrl_priv->reg + R9A06G032_SYSCTRL_DMAMUX); in r9a06g032_sysctrl_set_dmamux()
691 writel(dmamux, sysctrl_priv->reg + R9A06G032_SYSCTRL_DMAMUX); in r9a06g032_sysctrl_set_dmamux()
693 spin_unlock_irqrestore(&sysctrl_priv->lock, flags); in r9a06g032_sysctrl_set_dmamux()
702 u32 __iomem *reg = clocks->reg + (rb.reg * 4); in clk_rdesc_set()
715 u32 __iomem *reg = clocks->reg + (rb.reg * 4); in clk_rdesc_get()
764 struct device_node *np = dev->of_node; in r9a06g032_attach_dev()
770 while (!of_parse_phandle_with_args(np, "clocks", "#clock-cells", i++, in r9a06g032_attach_dev()
772 if (clkspec.np != pd->dev.of_node) in r9a06g032_attach_dev()
796 struct device_node *np = dev->of_node; in r9a06g032_add_clk_domain()
801 return -ENOMEM; in r9a06g032_add_clk_domain()
803 pd->name = np->name; in r9a06g032_add_clk_domain()
804 pd->flags = GENPD_FLAG_PM_CLK | GENPD_FLAG_ALWAYS_ON | in r9a06g032_add_clk_domain()
806 pd->attach_dev = r9a06g032_attach_dev; in r9a06g032_add_clk_domain()
807 pd->detach_dev = r9a06g032_detach_dev; in r9a06g032_add_clk_domain()
820 WARN_ON(!g->gate.reg && !g->gate.bit); in r9a06g032_clk_gate_set()
822 spin_lock_irqsave(&clocks->lock, flags); in r9a06g032_clk_gate_set()
823 clk_rdesc_set(clocks, g->gate, on); in r9a06g032_clk_gate_set()
824 /* De-assert reset */ in r9a06g032_clk_gate_set()
825 clk_rdesc_set(clocks, g->reset, 1); in r9a06g032_clk_gate_set()
826 spin_unlock_irqrestore(&clocks->lock, flags); in r9a06g032_clk_gate_set()
835 spin_lock_irqsave(&clocks->lock, flags); in r9a06g032_clk_gate_set()
836 clk_rdesc_set(clocks, g->ready, on); in r9a06g032_clk_gate_set()
838 clk_rdesc_set(clocks, g->midle, !on); in r9a06g032_clk_gate_set()
839 spin_unlock_irqrestore(&clocks->lock, flags); in r9a06g032_clk_gate_set()
848 r9a06g032_clk_gate_set(g->clocks, &g->gate, 1); in r9a06g032_clk_gate_enable()
856 r9a06g032_clk_gate_set(g->clocks, &g->gate, 0); in r9a06g032_clk_gate_disable()
864 if (g->gate.reset.reg && !clk_rdesc_get(g->clocks, g->gate.reset)) in r9a06g032_clk_gate_is_enabled()
867 return clk_rdesc_get(g->clocks, g->gate.gate); in r9a06g032_clk_gate_is_enabled()
889 init.name = desc->name; in r9a06g032_register_gate()
895 g->clocks = clocks; in r9a06g032_register_gate()
896 g->index = desc->index; in r9a06g032_register_gate()
897 g->gate = desc->gate; in r9a06g032_register_gate()
898 g->hw.init = &init; in r9a06g032_register_gate()
905 if (r9a06g032_clk_gate_is_enabled(&g->hw)) { in r9a06g032_register_gate()
907 pr_debug("%s was enabled, making read-only\n", desc->name); in r9a06g032_register_gate()
910 clk = clk_register(NULL, &g->hw); in r9a06g032_register_gate()
936 u32 __iomem *reg = clk->clocks->reg + (4 * clk->reg); in r9a06g032_div_recalc_rate()
939 if (div < clk->min) in r9a06g032_div_recalc_rate()
940 div = clk->min; in r9a06g032_div_recalc_rate()
941 else if (div > clk->max) in r9a06g032_div_recalc_rate()
942 div = clk->max; in r9a06g032_div_recalc_rate()
947 * Attempts to find a value that is in range of min,max,
960 if (div <= clk->min) in r9a06g032_div_clamp_div()
961 return clk->min; in r9a06g032_div_clamp_div()
962 if (div >= clk->max) in r9a06g032_div_clamp_div()
963 return clk->max; in r9a06g032_div_clamp_div()
965 for (i = 0; clk->table_size && i < clk->table_size - 1; i++) { in r9a06g032_div_clamp_div()
966 if (div >= clk->table[i] && div <= clk->table[i + 1]) { in r9a06g032_div_clamp_div()
967 unsigned long m = rate - in r9a06g032_div_clamp_div()
968 DIV_ROUND_UP(prate, clk->table[i]); in r9a06g032_div_clamp_div()
970 DIV_ROUND_UP(prate, clk->table[i + 1]) - in r9a06g032_div_clamp_div()
974 * the value closest to the ideal frequency in r9a06g032_div_clamp_div()
976 div = p >= m ? clk->table[i] : clk->table[i + 1]; in r9a06g032_div_clamp_div()
987 u32 div = DIV_ROUND_UP(req->best_parent_rate, req->rate); in r9a06g032_div_determine_rate()
990 hw->clk, req->rate, req->best_parent_rate, div); in r9a06g032_div_determine_rate()
992 clk->min, DIV_ROUND_UP(req->best_parent_rate, clk->min), in r9a06g032_div_determine_rate()
993 clk->max, DIV_ROUND_UP(req->best_parent_rate, clk->max)); in r9a06g032_div_determine_rate()
995 div = r9a06g032_div_clamp_div(clk, req->rate, req->best_parent_rate); in r9a06g032_div_determine_rate()
998 * that is 16 times the baud rate -- and that is wildly outside the in r9a06g032_div_determine_rate()
1005 if (clk->index == R9A06G032_DIV_UART || in r9a06g032_div_determine_rate()
1006 clk->index == R9A06G032_DIV_P2_PG) { in r9a06g032_div_determine_rate()
1008 req->rate = clk_get_rate(hw->clk); in r9a06g032_div_determine_rate()
1011 req->rate = DIV_ROUND_UP(req->best_parent_rate, div); in r9a06g032_div_determine_rate()
1012 pr_devel("%s %pC %ld / %u = %ld\n", __func__, hw->clk, in r9a06g032_div_determine_rate()
1013 req->best_parent_rate, div, req->rate); in r9a06g032_div_determine_rate()
1024 u32 __iomem *reg = clk->clocks->reg + (4 * clk->reg); in r9a06g032_div_set_rate()
1026 pr_devel("%s %pC rate %ld parent %ld div %d\n", __func__, hw->clk, in r9a06g032_div_set_rate()
1030 * Need to write the bit 31 with the divider value to in r9a06g032_div_set_rate()
1061 init.name = desc->name; in r9a06g032_register_div()
1067 div->clocks = clocks; in r9a06g032_register_div()
1068 div->index = desc->index; in r9a06g032_register_div()
1069 div->reg = desc->div.reg; in r9a06g032_register_div()
1070 div->hw.init = &init; in r9a06g032_register_div()
1071 div->min = desc->div.min; in r9a06g032_register_div()
1072 div->max = desc->div.max; in r9a06g032_register_div()
1074 for (i = 0; i < ARRAY_SIZE(div->table) && in r9a06g032_register_div()
1075 i < ARRAY_SIZE(desc->div.table) && desc->div.table[i]; i++) { in r9a06g032_register_div()
1076 div->table[div->table_size++] = desc->div.table[i]; in r9a06g032_register_div()
1079 clk = clk_register(NULL, &div->hw); in r9a06g032_register_div()
1090 * each of the clock source - the used clock source (for all sub clocks)
1092 * That single bit affects all sub-clocks, and therefore needs to change the
1113 return clk_rdesc_get(set->clocks, set->selector); in r9a06g032_clk_mux_get_parent()
1121 clk_rdesc_set(set->clocks, set->selector, !!index); in r9a06g032_clk_mux_set_parent()
1150 init.name = desc->name; in r9a06g032_register_bitsel()
1156 g->clocks = clocks; in r9a06g032_register_bitsel()
1157 g->index = desc->index; in r9a06g032_register_bitsel()
1158 g->selector = desc->dual.sel; in r9a06g032_register_bitsel()
1159 g->hw.init = &init; in r9a06g032_register_bitsel()
1161 clk = clk_register(NULL, &g->hw); in r9a06g032_register_bitsel()
1183 u8 sel_bit = clk_rdesc_get(g->clocks, g->selector); in r9a06g032_clk_dualgate_setenable()
1186 r9a06g032_clk_gate_set(g->clocks, &g->gate[!sel_bit], 0); in r9a06g032_clk_dualgate_setenable()
1187 r9a06g032_clk_gate_set(g->clocks, &g->gate[sel_bit], enable); in r9a06g032_clk_dualgate_setenable()
1211 u8 sel_bit = clk_rdesc_get(g->clocks, g->selector); in r9a06g032_clk_dualgate_is_enabled()
1213 return clk_rdesc_get(g->clocks, g->gate[sel_bit].gate); in r9a06g032_clk_dualgate_is_enabled()
1236 g->clocks = clocks; in r9a06g032_register_dualgate()
1237 g->index = desc->index; in r9a06g032_register_dualgate()
1238 g->selector = sel; in r9a06g032_register_dualgate()
1239 g->gate[0].gate = desc->dual.g1; in r9a06g032_register_dualgate()
1240 g->gate[0].reset = desc->dual.r1; in r9a06g032_register_dualgate()
1241 g->gate[1].gate = desc->dual.g2; in r9a06g032_register_dualgate()
1242 g->gate[1].reset = desc->dual.r2; in r9a06g032_register_dualgate()
1244 init.name = desc->name; in r9a06g032_register_dualgate()
1249 g->hw.init = &init; in r9a06g032_register_dualgate()
1255 if (r9a06g032_clk_dualgate_is_enabled(&g->hw)) { in r9a06g032_register_dualgate()
1257 pr_debug("%s was enabled, making read-only\n", desc->name); in r9a06g032_register_dualgate()
1260 clk = clk_register(NULL, &g->hw); in r9a06g032_register_dualgate()
1278 for_each_compatible_node(usbf_np, NULL, "renesas,rzn1-usbf") { in r9a06g032_init_h2mode()
1283 usb = readl(clocks->reg + R9A06G032_SYSCTRL_USB); in r9a06g032_init_h2mode()
1292 writel(usb, clocks->reg + R9A06G032_SYSCTRL_USB); in r9a06g032_init_h2mode()
1297 struct device *dev = &pdev->dev; in r9a06g032_clocks_probe()
1298 struct device_node *np = dev->of_node; in r9a06g032_clocks_probe()
1310 return -ENOMEM; in r9a06g032_clocks_probe()
1312 spin_lock_init(&clocks->lock); in r9a06g032_clocks_probe()
1314 clocks->data.clks = clks; in r9a06g032_clocks_probe()
1315 clocks->data.clk_num = R9A06G032_CLOCK_COUNT; in r9a06g032_clocks_probe()
1321 clocks->reg = of_iomap(np, 0); in r9a06g032_clocks_probe()
1322 if (WARN_ON(!clocks->reg)) in r9a06g032_clocks_probe()
1323 return -ENOMEM; in r9a06g032_clocks_probe()
1329 const char *parent_name = d->source ? in r9a06g032_clocks_probe()
1330 __clk_get_name(clocks->data.clks[d->source - 1]) : in r9a06g032_clocks_probe()
1334 switch (d->type) { in r9a06g032_clocks_probe()
1336 clk = clk_register_fixed_factor(NULL, d->name, in r9a06g032_clocks_probe()
1338 d->ffc.mul, in r9a06g032_clocks_probe()
1339 d->ffc.div); in r9a06g032_clocks_probe()
1349 uart_group_sel[d->dual.group] = d->dual.sel; in r9a06g032_clocks_probe()
1355 uart_group_sel[d->dual.group]); in r9a06g032_clocks_probe()
1358 clocks->data.clks[d->index] = clk; in r9a06g032_clocks_probe()
1360 error = of_clk_add_provider(np, of_clk_src_onecell_get, &clocks->data); in r9a06g032_clocks_probe()
1383 { .compatible = "renesas,r9a06g032-sysctrl" },
1389 .name = "renesas,r9a06g032-sysctrl",