Lines Matching +full:clkout +full:- +full:disable
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
62 * @gate: clock enable/disable
74 * de-asserted to bring the module out of reset.
88 K_GATE = 0, /* gate which enable/disable */
96 * struct r9a06g032_clkdesc - describe a single clock
104 * @gate: clock enable/disable
107 * @reg: clock divider register offset, in 32-bit words
110 * @div: divisor for fixed-factor clock
111 * @mul: multiplier for fixed-factor clock
114 * @g1: 1st source gate (clock enable/disable)
116 * @g2: 2nd source gate (clock enable/disable)
257 D_ROOT(CLKOUT, "clkout", 25, 1),
259 D_FFC(CLKOUT_D10, "clkout_d10", CLKOUT, 10),
260 D_FFC(CLKOUT_D16, "clkout_d16", CLKOUT, 16),
261 D_FFC(CLKOUT_D160, "clkout_d160", CLKOUT, 160),
262 D_DIV(CLKOUT_D1OR2, "clkout_d1or2", CLKOUT, 0, 1, 2),
263 D_FFC(CLKOUT_D20, "clkout_d20", CLKOUT, 20),
264 D_FFC(CLKOUT_D40, "clkout_d40", CLKOUT, 40),
265 D_FFC(CLKOUT_D5, "clkout_d5", CLKOUT, 5),
266 D_FFC(CLKOUT_D8, "clkout_d8", CLKOUT, 8),
267 D_DIV(DIV_ADC, "div_adc", CLKOUT, 77, 50, 250),
268 D_DIV(DIV_I2C, "div_i2c", CLKOUT, 78, 12, 16),
269 D_DIV(DIV_NAND, "div_nand", CLKOUT, 82, 12, 32),
270 D_DIV(DIV_P1_PG, "div_p1_pg", CLKOUT, 68, 12, 200),
271 D_DIV(DIV_P2_PG, "div_p2_pg", CLKOUT, 62, 12, 128),
272 D_DIV(DIV_P3_PG, "div_p3_pg", CLKOUT, 64, 8, 128),
273 D_DIV(DIV_P4_PG, "div_p4_pg", CLKOUT, 66, 8, 128),
274 D_DIV(DIV_P5_PG, "div_p5_pg", CLKOUT, 71, 10, 40),
275 D_DIV(DIV_P6_PG, "div_p6_pg", CLKOUT, 18, 12, 64),
276 D_DIV(DIV_QSPI0, "div_qspi0", CLKOUT, 73, 3, 7),
277 D_DIV(DIV_QSPI1, "div_qspi1", CLKOUT, 25, 3, 7),
278 D_DIV(DIV_REF_SYNC, "div_ref_sync", CLKOUT, 56, 2, 16, 2, 4, 8, 16),
279 D_DIV(DIV_SDIO0, "div_sdio0", CLKOUT, 74, 20, 128),
280 D_DIV(DIV_SDIO1, "div_sdio1", CLKOUT, 75, 20, 128),
281 D_DIV(DIV_SWITCH, "div_switch", CLKOUT, 37, 5, 40),
282 D_DIV(DIV_UART, "div_uart", CLKOUT, 79, 12, 128),
681 return -EPROBE_DEFER; in r9a06g032_sysctrl_set_dmamux()
683 spin_lock_irqsave(&sysctrl_priv->lock, flags); in r9a06g032_sysctrl_set_dmamux()
685 dmamux = readl(sysctrl_priv->reg + R9A06G032_SYSCTRL_DMAMUX); in r9a06g032_sysctrl_set_dmamux()
688 writel(dmamux, sysctrl_priv->reg + R9A06G032_SYSCTRL_DMAMUX); in r9a06g032_sysctrl_set_dmamux()
690 spin_unlock_irqrestore(&sysctrl_priv->lock, flags); in r9a06g032_sysctrl_set_dmamux()
699 u32 __iomem *reg = clocks->reg + (rb.reg * 4); in clk_rdesc_set()
712 u32 __iomem *reg = clocks->reg + (rb.reg * 4); in clk_rdesc_get()
761 struct device_node *np = dev->of_node; in r9a06g032_attach_dev()
767 while (!of_parse_phandle_with_args(np, "clocks", "#clock-cells", i++, in r9a06g032_attach_dev()
769 if (clkspec.np != pd->dev.of_node) in r9a06g032_attach_dev()
793 struct device_node *np = dev->of_node; in r9a06g032_add_clk_domain()
798 return -ENOMEM; in r9a06g032_add_clk_domain()
800 pd->name = np->name; in r9a06g032_add_clk_domain()
801 pd->flags = GENPD_FLAG_PM_CLK | GENPD_FLAG_ALWAYS_ON | in r9a06g032_add_clk_domain()
803 pd->attach_dev = r9a06g032_attach_dev; in r9a06g032_add_clk_domain()
804 pd->detach_dev = r9a06g032_detach_dev; in r9a06g032_add_clk_domain()
817 WARN_ON(!g->gate.reg && !g->gate.bit); in r9a06g032_clk_gate_set()
819 spin_lock_irqsave(&clocks->lock, flags); in r9a06g032_clk_gate_set()
820 clk_rdesc_set(clocks, g->gate, on); in r9a06g032_clk_gate_set()
821 /* De-assert reset */ in r9a06g032_clk_gate_set()
822 clk_rdesc_set(clocks, g->reset, 1); in r9a06g032_clk_gate_set()
823 spin_unlock_irqrestore(&clocks->lock, flags); in r9a06g032_clk_gate_set()
832 spin_lock_irqsave(&clocks->lock, flags); in r9a06g032_clk_gate_set()
833 clk_rdesc_set(clocks, g->ready, on); in r9a06g032_clk_gate_set()
835 clk_rdesc_set(clocks, g->midle, !on); in r9a06g032_clk_gate_set()
836 spin_unlock_irqrestore(&clocks->lock, flags); in r9a06g032_clk_gate_set()
845 r9a06g032_clk_gate_set(g->clocks, &g->gate, 1); in r9a06g032_clk_gate_enable()
853 r9a06g032_clk_gate_set(g->clocks, &g->gate, 0); in r9a06g032_clk_gate_disable()
861 if (g->gate.reset.reg && !clk_rdesc_get(g->clocks, g->gate.reset)) in r9a06g032_clk_gate_is_enabled()
864 return clk_rdesc_get(g->clocks, g->gate.gate); in r9a06g032_clk_gate_is_enabled()
869 .disable = r9a06g032_clk_gate_disable,
886 init.name = desc->name; in r9a06g032_register_gate()
892 g->clocks = clocks; in r9a06g032_register_gate()
893 g->index = desc->index; in r9a06g032_register_gate()
894 g->gate = desc->gate; in r9a06g032_register_gate()
895 g->hw.init = &init; in r9a06g032_register_gate()
899 * have to assume they are not Linux's to play with and try to disable in r9a06g032_register_gate()
902 if (r9a06g032_clk_gate_is_enabled(&g->hw)) { in r9a06g032_register_gate()
904 pr_debug("%s was enabled, making read-only\n", desc->name); in r9a06g032_register_gate()
907 clk = clk_register(NULL, &g->hw); in r9a06g032_register_gate()
933 u32 __iomem *reg = clk->clocks->reg + (4 * clk->reg); in r9a06g032_div_recalc_rate()
936 if (div < clk->min) in r9a06g032_div_recalc_rate()
937 div = clk->min; in r9a06g032_div_recalc_rate()
938 else if (div > clk->max) in r9a06g032_div_recalc_rate()
939 div = clk->max; in r9a06g032_div_recalc_rate()
957 if (div <= clk->min) in r9a06g032_div_clamp_div()
958 return clk->min; in r9a06g032_div_clamp_div()
959 if (div >= clk->max) in r9a06g032_div_clamp_div()
960 return clk->max; in r9a06g032_div_clamp_div()
962 for (i = 0; clk->table_size && i < clk->table_size - 1; i++) { in r9a06g032_div_clamp_div()
963 if (div >= clk->table[i] && div <= clk->table[i + 1]) { in r9a06g032_div_clamp_div()
964 unsigned long m = rate - in r9a06g032_div_clamp_div()
965 DIV_ROUND_UP(prate, clk->table[i]); in r9a06g032_div_clamp_div()
967 DIV_ROUND_UP(prate, clk->table[i + 1]) - in r9a06g032_div_clamp_div()
973 div = p >= m ? clk->table[i] : clk->table[i + 1]; in r9a06g032_div_clamp_div()
984 u32 div = DIV_ROUND_UP(req->best_parent_rate, req->rate); in r9a06g032_div_determine_rate()
987 hw->clk, req->rate, req->best_parent_rate, div); in r9a06g032_div_determine_rate()
989 clk->min, DIV_ROUND_UP(req->best_parent_rate, clk->min), in r9a06g032_div_determine_rate()
990 clk->max, DIV_ROUND_UP(req->best_parent_rate, clk->max)); in r9a06g032_div_determine_rate()
992 div = r9a06g032_div_clamp_div(clk, req->rate, req->best_parent_rate); in r9a06g032_div_determine_rate()
995 * that is 16 times the baud rate -- and that is wildly outside the in r9a06g032_div_determine_rate()
1002 if (clk->index == R9A06G032_DIV_UART || in r9a06g032_div_determine_rate()
1003 clk->index == R9A06G032_DIV_P2_PG) { in r9a06g032_div_determine_rate()
1005 req->rate = clk_get_rate(hw->clk); in r9a06g032_div_determine_rate()
1008 req->rate = DIV_ROUND_UP(req->best_parent_rate, div); in r9a06g032_div_determine_rate()
1009 pr_devel("%s %pC %ld / %u = %ld\n", __func__, hw->clk, in r9a06g032_div_determine_rate()
1010 req->best_parent_rate, div, req->rate); in r9a06g032_div_determine_rate()
1021 u32 __iomem *reg = clk->clocks->reg + (4 * clk->reg); in r9a06g032_div_set_rate()
1023 pr_devel("%s %pC rate %ld parent %ld div %d\n", __func__, hw->clk, in r9a06g032_div_set_rate()
1058 init.name = desc->name; in r9a06g032_register_div()
1064 div->clocks = clocks; in r9a06g032_register_div()
1065 div->index = desc->index; in r9a06g032_register_div()
1066 div->reg = desc->reg; in r9a06g032_register_div()
1067 div->hw.init = &init; in r9a06g032_register_div()
1068 div->min = desc->div_min; in r9a06g032_register_div()
1069 div->max = desc->div_max; in r9a06g032_register_div()
1071 for (i = 0; i < ARRAY_SIZE(div->table) && in r9a06g032_register_div()
1072 i < ARRAY_SIZE(desc->div_table) && desc->div_table[i]; i++) { in r9a06g032_register_div()
1073 div->table[div->table_size++] = desc->div_table[i]; in r9a06g032_register_div()
1076 clk = clk_register(NULL, &div->hw); in r9a06g032_register_div()
1087 * each of the clock source - the used clock source (for all sub clocks)
1089 * That single bit affects all sub-clocks, and therefore needs to change the
1110 return clk_rdesc_get(set->clocks, set->selector); in r9a06g032_clk_mux_get_parent()
1118 clk_rdesc_set(set->clocks, set->selector, !!index); in r9a06g032_clk_mux_set_parent()
1147 init.name = desc->name; in r9a06g032_register_bitsel()
1153 g->clocks = clocks; in r9a06g032_register_bitsel()
1154 g->index = desc->index; in r9a06g032_register_bitsel()
1155 g->selector = desc->dual.sel; in r9a06g032_register_bitsel()
1156 g->hw.init = &init; in r9a06g032_register_bitsel()
1158 clk = clk_register(NULL, &g->hw); in r9a06g032_register_bitsel()
1180 u8 sel_bit = clk_rdesc_get(g->clocks, g->selector); in r9a06g032_clk_dualgate_setenable()
1183 r9a06g032_clk_gate_set(g->clocks, &g->gate[!sel_bit], 0); in r9a06g032_clk_dualgate_setenable()
1184 r9a06g032_clk_gate_set(g->clocks, &g->gate[sel_bit], enable); in r9a06g032_clk_dualgate_setenable()
1208 u8 sel_bit = clk_rdesc_get(g->clocks, g->selector); in r9a06g032_clk_dualgate_is_enabled()
1210 return clk_rdesc_get(g->clocks, g->gate[sel_bit].gate); in r9a06g032_clk_dualgate_is_enabled()
1215 .disable = r9a06g032_clk_dualgate_disable,
1233 g->clocks = clocks; in r9a06g032_register_dualgate()
1234 g->index = desc->index; in r9a06g032_register_dualgate()
1235 g->selector = sel; in r9a06g032_register_dualgate()
1236 g->gate[0].gate = desc->dual.g1; in r9a06g032_register_dualgate()
1237 g->gate[0].reset = desc->dual.r1; in r9a06g032_register_dualgate()
1238 g->gate[1].gate = desc->dual.g2; in r9a06g032_register_dualgate()
1239 g->gate[1].reset = desc->dual.r2; in r9a06g032_register_dualgate()
1241 init.name = desc->name; in r9a06g032_register_dualgate()
1246 g->hw.init = &init; in r9a06g032_register_dualgate()
1249 * have to assume they are not Linux's to play with and try to disable in r9a06g032_register_dualgate()
1252 if (r9a06g032_clk_dualgate_is_enabled(&g->hw)) { in r9a06g032_register_dualgate()
1254 pr_debug("%s was enabled, making read-only\n", desc->name); in r9a06g032_register_dualgate()
1257 clk = clk_register(NULL, &g->hw); in r9a06g032_register_dualgate()
1276 "renesas,rzn1-usbf"))) { in r9a06g032_init_h2mode()
1281 usb = readl(clocks->reg + R9A06G032_SYSCTRL_USB); in r9a06g032_init_h2mode()
1290 writel(usb, clocks->reg + R9A06G032_SYSCTRL_USB); in r9a06g032_init_h2mode()
1295 struct device *dev = &pdev->dev; in r9a06g032_clocks_probe()
1296 struct device_node *np = dev->of_node; in r9a06g032_clocks_probe()
1308 return -ENOMEM; in r9a06g032_clocks_probe()
1310 spin_lock_init(&clocks->lock); in r9a06g032_clocks_probe()
1312 clocks->data.clks = clks; in r9a06g032_clocks_probe()
1313 clocks->data.clk_num = R9A06G032_CLOCK_COUNT; in r9a06g032_clocks_probe()
1319 clocks->reg = of_iomap(np, 0); in r9a06g032_clocks_probe()
1320 if (WARN_ON(!clocks->reg)) in r9a06g032_clocks_probe()
1321 return -ENOMEM; in r9a06g032_clocks_probe()
1327 const char *parent_name = d->source ? in r9a06g032_clocks_probe()
1328 __clk_get_name(clocks->data.clks[d->source - 1]) : in r9a06g032_clocks_probe()
1332 switch (d->type) { in r9a06g032_clocks_probe()
1334 clk = clk_register_fixed_factor(NULL, d->name, in r9a06g032_clocks_probe()
1336 d->mul, d->div); in r9a06g032_clocks_probe()
1346 uart_group_sel[d->dual.group] = d->dual.sel; in r9a06g032_clocks_probe()
1352 uart_group_sel[d->dual.group]); in r9a06g032_clocks_probe()
1355 clocks->data.clks[d->index] = clk; in r9a06g032_clocks_probe()
1357 error = of_clk_add_provider(np, of_clk_src_onecell_get, &clocks->data); in r9a06g032_clocks_probe()
1380 { .compatible = "renesas,r9a06g032-sysctrl" },
1386 .name = "renesas,r9a06g032-sysctrl",