1 | // SPDX-License-Identifier: GPL-2.0 |
2 | /* |
3 | * JZ4770 SoC CGU driver |
4 | * Copyright 2018, Paul Cercueil <paul@crapouillou.net> |
5 | */ |
6 | |
7 | #include <linux/bitops.h> |
8 | #include <linux/clk-provider.h> |
9 | #include <linux/delay.h> |
10 | #include <linux/io.h> |
11 | #include <linux/of.h> |
12 | |
13 | #include <dt-bindings/clock/ingenic,jz4770-cgu.h> |
14 | |
15 | #include "cgu.h" |
16 | #include "pm.h" |
17 | |
18 | /* |
19 | * CPM registers offset address definition |
20 | */ |
21 | #define CGU_REG_CPCCR 0x00 |
22 | #define CGU_REG_LCR 0x04 |
23 | #define CGU_REG_CPPCR0 0x10 |
24 | #define CGU_REG_CLKGR0 0x20 |
25 | #define CGU_REG_OPCR 0x24 |
26 | #define CGU_REG_CLKGR1 0x28 |
27 | #define CGU_REG_CPPCR1 0x30 |
28 | #define CGU_REG_USBPCR1 0x48 |
29 | #define CGU_REG_USBCDR 0x50 |
30 | #define CGU_REG_I2SCDR 0x60 |
31 | #define CGU_REG_LPCDR 0x64 |
32 | #define CGU_REG_MSC0CDR 0x68 |
33 | #define CGU_REG_UHCCDR 0x6c |
34 | #define CGU_REG_SSICDR 0x74 |
35 | #define CGU_REG_CIMCDR 0x7c |
36 | #define CGU_REG_GPSCDR 0x80 |
37 | #define CGU_REG_PCMCDR 0x84 |
38 | #define CGU_REG_GPUCDR 0x88 |
39 | #define CGU_REG_MSC1CDR 0xA4 |
40 | #define CGU_REG_MSC2CDR 0xA8 |
41 | #define CGU_REG_BCHCDR 0xAC |
42 | |
43 | /* bits within the OPCR register */ |
44 | #define OPCR_SPENDH BIT(5) /* UHC PHY suspend */ |
45 | |
46 | /* bits within the USBPCR1 register */ |
47 | #define USBPCR1_UHC_POWER BIT(5) /* UHC PHY power down */ |
48 | |
49 | static struct ingenic_cgu *cgu; |
50 | |
51 | static int jz4770_uhc_phy_enable(struct clk_hw *hw) |
52 | { |
53 | void __iomem *reg_opcr = cgu->base + CGU_REG_OPCR; |
54 | void __iomem *reg_usbpcr1 = cgu->base + CGU_REG_USBPCR1; |
55 | |
56 | writel(readl(addr: reg_opcr) & ~OPCR_SPENDH, addr: reg_opcr); |
57 | writel(readl(addr: reg_usbpcr1) | USBPCR1_UHC_POWER, addr: reg_usbpcr1); |
58 | return 0; |
59 | } |
60 | |
61 | static void jz4770_uhc_phy_disable(struct clk_hw *hw) |
62 | { |
63 | void __iomem *reg_opcr = cgu->base + CGU_REG_OPCR; |
64 | void __iomem *reg_usbpcr1 = cgu->base + CGU_REG_USBPCR1; |
65 | |
66 | writel(readl(addr: reg_usbpcr1) & ~USBPCR1_UHC_POWER, addr: reg_usbpcr1); |
67 | writel(readl(addr: reg_opcr) | OPCR_SPENDH, addr: reg_opcr); |
68 | } |
69 | |
70 | static int jz4770_uhc_phy_is_enabled(struct clk_hw *hw) |
71 | { |
72 | void __iomem *reg_opcr = cgu->base + CGU_REG_OPCR; |
73 | void __iomem *reg_usbpcr1 = cgu->base + CGU_REG_USBPCR1; |
74 | |
75 | return !(readl(addr: reg_opcr) & OPCR_SPENDH) && |
76 | (readl(addr: reg_usbpcr1) & USBPCR1_UHC_POWER); |
77 | } |
78 | |
79 | static const struct clk_ops jz4770_uhc_phy_ops = { |
80 | .enable = jz4770_uhc_phy_enable, |
81 | .disable = jz4770_uhc_phy_disable, |
82 | .is_enabled = jz4770_uhc_phy_is_enabled, |
83 | }; |
84 | |
85 | static const s8 pll_od_encoding[8] = { |
86 | 0x0, 0x1, -1, 0x2, -1, -1, -1, 0x3, |
87 | }; |
88 | |
89 | static const u8 jz4770_cgu_cpccr_div_table[] = { |
90 | 1, 2, 3, 4, 6, 8, 12, |
91 | }; |
92 | |
93 | static const struct ingenic_cgu_clk_info jz4770_cgu_clocks[] = { |
94 | |
95 | /* External clocks */ |
96 | |
97 | [JZ4770_CLK_EXT] = { "ext" , CGU_CLK_EXT }, |
98 | [JZ4770_CLK_OSC32K] = { "osc32k" , CGU_CLK_EXT }, |
99 | |
100 | /* PLLs */ |
101 | |
102 | [JZ4770_CLK_PLL0] = { |
103 | "pll0" , CGU_CLK_PLL, |
104 | .parents = { JZ4770_CLK_EXT }, |
105 | .pll = { |
106 | .reg = CGU_REG_CPPCR0, |
107 | .rate_multiplier = 1, |
108 | .m_shift = 24, |
109 | .m_bits = 7, |
110 | .m_offset = 1, |
111 | .n_shift = 18, |
112 | .n_bits = 5, |
113 | .n_offset = 1, |
114 | .od_shift = 16, |
115 | .od_bits = 2, |
116 | .od_max = 8, |
117 | .od_encoding = pll_od_encoding, |
118 | .bypass_reg = CGU_REG_CPPCR0, |
119 | .bypass_bit = 9, |
120 | .enable_bit = 8, |
121 | .stable_bit = 10, |
122 | }, |
123 | }, |
124 | |
125 | [JZ4770_CLK_PLL1] = { |
126 | /* TODO: PLL1 can depend on PLL0 */ |
127 | "pll1" , CGU_CLK_PLL, |
128 | .parents = { JZ4770_CLK_EXT }, |
129 | .pll = { |
130 | .reg = CGU_REG_CPPCR1, |
131 | .rate_multiplier = 1, |
132 | .m_shift = 24, |
133 | .m_bits = 7, |
134 | .m_offset = 1, |
135 | .n_shift = 18, |
136 | .n_bits = 5, |
137 | .n_offset = 1, |
138 | .od_shift = 16, |
139 | .od_bits = 2, |
140 | .od_max = 8, |
141 | .od_encoding = pll_od_encoding, |
142 | .bypass_bit = -1, |
143 | .enable_bit = 7, |
144 | .stable_bit = 6, |
145 | }, |
146 | }, |
147 | |
148 | /* Main clocks */ |
149 | |
150 | [JZ4770_CLK_CCLK] = { |
151 | "cclk" , CGU_CLK_DIV, |
152 | /* |
153 | * Disabling the CPU clock or any parent clocks will hang the |
154 | * system; mark it critical. |
155 | */ |
156 | .flags = CLK_IS_CRITICAL, |
157 | .parents = { JZ4770_CLK_PLL0, }, |
158 | .div = { |
159 | CGU_REG_CPCCR, 0, 1, 4, 22, -1, -1, 0, |
160 | jz4770_cgu_cpccr_div_table, |
161 | }, |
162 | }, |
163 | [JZ4770_CLK_H0CLK] = { |
164 | "h0clk" , CGU_CLK_DIV, |
165 | .parents = { JZ4770_CLK_PLL0, }, |
166 | .div = { |
167 | CGU_REG_CPCCR, 4, 1, 4, 22, -1, -1, 0, |
168 | jz4770_cgu_cpccr_div_table, |
169 | }, |
170 | }, |
171 | [JZ4770_CLK_H1CLK] = { |
172 | "h1clk" , CGU_CLK_DIV | CGU_CLK_GATE, |
173 | .parents = { JZ4770_CLK_PLL0, }, |
174 | .div = { |
175 | CGU_REG_CPCCR, 24, 1, 4, 22, -1, -1, 0, |
176 | jz4770_cgu_cpccr_div_table, |
177 | }, |
178 | .gate = { CGU_REG_CLKGR1, 7 }, |
179 | }, |
180 | [JZ4770_CLK_H2CLK] = { |
181 | "h2clk" , CGU_CLK_DIV, |
182 | .parents = { JZ4770_CLK_PLL0, }, |
183 | .div = { |
184 | CGU_REG_CPCCR, 16, 1, 4, 22, -1, -1, 0, |
185 | jz4770_cgu_cpccr_div_table, |
186 | }, |
187 | }, |
188 | [JZ4770_CLK_C1CLK] = { |
189 | "c1clk" , CGU_CLK_DIV | CGU_CLK_GATE, |
190 | .parents = { JZ4770_CLK_PLL0, }, |
191 | .div = { |
192 | CGU_REG_CPCCR, 12, 1, 4, 22, -1, -1, 0, |
193 | jz4770_cgu_cpccr_div_table, |
194 | }, |
195 | .gate = { CGU_REG_OPCR, 31, true }, // disable CCLK stop on idle |
196 | }, |
197 | [JZ4770_CLK_PCLK] = { |
198 | "pclk" , CGU_CLK_DIV, |
199 | .parents = { JZ4770_CLK_PLL0, }, |
200 | .div = { |
201 | CGU_REG_CPCCR, 8, 1, 4, 22, -1, -1, 0, |
202 | jz4770_cgu_cpccr_div_table, |
203 | }, |
204 | }, |
205 | |
206 | /* Those divided clocks can connect to PLL0 or PLL1 */ |
207 | |
208 | [JZ4770_CLK_MMC0_MUX] = { |
209 | "mmc0_mux" , CGU_CLK_DIV | CGU_CLK_GATE | CGU_CLK_MUX, |
210 | .parents = { JZ4770_CLK_PLL0, JZ4770_CLK_PLL1, }, |
211 | .mux = { CGU_REG_MSC0CDR, 30, 1 }, |
212 | .div = { CGU_REG_MSC0CDR, 0, 1, 7, -1, -1, 31 }, |
213 | .gate = { CGU_REG_MSC0CDR, 31 }, |
214 | }, |
215 | [JZ4770_CLK_MMC1_MUX] = { |
216 | "mmc1_mux" , CGU_CLK_DIV | CGU_CLK_GATE | CGU_CLK_MUX, |
217 | .parents = { JZ4770_CLK_PLL0, JZ4770_CLK_PLL1, }, |
218 | .mux = { CGU_REG_MSC1CDR, 30, 1 }, |
219 | .div = { CGU_REG_MSC1CDR, 0, 1, 7, -1, -1, 31 }, |
220 | .gate = { CGU_REG_MSC1CDR, 31 }, |
221 | }, |
222 | [JZ4770_CLK_MMC2_MUX] = { |
223 | "mmc2_mux" , CGU_CLK_DIV | CGU_CLK_GATE | CGU_CLK_MUX, |
224 | .parents = { JZ4770_CLK_PLL0, JZ4770_CLK_PLL1, }, |
225 | .mux = { CGU_REG_MSC2CDR, 30, 1 }, |
226 | .div = { CGU_REG_MSC2CDR, 0, 1, 7, -1, -1, 31 }, |
227 | .gate = { CGU_REG_MSC2CDR, 31 }, |
228 | }, |
229 | [JZ4770_CLK_CIM] = { |
230 | "cim" , CGU_CLK_DIV | CGU_CLK_GATE | CGU_CLK_MUX, |
231 | .parents = { JZ4770_CLK_PLL0, JZ4770_CLK_PLL1, }, |
232 | .mux = { CGU_REG_CIMCDR, 31, 1 }, |
233 | .div = { CGU_REG_CIMCDR, 0, 1, 8, -1, -1, -1 }, |
234 | .gate = { CGU_REG_CLKGR0, 26 }, |
235 | }, |
236 | [JZ4770_CLK_UHC] = { |
237 | "uhc" , CGU_CLK_DIV | CGU_CLK_GATE | CGU_CLK_MUX, |
238 | .parents = { JZ4770_CLK_PLL0, JZ4770_CLK_PLL1, }, |
239 | .mux = { CGU_REG_UHCCDR, 29, 1 }, |
240 | .div = { CGU_REG_UHCCDR, 0, 1, 4, -1, -1, -1 }, |
241 | .gate = { CGU_REG_CLKGR0, 24 }, |
242 | }, |
243 | [JZ4770_CLK_GPU] = { |
244 | "gpu" , CGU_CLK_DIV | CGU_CLK_GATE | CGU_CLK_MUX, |
245 | .parents = { JZ4770_CLK_PLL0, JZ4770_CLK_PLL1, -1 }, |
246 | .mux = { CGU_REG_GPUCDR, 31, 1 }, |
247 | .div = { CGU_REG_GPUCDR, 0, 1, 3, -1, -1, -1 }, |
248 | .gate = { CGU_REG_CLKGR1, 9 }, |
249 | }, |
250 | [JZ4770_CLK_BCH] = { |
251 | "bch" , CGU_CLK_DIV | CGU_CLK_GATE | CGU_CLK_MUX, |
252 | .parents = { JZ4770_CLK_PLL0, JZ4770_CLK_PLL1, }, |
253 | .mux = { CGU_REG_BCHCDR, 31, 1 }, |
254 | .div = { CGU_REG_BCHCDR, 0, 1, 3, -1, -1, -1 }, |
255 | .gate = { CGU_REG_CLKGR0, 1 }, |
256 | }, |
257 | [JZ4770_CLK_LPCLK_MUX] = { |
258 | "lpclk" , CGU_CLK_DIV | CGU_CLK_GATE | CGU_CLK_MUX, |
259 | .parents = { JZ4770_CLK_PLL0, JZ4770_CLK_PLL1, }, |
260 | .mux = { CGU_REG_LPCDR, 29, 1 }, |
261 | .div = { CGU_REG_LPCDR, 0, 1, 11, -1, -1, -1 }, |
262 | .gate = { CGU_REG_CLKGR0, 28 }, |
263 | }, |
264 | [JZ4770_CLK_GPS] = { |
265 | "gps" , CGU_CLK_DIV | CGU_CLK_GATE | CGU_CLK_MUX, |
266 | .parents = { JZ4770_CLK_PLL0, JZ4770_CLK_PLL1, }, |
267 | .mux = { CGU_REG_GPSCDR, 31, 1 }, |
268 | .div = { CGU_REG_GPSCDR, 0, 1, 4, -1, -1, -1 }, |
269 | .gate = { CGU_REG_CLKGR0, 22 }, |
270 | }, |
271 | |
272 | /* Those divided clocks can connect to EXT, PLL0 or PLL1 */ |
273 | |
274 | [JZ4770_CLK_SSI_MUX] = { |
275 | "ssi_mux" , CGU_CLK_DIV | CGU_CLK_MUX, |
276 | .parents = { JZ4770_CLK_EXT, -1, |
277 | JZ4770_CLK_PLL0, JZ4770_CLK_PLL1 }, |
278 | .mux = { CGU_REG_SSICDR, 30, 2 }, |
279 | .div = { CGU_REG_SSICDR, 0, 1, 6, -1, -1, -1 }, |
280 | }, |
281 | [JZ4770_CLK_PCM_MUX] = { |
282 | "pcm_mux" , CGU_CLK_DIV | CGU_CLK_MUX, |
283 | .parents = { JZ4770_CLK_EXT, -1, |
284 | JZ4770_CLK_PLL0, JZ4770_CLK_PLL1 }, |
285 | .mux = { CGU_REG_PCMCDR, 30, 2 }, |
286 | .div = { CGU_REG_PCMCDR, 0, 1, 9, -1, -1, -1 }, |
287 | }, |
288 | [JZ4770_CLK_I2S] = { |
289 | "i2s" , CGU_CLK_DIV | CGU_CLK_GATE | CGU_CLK_MUX, |
290 | .parents = { JZ4770_CLK_EXT, -1, |
291 | JZ4770_CLK_PLL0, JZ4770_CLK_PLL1 }, |
292 | .mux = { CGU_REG_I2SCDR, 30, 2 }, |
293 | .div = { CGU_REG_I2SCDR, 0, 1, 9, -1, -1, -1 }, |
294 | .gate = { CGU_REG_CLKGR1, 13 }, |
295 | }, |
296 | [JZ4770_CLK_OTG] = { |
297 | "usb" , CGU_CLK_DIV | CGU_CLK_GATE | CGU_CLK_MUX, |
298 | .parents = { JZ4770_CLK_EXT, -1, |
299 | JZ4770_CLK_PLL0, JZ4770_CLK_PLL1 }, |
300 | .mux = { CGU_REG_USBCDR, 30, 2 }, |
301 | .div = { CGU_REG_USBCDR, 0, 1, 8, -1, -1, -1 }, |
302 | .gate = { CGU_REG_CLKGR0, 2 }, |
303 | }, |
304 | |
305 | /* Gate-only clocks */ |
306 | |
307 | [JZ4770_CLK_SSI0] = { |
308 | "ssi0" , CGU_CLK_GATE, |
309 | .parents = { JZ4770_CLK_SSI_MUX, }, |
310 | .gate = { CGU_REG_CLKGR0, 4 }, |
311 | }, |
312 | [JZ4770_CLK_SSI1] = { |
313 | "ssi1" , CGU_CLK_GATE, |
314 | .parents = { JZ4770_CLK_SSI_MUX, }, |
315 | .gate = { CGU_REG_CLKGR0, 19 }, |
316 | }, |
317 | [JZ4770_CLK_SSI2] = { |
318 | "ssi2" , CGU_CLK_GATE, |
319 | .parents = { JZ4770_CLK_SSI_MUX, }, |
320 | .gate = { CGU_REG_CLKGR0, 20 }, |
321 | }, |
322 | [JZ4770_CLK_PCM0] = { |
323 | "pcm0" , CGU_CLK_GATE, |
324 | .parents = { JZ4770_CLK_PCM_MUX, }, |
325 | .gate = { CGU_REG_CLKGR1, 8 }, |
326 | }, |
327 | [JZ4770_CLK_PCM1] = { |
328 | "pcm1" , CGU_CLK_GATE, |
329 | .parents = { JZ4770_CLK_PCM_MUX, }, |
330 | .gate = { CGU_REG_CLKGR1, 10 }, |
331 | }, |
332 | [JZ4770_CLK_DMA] = { |
333 | "dma" , CGU_CLK_GATE, |
334 | .parents = { JZ4770_CLK_H2CLK, }, |
335 | .gate = { CGU_REG_CLKGR0, 21 }, |
336 | }, |
337 | [JZ4770_CLK_BDMA] = { |
338 | "bdma" , CGU_CLK_GATE, |
339 | .parents = { JZ4770_CLK_H2CLK, }, |
340 | .gate = { CGU_REG_CLKGR1, 0 }, |
341 | }, |
342 | [JZ4770_CLK_I2C0] = { |
343 | "i2c0" , CGU_CLK_GATE, |
344 | .parents = { JZ4770_CLK_EXT, }, |
345 | .gate = { CGU_REG_CLKGR0, 5 }, |
346 | }, |
347 | [JZ4770_CLK_I2C1] = { |
348 | "i2c1" , CGU_CLK_GATE, |
349 | .parents = { JZ4770_CLK_EXT, }, |
350 | .gate = { CGU_REG_CLKGR0, 6 }, |
351 | }, |
352 | [JZ4770_CLK_I2C2] = { |
353 | "i2c2" , CGU_CLK_GATE, |
354 | .parents = { JZ4770_CLK_EXT, }, |
355 | .gate = { CGU_REG_CLKGR1, 15 }, |
356 | }, |
357 | [JZ4770_CLK_UART0] = { |
358 | "uart0" , CGU_CLK_GATE, |
359 | .parents = { JZ4770_CLK_EXT, }, |
360 | .gate = { CGU_REG_CLKGR0, 15 }, |
361 | }, |
362 | [JZ4770_CLK_UART1] = { |
363 | "uart1" , CGU_CLK_GATE, |
364 | .parents = { JZ4770_CLK_EXT, }, |
365 | .gate = { CGU_REG_CLKGR0, 16 }, |
366 | }, |
367 | [JZ4770_CLK_UART2] = { |
368 | "uart2" , CGU_CLK_GATE, |
369 | .parents = { JZ4770_CLK_EXT, }, |
370 | .gate = { CGU_REG_CLKGR0, 17 }, |
371 | }, |
372 | [JZ4770_CLK_UART3] = { |
373 | "uart3" , CGU_CLK_GATE, |
374 | .parents = { JZ4770_CLK_EXT, }, |
375 | .gate = { CGU_REG_CLKGR0, 18 }, |
376 | }, |
377 | [JZ4770_CLK_IPU] = { |
378 | "ipu" , CGU_CLK_GATE, |
379 | .parents = { JZ4770_CLK_H0CLK, }, |
380 | .gate = { CGU_REG_CLKGR0, 29 }, |
381 | }, |
382 | [JZ4770_CLK_ADC] = { |
383 | "adc" , CGU_CLK_GATE, |
384 | .parents = { JZ4770_CLK_EXT, }, |
385 | .gate = { CGU_REG_CLKGR0, 14 }, |
386 | }, |
387 | [JZ4770_CLK_AIC] = { |
388 | "aic" , CGU_CLK_GATE, |
389 | .parents = { JZ4770_CLK_EXT, }, |
390 | .gate = { CGU_REG_CLKGR0, 8 }, |
391 | }, |
392 | [JZ4770_CLK_AUX] = { |
393 | "aux" , CGU_CLK_GATE, |
394 | .parents = { JZ4770_CLK_C1CLK, }, |
395 | .gate = { CGU_REG_CLKGR1, 14 }, |
396 | }, |
397 | [JZ4770_CLK_VPU] = { |
398 | "vpu" , CGU_CLK_GATE, |
399 | .parents = { JZ4770_CLK_H1CLK, }, |
400 | .gate = { CGU_REG_LCR, 30, false, 150 }, |
401 | }, |
402 | [JZ4770_CLK_MMC0] = { |
403 | "mmc0" , CGU_CLK_GATE, |
404 | .parents = { JZ4770_CLK_MMC0_MUX, }, |
405 | .gate = { CGU_REG_CLKGR0, 3 }, |
406 | }, |
407 | [JZ4770_CLK_MMC1] = { |
408 | "mmc1" , CGU_CLK_GATE, |
409 | .parents = { JZ4770_CLK_MMC1_MUX, }, |
410 | .gate = { CGU_REG_CLKGR0, 11 }, |
411 | }, |
412 | [JZ4770_CLK_MMC2] = { |
413 | "mmc2" , CGU_CLK_GATE, |
414 | .parents = { JZ4770_CLK_MMC2_MUX, }, |
415 | .gate = { CGU_REG_CLKGR0, 12 }, |
416 | }, |
417 | [JZ4770_CLK_OTG_PHY] = { |
418 | "usb_phy" , CGU_CLK_GATE, |
419 | .parents = { JZ4770_CLK_OTG }, |
420 | .gate = { CGU_REG_OPCR, 7, true, 50 }, |
421 | }, |
422 | |
423 | /* Custom clocks */ |
424 | |
425 | [JZ4770_CLK_UHC_PHY] = { |
426 | "uhc_phy" , CGU_CLK_CUSTOM, |
427 | .parents = { JZ4770_CLK_UHC, -1, -1, -1 }, |
428 | .custom = { &jz4770_uhc_phy_ops }, |
429 | }, |
430 | |
431 | [JZ4770_CLK_EXT512] = { |
432 | "ext/512" , CGU_CLK_FIXDIV, |
433 | .parents = { JZ4770_CLK_EXT }, |
434 | .fixdiv = { 512 }, |
435 | }, |
436 | |
437 | [JZ4770_CLK_RTC] = { |
438 | "rtc" , CGU_CLK_MUX, |
439 | .parents = { JZ4770_CLK_EXT512, JZ4770_CLK_OSC32K, }, |
440 | .mux = { CGU_REG_OPCR, 2, 1}, |
441 | }, |
442 | }; |
443 | |
444 | static void __init jz4770_cgu_init(struct device_node *np) |
445 | { |
446 | int retval; |
447 | |
448 | cgu = ingenic_cgu_new(clock_info: jz4770_cgu_clocks, |
449 | ARRAY_SIZE(jz4770_cgu_clocks), np); |
450 | if (!cgu) { |
451 | pr_err("%s: failed to initialise CGU\n" , __func__); |
452 | return; |
453 | } |
454 | |
455 | retval = ingenic_cgu_register_clocks(cgu); |
456 | if (retval) |
457 | pr_err("%s: failed to register CGU Clocks\n" , __func__); |
458 | |
459 | ingenic_cgu_register_syscore_ops(cgu); |
460 | } |
461 | |
462 | /* We only probe via devicetree, no need for a platform driver */ |
463 | CLK_OF_DECLARE_DRIVER(jz4770_cgu, "ingenic,jz4770-cgu" , jz4770_cgu_init); |
464 | |