Lines Matching +full:clkout +full:- +full:clock

1 // SPDX-License-Identifier: GPL-2.0
3 * R9A06G032 clock driver
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
63 * @reset: clock module reset (active low)
69 * which controls some aspect of clock gating. The @gate field
70 * is mandatory, this one enables/disables the clock. The
74 * de-asserted to bring the module out of reset.
89 K_FFC, /* fixed factor clock */
96 * struct r9a06g032_clkdesc - describe a single clock
97 * @name: string describing this clock
98 * @managed: boolean indicating if this clock should be
101 * @index: the ID of this clock element
102 * @source: the ID+1 of the parent clock element.
103 * Root clock uses ID of ~0 (PARENT_ID);
104 * @gate: clock enable/disable
105 * @div: substructure for clock divider
106 * @div.min: smallest permitted clock divider
107 * @div.max: largest permitted clock divider
108 * @div.reg: clock divider register offset, in 32-bit words
109 * @div.table: optional list of fixed clock divider values;
111 * @ffc: substructure for fixed-factor clocks
112 * @ffc.div: divisor for fixed-factor clock
113 * @ffc.mul: multiplier for fixed-factor clock
114 * @dual: substructure for dual clock gates
116 * @dual.sel: select either g1/r1 or g2/r2 as clock source
117 * @dual.g1: 1st source gate (clock enable/disable)
119 * @dual.g2: 2nd source gate (clock enable/disable)
122 * Describes a single element in the clock tree hierarchy.
123 * As there are quite a large number of clock elements, this
219 /* Internal clock IDs */
260 D_ROOT(CLKOUT, "clkout", 25, 1),
262 D_FFC(CLKOUT_D10, "clkout_d10", CLKOUT, 10),
263 D_FFC(CLKOUT_D16, "clkout_d16", CLKOUT, 16),
264 D_FFC(CLKOUT_D160, "clkout_d160", CLKOUT, 160),
265 D_DIV(CLKOUT_D1OR2, "clkout_d1or2", CLKOUT, 0, 1, 2),
266 D_FFC(CLKOUT_D20, "clkout_d20", CLKOUT, 20),
267 D_FFC(CLKOUT_D40, "clkout_d40", CLKOUT, 40),
268 D_FFC(CLKOUT_D5, "clkout_d5", CLKOUT, 5),
269 D_FFC(CLKOUT_D8, "clkout_d8", CLKOUT, 8),
270 D_DIV(DIV_ADC, "div_adc", CLKOUT, 77, 50, 250),
271 D_DIV(DIV_I2C, "div_i2c", CLKOUT, 78, 12, 16),
272 D_DIV(DIV_NAND, "div_nand", CLKOUT, 82, 12, 32),
273 D_DIV(DIV_P1_PG, "div_p1_pg", CLKOUT, 68, 12, 200),
274 D_DIV(DIV_P2_PG, "div_p2_pg", CLKOUT, 62, 12, 128),
275 D_DIV(DIV_P3_PG, "div_p3_pg", CLKOUT, 64, 8, 128),
276 D_DIV(DIV_P4_PG, "div_p4_pg", CLKOUT, 66, 8, 128),
277 D_DIV(DIV_P5_PG, "div_p5_pg", CLKOUT, 71, 10, 40),
278 D_DIV(DIV_P6_PG, "div_p6_pg", CLKOUT, 18, 12, 64),
279 D_DIV(DIV_QSPI0, "div_qspi0", CLKOUT, 73, 3, 7),
280 D_DIV(DIV_QSPI1, "div_qspi1", CLKOUT, 25, 3, 7),
281 D_DIV(DIV_REF_SYNC, "div_ref_sync", CLKOUT, 56, 2, 16, 2, 4, 8, 16),
282 D_DIV(DIV_SDIO0, "div_sdio0", CLKOUT, 74, 20, 128),
283 D_DIV(DIV_SDIO1, "div_sdio1", CLKOUT, 75, 20, 128),
284 D_DIV(DIV_SWITCH, "div_switch", CLKOUT, 37, 5, 40),
285 D_DIV(DIV_UART, "div_uart", CLKOUT, 79, 12, 128),
631 * parent for a clock, but also the gate it's supposed to use.
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()
722 * This implements the R9A06G032 clock gate 'driver'. We cannot use the system's
723 * clock gate framework as the gates on the R9A06G032 have a special enabling
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()
828 /* Hardware manual recommends 5us delay after enabling clock & reset */ 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()
863 /* if clock is in reset, the gate might be on, and still not 'be' on */ in r9a06g032_clk_gate_is_enabled()
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()
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()
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()
997 * this is a hack. Currently the serial driver asks for a clock 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()
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()
1088 * This clock provider handles the case of the R9A06G032 where you have
1089 * peripherals that have two potential clock source and two gates, one for
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
1095 * This implements two clock providers, one 'bitselect' that
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",