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>
25 #include <linux/soc/renesas/r9a06g032-sysctrl.h>
27 #include <dt-bindings/clock/r9a06g032-sysctrl.h>
42 * struct regbit - describe one bit in a register
44 * expressed in units of 32-bit words (not bytes),
52 * Since registers are aligned on 32-bit boundaries, the
53 * offset will be specified in 32-bit words rather than bytes.
57 * offset from bytes to 32-bit words.
70 * struct r9a06g032_gate - clock-related control bits
83 * de-asserted to bring the module out of reset.
105 * struct r9a06g032_clkdesc - describe a single clock
111 * @source: the ID+1 of the parent clock element.
117 * @div.reg: clock divider register offset, in 32-bit words
120 * @ffc: substructure for fixed-factor clocks
121 * @ffc.div: divisor for fixed-factor clock
122 * @ffc.mul: multiplier for fixed-factor clock
125 * @dual.sel: select either g1/r1 or g2/r2 as clock source
126 * @dual.g1: 1st source gate (clock enable/disable)
127 * @dual.r1: 1st source reset (module reset)
128 * @dual.g2: 2nd source gate (clock enable/disable)
129 * @dual.r2: 2nd source reset (module reset)
140 uint32_t source:8; /* source index + 1 (0 == none) */ member
177 .source = 1 + R9A06G032_##_src, \
184 .source = 1 + R9A06G032_##_src, \
199 .source = 1 + R9A06G032_##_src, \
207 .source = 1 + R9A06G032_##_src, \
217 .source = 1 + R9A06G032_##_src, \
646 .source = 1 + R9A06G032_DIV_UART,
655 .source = 1 + R9A06G032_DIV_P2_PG,
693 return -EPROBE_DEFER; in r9a06g032_sysctrl_set_dmamux()
695 spin_lock_irqsave(&sysctrl_priv->lock, flags); in r9a06g032_sysctrl_set_dmamux()
697 dmamux = readl(sysctrl_priv->reg + R9A06G032_SYSCTRL_DMAMUX); in r9a06g032_sysctrl_set_dmamux()
700 writel(dmamux, sysctrl_priv->reg + R9A06G032_SYSCTRL_DMAMUX); in r9a06g032_sysctrl_set_dmamux()
702 spin_unlock_irqrestore(&sysctrl_priv->lock, flags); in r9a06g032_sysctrl_set_dmamux()
711 u32 __iomem *reg = clocks->reg + (rb.reg * 4); in clk_rdesc_set()
724 u32 __iomem *reg = clocks->reg + (rb.reg * 4); in clk_rdesc_get()
748 struct clk *clk; in create_add_module_clock() local
751 clk = of_clk_get_from_provider(clkspec); in create_add_module_clock()
752 if (IS_ERR(clk)) in create_add_module_clock()
753 return PTR_ERR(clk); in create_add_module_clock()
757 clk_put(clk); in create_add_module_clock()
761 error = pm_clk_add_clk(dev, clk); in create_add_module_clock()
764 clk_put(clk); in create_add_module_clock()
773 struct device_node *np = dev->of_node; in r9a06g032_attach_dev()
779 while (!of_parse_phandle_with_args(np, "clocks", "#clock-cells", i++, in r9a06g032_attach_dev()
781 if (clkspec.np != pd->dev.of_node) in r9a06g032_attach_dev()
805 struct device_node *np = dev->of_node; in r9a06g032_add_clk_domain()
810 return -ENOMEM; in r9a06g032_add_clk_domain()
812 pd->name = np->name; in r9a06g032_add_clk_domain()
813 pd->flags = GENPD_FLAG_PM_CLK | GENPD_FLAG_ALWAYS_ON | in r9a06g032_add_clk_domain()
815 pd->attach_dev = r9a06g032_attach_dev; in r9a06g032_add_clk_domain()
816 pd->detach_dev = r9a06g032_detach_dev; in r9a06g032_add_clk_domain()
829 WARN_ON(!g->gate.reg && !g->gate.bit); in r9a06g032_clk_gate_set()
831 spin_lock_irqsave(&clocks->lock, flags); in r9a06g032_clk_gate_set()
832 clk_rdesc_set(clocks, g->gate, on); in r9a06g032_clk_gate_set()
833 /* De-assert reset */ in r9a06g032_clk_gate_set()
834 clk_rdesc_set(clocks, g->reset, 1); in r9a06g032_clk_gate_set()
835 spin_unlock_irqrestore(&clocks->lock, flags); in r9a06g032_clk_gate_set()
844 spin_lock_irqsave(&clocks->lock, flags); in r9a06g032_clk_gate_set()
845 clk_rdesc_set(clocks, g->ready, on); in r9a06g032_clk_gate_set()
847 clk_rdesc_set(clocks, g->midle, !on); in r9a06g032_clk_gate_set()
848 spin_unlock_irqrestore(&clocks->lock, flags); in r9a06g032_clk_gate_set()
857 r9a06g032_clk_gate_set(g->clocks, &g->gate, 1); in r9a06g032_clk_gate_enable()
865 r9a06g032_clk_gate_set(g->clocks, &g->gate, 0); in r9a06g032_clk_gate_disable()
873 if (g->gate.reset.reg && !clk_rdesc_get(g->clocks, g->gate.reset)) in r9a06g032_clk_gate_is_enabled()
876 return clk_rdesc_get(g->clocks, g->gate.gate); in r9a06g032_clk_gate_is_enabled()
885 static struct clk *
890 struct clk *clk; in r9a06g032_register_gate() local
898 init.name = desc->name; in r9a06g032_register_gate()
904 g->clocks = clocks; in r9a06g032_register_gate()
905 g->index = desc->index; in r9a06g032_register_gate()
906 g->gate = desc->gate; in r9a06g032_register_gate()
907 g->hw.init = &init; in r9a06g032_register_gate()
914 if (r9a06g032_clk_gate_is_enabled(&g->hw)) { in r9a06g032_register_gate()
916 pr_debug("%s was enabled, making read-only\n", desc->name); in r9a06g032_register_gate()
919 clk = clk_register(NULL, &g->hw); in r9a06g032_register_gate()
920 if (IS_ERR(clk)) { in r9a06g032_register_gate()
924 return clk; in r9a06g032_register_gate()
944 struct r9a06g032_clk_div *clk = to_r9a06g032_div(hw); in r9a06g032_div_recalc_rate() local
945 u32 __iomem *reg = clk->clocks->reg + (4 * clk->reg); in r9a06g032_div_recalc_rate()
948 if (div < clk->min) in r9a06g032_div_recalc_rate()
949 div = clk->min; in r9a06g032_div_recalc_rate()
950 else if (div > clk->max) in r9a06g032_div_recalc_rate()
951 div = clk->max; in r9a06g032_div_recalc_rate()
962 r9a06g032_div_clamp_div(struct r9a06g032_clk_div *clk, in r9a06g032_div_clamp_div() argument
969 if (div <= clk->min) in r9a06g032_div_clamp_div()
970 return clk->min; in r9a06g032_div_clamp_div()
971 if (div >= clk->max) in r9a06g032_div_clamp_div()
972 return clk->max; in r9a06g032_div_clamp_div()
974 for (i = 0; clk->table_size && i < clk->table_size - 1; i++) { in r9a06g032_div_clamp_div()
975 if (div >= clk->table[i] && div <= clk->table[i + 1]) { in r9a06g032_div_clamp_div()
976 unsigned long m = rate - in r9a06g032_div_clamp_div()
977 DIV_ROUND_UP(prate, clk->table[i]); in r9a06g032_div_clamp_div()
979 DIV_ROUND_UP(prate, clk->table[i + 1]) - in r9a06g032_div_clamp_div()
985 div = p >= m ? clk->table[i] : clk->table[i + 1]; in r9a06g032_div_clamp_div()
995 struct r9a06g032_clk_div *clk = to_r9a06g032_div(hw); in r9a06g032_div_determine_rate() local
996 u32 div = DIV_ROUND_UP(req->best_parent_rate, req->rate); in r9a06g032_div_determine_rate()
999 hw->clk, req->rate, req->best_parent_rate, div); in r9a06g032_div_determine_rate()
1001 clk->min, DIV_ROUND_UP(req->best_parent_rate, clk->min), in r9a06g032_div_determine_rate()
1002 clk->max, DIV_ROUND_UP(req->best_parent_rate, clk->max)); in r9a06g032_div_determine_rate()
1004 div = r9a06g032_div_clamp_div(clk, req->rate, req->best_parent_rate); in r9a06g032_div_determine_rate()
1007 * that is 16 times the baud rate -- and that is wildly outside the in r9a06g032_div_determine_rate()
1014 if (clk->index == R9A06G032_DIV_UART || in r9a06g032_div_determine_rate()
1015 clk->index == R9A06G032_DIV_P2_PG) { in r9a06g032_div_determine_rate()
1017 req->rate = clk_get_rate(hw->clk); in r9a06g032_div_determine_rate()
1020 req->rate = DIV_ROUND_UP(req->best_parent_rate, div); in r9a06g032_div_determine_rate()
1021 pr_devel("%s %pC %ld / %u = %ld\n", __func__, hw->clk, in r9a06g032_div_determine_rate()
1022 req->best_parent_rate, div, req->rate); in r9a06g032_div_determine_rate()
1030 struct r9a06g032_clk_div *clk = to_r9a06g032_div(hw); in r9a06g032_div_set_rate() local
1033 u32 __iomem *reg = clk->clocks->reg + (4 * clk->reg); in r9a06g032_div_set_rate()
1035 pr_devel("%s %pC rate %ld parent %ld div %d\n", __func__, hw->clk, in r9a06g032_div_set_rate()
1056 static struct clk *
1062 struct clk *clk; in r9a06g032_register_div() local
1070 init.name = desc->name; in r9a06g032_register_div()
1076 div->clocks = clocks; in r9a06g032_register_div()
1077 div->index = desc->index; in r9a06g032_register_div()
1078 div->reg = desc->div.reg; in r9a06g032_register_div()
1079 div->hw.init = &init; in r9a06g032_register_div()
1080 div->min = desc->div.min; in r9a06g032_register_div()
1081 div->max = desc->div.max; in r9a06g032_register_div()
1083 for (i = 0; i < ARRAY_SIZE(div->table) && in r9a06g032_register_div()
1084 i < ARRAY_SIZE(desc->div.table) && desc->div.table[i]; i++) { in r9a06g032_register_div()
1085 div->table[div->table_size++] = desc->div.table[i]; in r9a06g032_register_div()
1088 clk = clk_register(NULL, &div->hw); in r9a06g032_register_div()
1089 if (IS_ERR(clk)) { in r9a06g032_register_div()
1093 return clk; in r9a06g032_register_div()
1098 * peripherals that have two potential clock source and two gates, one for
1099 * each of the clock source - the used clock source (for all sub clocks)
1101 * That single bit affects all sub-clocks, and therefore needs to change the
1122 return clk_rdesc_get(set->clocks, set->selector); in r9a06g032_clk_mux_get_parent()
1130 clk_rdesc_set(set->clocks, set->selector, !!index); in r9a06g032_clk_mux_set_parent()
1141 static struct clk *
1146 struct clk *clk; in r9a06g032_register_bitsel() local
1159 init.name = desc->name; in r9a06g032_register_bitsel()
1165 g->clocks = clocks; in r9a06g032_register_bitsel()
1166 g->index = desc->index; in r9a06g032_register_bitsel()
1167 g->selector = desc->dual.sel; in r9a06g032_register_bitsel()
1168 g->hw.init = &init; in r9a06g032_register_bitsel()
1170 clk = clk_register(NULL, &g->hw); in r9a06g032_register_bitsel()
1171 if (IS_ERR(clk)) { in r9a06g032_register_bitsel()
1175 return clk; in r9a06g032_register_bitsel()
1192 u8 sel_bit = clk_rdesc_get(g->clocks, g->selector); in r9a06g032_clk_dualgate_setenable()
1195 r9a06g032_clk_gate_set(g->clocks, &g->gate[!sel_bit], 0); in r9a06g032_clk_dualgate_setenable()
1196 r9a06g032_clk_gate_set(g->clocks, &g->gate[sel_bit], enable); in r9a06g032_clk_dualgate_setenable()
1220 u8 sel_bit = clk_rdesc_get(g->clocks, g->selector); in r9a06g032_clk_dualgate_is_enabled()
1222 return clk_rdesc_get(g->clocks, g->gate[sel_bit].gate); in r9a06g032_clk_dualgate_is_enabled()
1231 static struct clk *
1238 struct clk *clk; in r9a06g032_register_dualgate() local
1245 g->clocks = clocks; in r9a06g032_register_dualgate()
1246 g->index = desc->index; in r9a06g032_register_dualgate()
1247 g->selector = sel; in r9a06g032_register_dualgate()
1248 g->gate[0].gate = desc->dual.g1; in r9a06g032_register_dualgate()
1249 g->gate[0].reset = desc->dual.r1; in r9a06g032_register_dualgate()
1250 g->gate[1].gate = desc->dual.g2; in r9a06g032_register_dualgate()
1251 g->gate[1].reset = desc->dual.r2; in r9a06g032_register_dualgate()
1253 init.name = desc->name; in r9a06g032_register_dualgate()
1258 g->hw.init = &init; in r9a06g032_register_dualgate()
1264 if (r9a06g032_clk_dualgate_is_enabled(&g->hw)) { in r9a06g032_register_dualgate()
1266 pr_debug("%s was enabled, making read-only\n", desc->name); in r9a06g032_register_dualgate()
1269 clk = clk_register(NULL, &g->hw); in r9a06g032_register_dualgate()
1270 if (IS_ERR(clk)) { in r9a06g032_register_dualgate()
1274 return clk; in r9a06g032_register_dualgate()
1284 writel(R9A06G032_SYSCTRL_SWRST, sysctrl_priv->reg + R9A06G032_SYSCTRL_RSTCTRL); in r9a06g032_restart_handler()
1293 for_each_compatible_node(usbf_np, NULL, "renesas,rzn1-usbf") { in r9a06g032_init_h2mode()
1298 usb = readl(clocks->reg + R9A06G032_SYSCTRL_USB); in r9a06g032_init_h2mode()
1307 writel(usb, clocks->reg + R9A06G032_SYSCTRL_USB); in r9a06g032_init_h2mode()
1312 struct device *dev = &pdev->dev; in r9a06g032_clocks_probe()
1313 struct device_node *np = dev->of_node; in r9a06g032_clocks_probe()
1315 struct clk **clks; in r9a06g032_clocks_probe()
1316 struct clk *mclk; in r9a06g032_clocks_probe()
1322 clks = devm_kcalloc(dev, R9A06G032_CLOCK_COUNT, sizeof(struct clk *), in r9a06g032_clocks_probe()
1325 return -ENOMEM; in r9a06g032_clocks_probe()
1327 spin_lock_init(&clocks->lock); in r9a06g032_clocks_probe()
1329 clocks->data.clks = clks; in r9a06g032_clocks_probe()
1330 clocks->data.clk_num = R9A06G032_CLOCK_COUNT; in r9a06g032_clocks_probe()
1336 clocks->reg = of_iomap(np, 0); in r9a06g032_clocks_probe()
1337 if (WARN_ON(!clocks->reg)) in r9a06g032_clocks_probe()
1338 return -ENOMEM; in r9a06g032_clocks_probe()
1344 clocks->reg + R9A06G032_SYSCTRL_RSTCTRL); in r9a06g032_clocks_probe()
1347 clocks->reg + R9A06G032_SYSCTRL_RSTEN); in r9a06g032_clocks_probe()
1356 const char *parent_name = d->source ? in r9a06g032_clocks_probe()
1357 __clk_get_name(clocks->data.clks[d->source - 1]) : in r9a06g032_clocks_probe()
1359 struct clk *clk = NULL; in r9a06g032_clocks_probe() local
1361 switch (d->type) { in r9a06g032_clocks_probe()
1363 clk = clk_register_fixed_factor(NULL, d->name, in r9a06g032_clocks_probe()
1365 d->ffc.mul, in r9a06g032_clocks_probe()
1366 d->ffc.div); in r9a06g032_clocks_probe()
1369 clk = r9a06g032_register_gate(clocks, parent_name, d); in r9a06g032_clocks_probe()
1372 clk = r9a06g032_register_div(clocks, parent_name, d); in r9a06g032_clocks_probe()
1376 uart_group_sel[d->dual.group] = d->dual.sel; in r9a06g032_clocks_probe()
1377 clk = r9a06g032_register_bitsel(clocks, parent_name, d); in r9a06g032_clocks_probe()
1380 clk = r9a06g032_register_dualgate(clocks, parent_name, in r9a06g032_clocks_probe()
1382 uart_group_sel[d->dual.group]); in r9a06g032_clocks_probe()
1385 clocks->data.clks[d->index] = clk; in r9a06g032_clocks_probe()
1387 error = of_clk_add_provider(np, of_clk_src_onecell_get, &clocks->data); in r9a06g032_clocks_probe()
1410 { .compatible = "renesas,r9a06g032-sysctrl" },
1416 .name = "renesas,r9a06g032-sysctrl",