jh7100_clkc.c revision 1.3 1 /* $NetBSD: jh7100_clkc.c,v 1.3 2024/07/27 07:09:50 skrll Exp $ */
2
3 /*-
4 * Copyright (c) 2023 The NetBSD Foundation, Inc.
5 * All rights reserved.
6 *
7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Nick Hudson
9 *
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
12 * are met:
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE.
30 */
31
32 #include <sys/cdefs.h>
33 __KERNEL_RCSID(0, "$NetBSD: jh7100_clkc.c,v 1.3 2024/07/27 07:09:50 skrll Exp $");
34
35 #include <sys/param.h>
36
37 #include <sys/bus.h>
38 #include <sys/device.h>
39
40 #include <dev/clk/clk_backend.h>
41
42 #include <dev/fdt/fdtvar.h>
43
44 #include <riscv/starfive/jh71x0_clkc.h>
45
46
47 #define JH7100_CLK_CPUNDBUS_ROOT 0
48 #define JH7100_CLK_DSP_ROOT 2
49 #define JH7100_CLK_GMACUSB_ROOT 3
50 #define JH7100_CLK_PERH0_ROOT 4
51 #define JH7100_CLK_PERH1_ROOT 5
52 #define JH7100_CLK_VOUT_ROOT 7
53 #define JH7100_CLK_AUDIO_ROOT 8
54 #define JH7100_CLK_VOUTBUS_ROOT 11
55 #define JH7100_CLK_CPUNBUS_ROOT_DIV 12
56 #define JH7100_CLK_DSP_ROOT_DIV 13
57 #define JH7100_CLK_PERH0_SRC 14
58 #define JH7100_CLK_PERH1_SRC 15
59 #define JH7100_CLK_PLL2_REF 19
60 #define JH7100_CLK_CPU_CORE 20
61 #define JH7100_CLK_CPU_AXI 21
62 #define JH7100_CLK_AHB_BUS 22
63 #define JH7100_CLK_APB1_BUS 23
64 #define JH7100_CLK_APB2_BUS 24
65 #define JH7100_CLK_DOM7AHB_BUS 26
66 #define JH7100_CLK_SGDMA2P_AXI 31
67 #define JH7100_CLK_SGDMA2P_AHB 33
68 #define JH7100_CLK_VP6_CORE 38
69 #define JH7100_CLK_JPEG_APB 50
70 #define JH7100_CLK_SGDMA1P_BUS 84
71 #define JH7100_CLK_SGDMA1P_AXI 85
72 #define JH7100_CLK_AUDIO_DIV 95
73 #define JH7100_CLK_AUDIO_SRC 96
74 #define JH7100_CLK_AUDIO_12288 97
75 #define JH7100_CLK_VOUT_SRC 109
76 #define JH7100_CLK_DISPBUS_SRC 110
77 #define JH7100_CLK_DISP_BUS 111
78 #define JH7100_CLK_DISP_AXI 112
79 #define JH7100_CLK_SDIO0_AHB 114
80 #define JH7100_CLK_SDIO0_CCLKINT 115
81 #define JH7100_CLK_SDIO0_CCLKINT_INV 116
82 #define JH7100_CLK_SDIO1_AHB 117
83 #define JH7100_CLK_SDIO1_CCLKINT 118
84 #define JH7100_CLK_SDIO1_CCLKINT_INV 119
85 #define JH7100_CLK_GMAC_AHB 120
86 #define JH7100_CLK_GMAC_ROOT_DIV 121
87 #define JH7100_CLK_GMAC_PTP_REF 122
88 #define JH7100_CLK_GMAC_GTX 123
89 #define JH7100_CLK_GMAC_RMII_TX 124
90 #define JH7100_CLK_GMAC_RMII_RX 125
91 #define JH7100_CLK_GMAC_TX 126
92 #define JH7100_CLK_GMAC_TX_INV 127
93 #define JH7100_CLK_GMAC_RX_PRE 128
94 #define JH7100_CLK_GMAC_RX_INV 129
95 #define JH7100_CLK_GMAC_RMII 130
96 #define JH7100_CLK_GMAC_TOPHYREF 131
97 #define JH7100_CLK_QSPI_AHB 137
98 #define JH7100_CLK_SEC_AHB 140
99 #define JH7100_CLK_TRNG_APB 144
100 #define JH7100_CLK_OTP_APB 145
101 #define JH7100_CLK_UART0_APB 146
102 #define JH7100_CLK_UART0_CORE 147
103 #define JH7100_CLK_UART1_APB 148
104 #define JH7100_CLK_UART1_CORE 149
105 #define JH7100_CLK_SPI0_APB 150
106 #define JH7100_CLK_SPI0_CORE 151
107 #define JH7100_CLK_SPI1_APB 152
108 #define JH7100_CLK_SPI1_CORE 153
109 #define JH7100_CLK_I2C0_APB 154
110 #define JH7100_CLK_I2C0_CORE 155
111 #define JH7100_CLK_I2C1_APB 156
112 #define JH7100_CLK_I2C1_CORE 157
113 #define JH7100_CLK_GPIO_APB 158
114 #define JH7100_CLK_UART2_APB 159
115 #define JH7100_CLK_UART2_CORE 160
116 #define JH7100_CLK_UART3_APB 161
117 #define JH7100_CLK_UART3_CORE 162
118 #define JH7100_CLK_SPI2_APB 163
119 #define JH7100_CLK_SPI2_CORE 164
120 #define JH7100_CLK_SPI3_APB 165
121 #define JH7100_CLK_SPI3_CORE 166
122 #define JH7100_CLK_I2C2_APB 167
123 #define JH7100_CLK_I2C2_CORE 168
124 #define JH7100_CLK_I2C3_APB 169
125 #define JH7100_CLK_I2C3_CORE 170
126 #define JH7100_CLK_WDTIMER_APB 171
127 #define JH7100_CLK_WDT_CORE 172
128 #define JH7100_CLK_PWM_APB 181
129
130 #define JH7100_CLK_PLL0_OUT 186
131 #define JH7100_CLK_PLL1_OUT 187
132 #define JH7100_CLK_PLL2_OUT 188
133
134 #define JH7100_NCLKS 189
135
136
137 static const char *cpundbus_root_parents[] = {
138 "osc_sys", "pll0_out", "pll1_out", "pll2_out",
139 };
140
141 static const char *dsp_root_parents[] = {
142 "osc_sys", "pll0_out", "pll1_out", "pll2_out",
143 };
144
145 static const char *gmacusb_root_parents[] = {
146 "osc_sys", "pll0_out", "pll2_out",
147 };
148
149 static const char *perh0_root_parents[] = {
150 "osc_sys", "pll0_out",
151 };
152
153 static const char *perh1_root_parents[] = {
154 "osc_sys", "pll2_out",
155 };
156
157 static const char *pll2_refclk_parents[] = {
158 "osc_sys", "osc_aud",
159 };
160
161 static const char *vout_root_parents[] = {
162 "osc_aud", "pll0_out", "pll2_out",
163 };
164
165 static const char *gmac_rx_pre_parents[] = {
166 "gmac_gr_mii_rxclk", "gmac_rmii_rxclk",
167 };
168
169 static const char *gmac_tx_parents[] = {
170 "gmac_gtxclk", "gmac_tx_inv", "gmac_rmii_txclk",
171 };
172
173
174 static struct jh71x0_clkc_clk jh7100_clocks[] = {
175 JH71X0CLKC_FIXED_FACTOR(JH7100_CLK_PLL0_OUT, "pll0_out", "osc_sys", 1, 40),
176 JH71X0CLKC_FIXED_FACTOR(JH7100_CLK_PLL1_OUT, "pll1_out", "osc_sys", 1, 64),
177 JH71X0CLKC_FIXED_FACTOR(JH7100_CLK_PLL2_OUT, "pll2_out", "pll2_refclk", 1, 55),
178
179 JH71X0CLKC_MUX(JH7100_CLK_CPUNDBUS_ROOT, "cpundbus_root", cpundbus_root_parents),
180 JH71X0CLKC_MUX(JH7100_CLK_DSP_ROOT, "dsp_root", dsp_root_parents),
181 JH71X0CLKC_MUX(JH7100_CLK_GMACUSB_ROOT, "gmacusb_root", gmacusb_root_parents),
182 JH71X0CLKC_MUX(JH7100_CLK_PERH0_ROOT, "perh0_root", perh0_root_parents),
183 JH71X0CLKC_MUX(JH7100_CLK_PERH1_ROOT, "perh1_root", perh1_root_parents),
184 JH71X0CLKC_MUX(JH7100_CLK_PLL2_REF, "pll2_refclk", pll2_refclk_parents),
185
186 JH71X0CLKC_MUX(JH7100_CLK_VOUT_ROOT, "vout_root", vout_root_parents),
187 JH71X0CLKC_MUX(JH7100_CLK_VOUTBUS_ROOT, "voutbus_root", vout_root_parents),
188
189 JH71X0CLKC_MUX_FLAGS(JH7100_CLK_GMAC_TX, "gmac_tx", gmac_tx_parents, CLK_SET_RATE_PARENT),
190
191 JH71X0CLKC_MUX(JH7100_CLK_GMAC_RX_PRE, "gmac_rx_pre", gmac_rx_pre_parents),
192
193 JH71X0CLKC_DIV(JH7100_CLK_CPUNBUS_ROOT_DIV, "cpunbus_root_div",
194 2, "cpundbus_root"),
195 JH71X0CLKC_DIV(JH7100_CLK_PERH0_SRC, "perh0_src", 4, "perh0_root"),
196 JH71X0CLKC_DIV(JH7100_CLK_PERH1_SRC, "perh1_src", 4, "perh1_root"),
197
198 JH71X0CLKC_DIV(JH7100_CLK_AHB_BUS, "ahb_bus", 8, "cpunbus_root_div"),
199 JH71X0CLKC_DIV(JH7100_CLK_APB1_BUS, "apb1_bus", 8, "ahb_bus"),
200 JH71X0CLKC_DIV(JH7100_CLK_APB2_BUS, "apb2_bus", 8, "ahb_bus"),
201 JH71X0CLKC_DIV(JH7100_CLK_CPU_CORE, "cpu_core", 8, "cpunbus_root_div"),
202 JH71X0CLKC_DIV(JH7100_CLK_CPU_AXI, "cpu_axi", 8, "cpu_core"),
203 JH71X0CLKC_DIV(JH7100_CLK_GMAC_ROOT_DIV, "gmac_root_div", 8, "gmacusb_root"),
204 JH71X0CLKC_DIV(JH7100_CLK_DSP_ROOT_DIV, "dsp_root_div", 4, "dsp_root"),
205 JH71X0CLKC_DIV(JH7100_CLK_SGDMA1P_BUS, "sgdma1p_bus", 8, "cpunbus_root_div"),
206
207 JH71X0CLKC_DIV(JH7100_CLK_DISPBUS_SRC, "dispbus_src", 4, "voutbus_root"),
208
209 JH71X0CLKC_DIV(JH7100_CLK_DISP_BUS, "disp_bus", 4, "dispbus_src"),
210
211 JH71X0CLKC_GATE(JH7100_CLK_UART0_APB, "uart0_apb", "apb1_bus"),
212 JH71X0CLKC_GATE(JH7100_CLK_UART1_APB, "uart1_apb", "apb1_bus"),
213 JH71X0CLKC_GATE(JH7100_CLK_UART2_APB, "uart2_apb", "apb2_bus"),
214 JH71X0CLKC_GATE(JH7100_CLK_UART3_APB, "uart3_apb", "apb2_bus"),
215 JH71X0CLKC_GATE(JH7100_CLK_SGDMA2P_AXI, "sgdma2p_axi", "cpu_axi"),
216 JH71X0CLKC_GATE(JH7100_CLK_SGDMA2P_AHB, "sgdma2p_ahb", "ahb_bus"),
217 JH71X0CLKC_GATE(JH7100_CLK_SGDMA1P_AXI, "sgdma1p_axi", "sgdma1p_bus"),
218 JH71X0CLKC_GATE(JH7100_CLK_GPIO_APB, "gpio_apb", "apb1_bus"),
219 JH71X0CLKC_GATE(JH7100_CLK_I2C0_APB, "i2c0_apb", "apb1_bus"),
220 JH71X0CLKC_GATE(JH7100_CLK_I2C1_APB, "i2c1_apb", "apb1_bus"),
221 JH71X0CLKC_GATE(JH7100_CLK_I2C2_APB, "i2c2_apb", "apb2_bus"),
222 JH71X0CLKC_GATE(JH7100_CLK_I2C3_APB, "i2c3_apb", "apb2_bus"),
223 JH71X0CLKC_GATE(JH7100_CLK_TRNG_APB, "trng_apb", "apb1_bus"),
224 JH71X0CLKC_GATE(JH7100_CLK_SEC_AHB, "sec_ahb", "ahb_bus"),
225 JH71X0CLKC_GATE(JH7100_CLK_GMAC_AHB, "gmac_ahb", "ahb_bus"),
226 JH71X0CLKC_GATE(JH7100_CLK_GMAC_AHB, "gmac_ahb", "ahb_bus"),
227 JH71X0CLKC_GATE(JH7100_CLK_JPEG_APB, "jpeg_apb", "apb1_bus"),
228 JH71X0CLKC_GATE(JH7100_CLK_PWM_APB, "pwm_apb", "apb2_bus"),
229 JH71X0CLKC_GATE(JH7100_CLK_QSPI_AHB, "qspi_ahb", "ahb_bus"),
230 JH71X0CLKC_GATE(JH7100_CLK_SPI0_APB, "spi0_apb", "apb1_bus"),
231 JH71X0CLKC_GATE(JH7100_CLK_SPI1_APB, "spi1_apb", "apb1_bus"),
232 JH71X0CLKC_GATE(JH7100_CLK_SPI2_APB, "spi2_apb", "apb2_bus"),
233 JH71X0CLKC_GATE(JH7100_CLK_SPI3_APB, "spi3_apb", "apb2_bus"),
234 JH71X0CLKC_GATE(JH7100_CLK_SDIO0_AHB, "sdio0_ahb", "ahb_bus"),
235 JH71X0CLKC_GATE(JH7100_CLK_SDIO1_AHB, "sdio1_ahb", "ahb_bus"),
236 JH71X0CLKC_GATE(JH7100_CLK_OTP_APB, "otp_apb", "apb1_bus"),
237 JH71X0CLKC_GATE(JH7100_CLK_DOM7AHB_BUS, "dom7ahb_bus", "ahb_bus"),
238 JH71X0CLKC_GATE(JH7100_CLK_AUDIO_SRC, "audio_src", "audio_div"),
239 JH71X0CLKC_GATE(JH7100_CLK_AUDIO_12288, "audio_12288", "osc_aud"),
240
241 JH71X0CLKC_GATE(JH7100_CLK_DISP_AXI, "disp_axi", "disp_bus"),
242
243 JH71X0CLKC_GATE(JH7100_CLK_GMAC_RMII, "gmac_rmii", "gmac_rmii_ref"),
244
245 JH71X0CLKC_GATE(JH7100_CLK_WDTIMER_APB, "wdtimer_apb", "apb2_bus"),
246
247 JH71X0CLKC_GATEDIV(JH7100_CLK_UART0_CORE, "uart0_core", 63, "perh1_src"),
248 JH71X0CLKC_GATEDIV(JH7100_CLK_UART1_CORE, "uart1_core", 63, "perh1_src"),
249 JH71X0CLKC_GATEDIV(JH7100_CLK_UART2_CORE, "uart2_core", 63, "perh0_src"),
250 JH71X0CLKC_GATEDIV(JH7100_CLK_UART3_CORE, "uart3_core", 63, "perh0_src"),
251 JH71X0CLKC_GATEDIV(JH7100_CLK_I2C0_CORE, "i2c0_core", 63, "perh1_src"),
252 JH71X0CLKC_GATEDIV(JH7100_CLK_I2C1_CORE, "i2c1_core", 63, "perh1_src"),
253 JH71X0CLKC_GATEDIV(JH7100_CLK_I2C2_CORE, "i2c2_core", 63, "perh0_src"),
254 JH71X0CLKC_GATEDIV(JH7100_CLK_I2C3_CORE, "i2c3_core", 63, "perh0_src"),
255 JH71X0CLKC_GATEDIV(JH7100_CLK_GMAC_PTP_REF, "gmac_ptp_refclk", 31, "gmac_root_div"),
256 JH71X0CLKC_GATEDIV(JH7100_CLK_VP6_CORE, "vp6_core", 4, "dsp_root_div"),
257 JH71X0CLKC_GATEDIV(JH7100_CLK_VP6_CORE, "vp6_core", 4, "dsp_root_div"),
258 JH71X0CLKC_GATEDIV(JH7100_CLK_SPI0_CORE, "spi0_core", 63, "perh1_src"),
259 JH71X0CLKC_GATEDIV(JH7100_CLK_SPI1_CORE, "spi1_core", 63, "perh1_src"),
260 JH71X0CLKC_GATEDIV(JH7100_CLK_SPI2_CORE, "spi2_core", 63, "perh0_src"),
261 JH71X0CLKC_GATEDIV(JH7100_CLK_SPI3_CORE, "spi3_core", 63, "perh0_src"),
262 JH71X0CLKC_GATEDIV(JH7100_CLK_VP6_CORE, "vp6_core", 4, "dsp_root_div"),
263 JH71X0CLKC_GATEDIV(JH7100_CLK_SDIO0_CCLKINT, "sdio0_cclkint", 24, "perh0_src"),
264 JH71X0CLKC_GATEDIV(JH7100_CLK_SDIO1_CCLKINT, "sdio1_cclkint", 24, "perh1_src"),
265 JH71X0CLKC_GATEDIV(JH7100_CLK_AUDIO_ROOT, "audio_root", 8, "pll0_out"),
266 JH71X0CLKC_GATEDIV(JH7100_CLK_VOUT_SRC, "vout_src", 4, "vout_root"),
267 JH71X0CLKC_GATEDIV(JH7100_CLK_WDT_CORE, "wdt_coreclk", 63, "perh0_src"),
268 JH71X0CLKC_GATEDIV(JH7100_CLK_GMAC_GTX, "gmac_gtxclk", 255, "gmac_root_div"),
269 JH71X0CLKC_GATEDIV(JH7100_CLK_GMAC_RMII_TX, "gmac_rmii_txclk", 8, "gmac_rmii_ref"),
270 JH71X0CLKC_GATEDIV(JH7100_CLK_GMAC_RMII_RX, "gmac_rmii_rxclk", 8, "gmac_rmii_ref"),
271 JH71X0CLKC_GATEDIV(JH7100_CLK_GMAC_TOPHYREF, "gmac_tophyref", 127, "gmac_root_div"),
272
273 JH71X0CLKC_FRACDIV(JH7100_CLK_AUDIO_DIV, "audio_div", "audio_root"),
274
275 JH71X0CLKC_INV(JH7100_CLK_SDIO0_CCLKINT_INV, "sdio0_cclkint_inv", "sdio0_cclkint"),
276 JH71X0CLKC_INV(JH7100_CLK_SDIO1_CCLKINT_INV, "sdio1_cclkint_inv", "sdio1_cclkint"),
277 JH71X0CLKC_INV(JH7100_CLK_GMAC_RX_INV, "gmac_rx_inv", "gmac_rx_pre"),
278 JH71X0CLKC_INV(JH7100_CLK_GMAC_TX_INV, "gmac_tx_inv", "gmac_tx"),
279 };
280
281
282 static const struct device_compatible_entry compat_data[] = {
283 { .compat = "starfive,jh7100-clkgen" },
284 DEVICE_COMPAT_EOL
285 };
286
287
288 static struct clk *
289 jh7100_clkc_fdt_decode(device_t dev, int phandle, const void *data,
290 size_t len)
291 {
292 struct jh71x0_clkc_softc * const sc = device_private(dev);
293
294 if (len != 4)
295 return NULL;
296
297 u_int id = be32dec(data);
298 if (id >= sc->sc_nclks)
299 return NULL;
300
301 if (sc->sc_clk[id].jcc_type == JH71X0CLK_UNKNOWN) {
302 printf("Unknown clock %d\n", id);
303 return NULL;
304 }
305 return &sc->sc_clk[id].jcc_clk;
306 }
307
308 static const struct fdtbus_clock_controller_func jh7100_clkc_fdt_funcs = {
309 .decode = jh7100_clkc_fdt_decode
310 };
311
312 static int
313 jh7100_clkc_match(device_t parent, cfdata_t cf, void *aux)
314 {
315 struct fdt_attach_args * const faa = aux;
316
317 return of_compatible_match(faa->faa_phandle, compat_data);
318 }
319
320 static void
321 jh7100_clkc_attach(device_t parent, device_t self, void *aux)
322 {
323 struct jh71x0_clkc_softc * const sc = device_private(self);
324 struct fdt_attach_args * const faa = aux;
325 const int phandle = faa->faa_phandle;
326 bus_addr_t addr;
327 bus_size_t size;
328 int error;
329
330 error = fdtbus_get_reg(phandle, 0, &addr, &size);
331 if (error) {
332 aprint_error(": couldn't get registers\n");
333 return;
334 }
335
336 sc->sc_dev = self;
337 sc->sc_phandle = phandle;
338 sc->sc_bst = faa->faa_bst;
339 error = bus_space_map(sc->sc_bst, addr, size, 0, &sc->sc_bsh);
340 if (error) {
341 aprint_error(": couldn't map registers\n");
342 return;
343 }
344
345 struct clk * const osclk = fdtbus_clock_get(phandle, "osc_sys");
346 if (osclk == NULL) {
347 aprint_error(": couldn't get osc_sys\n");
348 return;
349 }
350 u_int osclk_rate = clk_get_rate(osclk);
351
352 struct clk * const oaclk = fdtbus_clock_get(phandle, "osc_aud");
353 if (oaclk == NULL) {
354 aprint_error(": couldn't get osc_aud\n");
355 return;
356 }
357 u_int oaclk_rate = clk_get_rate(oaclk);
358
359 sc->sc_clkdom.name = device_xname(self);
360 sc->sc_clkdom.funcs = &jh71x0_clkc_funcs;
361 sc->sc_clkdom.priv = sc;
362
363 sc->sc_clk = jh7100_clocks;
364 sc->sc_nclks = __arraycount(jh7100_clocks);
365 for (size_t id = 0; id < sc->sc_nclks; id++) {
366 if (sc->sc_clk[id].jcc_type == JH71X0CLK_UNKNOWN)
367 continue;
368
369 sc->sc_clk[id].jcc_clk.domain = &sc->sc_clkdom;
370 clk_attach(&sc->sc_clk[id].jcc_clk);
371 }
372
373 aprint_naive("\n");
374 aprint_normal(": JH7100 (OSC0 %u Hz, OSC1 %u Hz)\n",
375 osclk_rate, oaclk_rate);
376
377 for (size_t id = 0; id < sc->sc_nclks; id++) {
378 if (sc->sc_clk[id].jcc_type == JH71X0CLK_UNKNOWN)
379 continue;
380
381 struct clk * const clk = &sc->sc_clk[id].jcc_clk;
382
383 aprint_debug_dev(self, "id %zu [%s]: %u Hz\n", id,
384 clk->name ? clk->name : "<none>", clk_get_rate(clk));
385 }
386
387 fdtbus_register_clock_controller(self, phandle, &jh7100_clkc_fdt_funcs);
388 }
389
390 CFATTACH_DECL_NEW(jh7100_clkc, sizeof(struct jh71x0_clkc_softc),
391 jh7100_clkc_match, jh7100_clkc_attach, NULL, NULL);
392