]>
Commit | Line | Data |
---|---|---|
29136ad5 PB |
1 | /* |
2 | * Ingenic JZ4780 SoC CGU driver | |
3 | * | |
4 | * Copyright (c) 2013-2015 Imagination Technologies | |
fb615d61 | 5 | * Author: Paul Burton <[email protected]> |
29136ad5 PB |
6 | * |
7 | * This program is free software; you can redistribute it and/or | |
8 | * modify it under the terms of the GNU General Public License as | |
9 | * published by the Free Software Foundation; either version 2 of | |
10 | * the License, or (at your option) any later version. | |
11 | * | |
12 | * This program is distributed in the hope that it will be useful, | |
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
15 | * GNU General Public License for more details. | |
16 | */ | |
17 | ||
18 | #include <linux/clk-provider.h> | |
19 | #include <linux/delay.h> | |
20 | #include <linux/of.h> | |
21 | #include <dt-bindings/clock/jz4780-cgu.h> | |
22 | #include "cgu.h" | |
23 | ||
24 | /* CGU register offsets */ | |
25 | #define CGU_REG_CLOCKCONTROL 0x00 | |
26 | #define CGU_REG_PLLCONTROL 0x0c | |
27 | #define CGU_REG_APLL 0x10 | |
28 | #define CGU_REG_MPLL 0x14 | |
29 | #define CGU_REG_EPLL 0x18 | |
30 | #define CGU_REG_VPLL 0x1c | |
31 | #define CGU_REG_CLKGR0 0x20 | |
32 | #define CGU_REG_OPCR 0x24 | |
33 | #define CGU_REG_CLKGR1 0x28 | |
34 | #define CGU_REG_DDRCDR 0x2c | |
35 | #define CGU_REG_VPUCDR 0x30 | |
36 | #define CGU_REG_USBPCR 0x3c | |
37 | #define CGU_REG_USBRDT 0x40 | |
38 | #define CGU_REG_USBVBFIL 0x44 | |
39 | #define CGU_REG_USBPCR1 0x48 | |
40 | #define CGU_REG_LP0CDR 0x54 | |
41 | #define CGU_REG_I2SCDR 0x60 | |
42 | #define CGU_REG_LP1CDR 0x64 | |
43 | #define CGU_REG_MSC0CDR 0x68 | |
44 | #define CGU_REG_UHCCDR 0x6c | |
45 | #define CGU_REG_SSICDR 0x74 | |
46 | #define CGU_REG_CIMCDR 0x7c | |
47 | #define CGU_REG_PCMCDR 0x84 | |
48 | #define CGU_REG_GPUCDR 0x88 | |
49 | #define CGU_REG_HDMICDR 0x8c | |
50 | #define CGU_REG_MSC1CDR 0xa4 | |
51 | #define CGU_REG_MSC2CDR 0xa8 | |
52 | #define CGU_REG_BCHCDR 0xac | |
53 | #define CGU_REG_CLOCKSTATUS 0xd4 | |
54 | ||
55 | /* bits within the OPCR register */ | |
56 | #define OPCR_SPENDN0 (1 << 7) | |
57 | #define OPCR_SPENDN1 (1 << 6) | |
58 | ||
59 | /* bits within the USBPCR register */ | |
60 | #define USBPCR_USB_MODE BIT(31) | |
61 | #define USBPCR_IDPULLUP_MASK (0x3 << 28) | |
62 | #define USBPCR_COMMONONN BIT(25) | |
63 | #define USBPCR_VBUSVLDEXT BIT(24) | |
64 | #define USBPCR_VBUSVLDEXTSEL BIT(23) | |
65 | #define USBPCR_POR BIT(22) | |
66 | #define USBPCR_OTG_DISABLE BIT(20) | |
67 | #define USBPCR_COMPDISTUNE_MASK (0x7 << 17) | |
68 | #define USBPCR_OTGTUNE_MASK (0x7 << 14) | |
69 | #define USBPCR_SQRXTUNE_MASK (0x7 << 11) | |
70 | #define USBPCR_TXFSLSTUNE_MASK (0xf << 7) | |
71 | #define USBPCR_TXPREEMPHTUNE BIT(6) | |
72 | #define USBPCR_TXHSXVTUNE_MASK (0x3 << 4) | |
73 | #define USBPCR_TXVREFTUNE_MASK 0xf | |
74 | ||
75 | /* bits within the USBPCR1 register */ | |
76 | #define USBPCR1_REFCLKSEL_SHIFT 26 | |
77 | #define USBPCR1_REFCLKSEL_MASK (0x3 << USBPCR1_REFCLKSEL_SHIFT) | |
78 | #define USBPCR1_REFCLKSEL_CORE (0x2 << USBPCR1_REFCLKSEL_SHIFT) | |
79 | #define USBPCR1_REFCLKDIV_SHIFT 24 | |
80 | #define USBPCR1_REFCLKDIV_MASK (0x3 << USBPCR1_REFCLKDIV_SHIFT) | |
81 | #define USBPCR1_REFCLKDIV_19_2 (0x3 << USBPCR1_REFCLKDIV_SHIFT) | |
82 | #define USBPCR1_REFCLKDIV_48 (0x2 << USBPCR1_REFCLKDIV_SHIFT) | |
83 | #define USBPCR1_REFCLKDIV_24 (0x1 << USBPCR1_REFCLKDIV_SHIFT) | |
84 | #define USBPCR1_REFCLKDIV_12 (0x0 << USBPCR1_REFCLKDIV_SHIFT) | |
85 | #define USBPCR1_USB_SEL BIT(28) | |
86 | #define USBPCR1_WORD_IF0 BIT(19) | |
87 | #define USBPCR1_WORD_IF1 BIT(18) | |
88 | ||
89 | /* bits within the USBRDT register */ | |
90 | #define USBRDT_VBFIL_LD_EN BIT(25) | |
91 | #define USBRDT_USBRDT_MASK 0x7fffff | |
92 | ||
93 | /* bits within the USBVBFIL register */ | |
94 | #define USBVBFIL_IDDIGFIL_SHIFT 16 | |
95 | #define USBVBFIL_IDDIGFIL_MASK (0xffff << USBVBFIL_IDDIGFIL_SHIFT) | |
96 | #define USBVBFIL_USBVBFIL_MASK (0xffff) | |
97 | ||
98 | static struct ingenic_cgu *cgu; | |
99 | ||
100 | static u8 jz4780_otg_phy_get_parent(struct clk_hw *hw) | |
101 | { | |
102 | /* we only use CLKCORE, revisit if that ever changes */ | |
103 | return 0; | |
104 | } | |
105 | ||
106 | static int jz4780_otg_phy_set_parent(struct clk_hw *hw, u8 idx) | |
107 | { | |
108 | unsigned long flags; | |
109 | u32 usbpcr1; | |
110 | ||
111 | if (idx > 0) | |
112 | return -EINVAL; | |
113 | ||
114 | spin_lock_irqsave(&cgu->lock, flags); | |
115 | ||
116 | usbpcr1 = readl(cgu->base + CGU_REG_USBPCR1); | |
117 | usbpcr1 &= ~USBPCR1_REFCLKSEL_MASK; | |
118 | /* we only use CLKCORE */ | |
119 | usbpcr1 |= USBPCR1_REFCLKSEL_CORE; | |
120 | writel(usbpcr1, cgu->base + CGU_REG_USBPCR1); | |
121 | ||
122 | spin_unlock_irqrestore(&cgu->lock, flags); | |
123 | return 0; | |
124 | } | |
125 | ||
126 | static unsigned long jz4780_otg_phy_recalc_rate(struct clk_hw *hw, | |
127 | unsigned long parent_rate) | |
128 | { | |
129 | u32 usbpcr1; | |
130 | unsigned refclk_div; | |
131 | ||
132 | usbpcr1 = readl(cgu->base + CGU_REG_USBPCR1); | |
133 | refclk_div = usbpcr1 & USBPCR1_REFCLKDIV_MASK; | |
134 | ||
135 | switch (refclk_div) { | |
136 | case USBPCR1_REFCLKDIV_12: | |
137 | return 12000000; | |
138 | ||
139 | case USBPCR1_REFCLKDIV_24: | |
140 | return 24000000; | |
141 | ||
142 | case USBPCR1_REFCLKDIV_48: | |
143 | return 48000000; | |
144 | ||
145 | case USBPCR1_REFCLKDIV_19_2: | |
146 | return 19200000; | |
147 | } | |
148 | ||
149 | BUG(); | |
150 | return parent_rate; | |
151 | } | |
152 | ||
153 | static long jz4780_otg_phy_round_rate(struct clk_hw *hw, unsigned long req_rate, | |
154 | unsigned long *parent_rate) | |
155 | { | |
156 | if (req_rate < 15600000) | |
157 | return 12000000; | |
158 | ||
159 | if (req_rate < 21600000) | |
160 | return 19200000; | |
161 | ||
162 | if (req_rate < 36000000) | |
163 | return 24000000; | |
164 | ||
165 | return 48000000; | |
166 | } | |
167 | ||
168 | static int jz4780_otg_phy_set_rate(struct clk_hw *hw, unsigned long req_rate, | |
169 | unsigned long parent_rate) | |
170 | { | |
171 | unsigned long flags; | |
172 | u32 usbpcr1, div_bits; | |
173 | ||
174 | switch (req_rate) { | |
175 | case 12000000: | |
176 | div_bits = USBPCR1_REFCLKDIV_12; | |
177 | break; | |
178 | ||
179 | case 19200000: | |
180 | div_bits = USBPCR1_REFCLKDIV_19_2; | |
181 | break; | |
182 | ||
183 | case 24000000: | |
184 | div_bits = USBPCR1_REFCLKDIV_24; | |
185 | break; | |
186 | ||
187 | case 48000000: | |
188 | div_bits = USBPCR1_REFCLKDIV_48; | |
189 | break; | |
190 | ||
191 | default: | |
192 | return -EINVAL; | |
193 | } | |
194 | ||
195 | spin_lock_irqsave(&cgu->lock, flags); | |
196 | ||
197 | usbpcr1 = readl(cgu->base + CGU_REG_USBPCR1); | |
198 | usbpcr1 &= ~USBPCR1_REFCLKDIV_MASK; | |
199 | usbpcr1 |= div_bits; | |
200 | writel(usbpcr1, cgu->base + CGU_REG_USBPCR1); | |
201 | ||
202 | spin_unlock_irqrestore(&cgu->lock, flags); | |
203 | return 0; | |
204 | } | |
205 | ||
ee1f9df2 | 206 | static const struct clk_ops jz4780_otg_phy_ops = { |
29136ad5 PB |
207 | .get_parent = jz4780_otg_phy_get_parent, |
208 | .set_parent = jz4780_otg_phy_set_parent, | |
209 | ||
210 | .recalc_rate = jz4780_otg_phy_recalc_rate, | |
211 | .round_rate = jz4780_otg_phy_round_rate, | |
212 | .set_rate = jz4780_otg_phy_set_rate, | |
213 | }; | |
214 | ||
215 | static const s8 pll_od_encoding[16] = { | |
216 | 0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, | |
217 | 0x8, 0x9, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf, | |
218 | }; | |
219 | ||
220 | static const struct ingenic_cgu_clk_info jz4780_cgu_clocks[] = { | |
221 | ||
222 | /* External clocks */ | |
223 | ||
224 | [JZ4780_CLK_EXCLK] = { "ext", CGU_CLK_EXT }, | |
225 | [JZ4780_CLK_RTCLK] = { "rtc", CGU_CLK_EXT }, | |
226 | ||
227 | /* PLLs */ | |
228 | ||
229 | #define DEF_PLL(name) { \ | |
230 | .reg = CGU_REG_ ## name, \ | |
231 | .m_shift = 19, \ | |
232 | .m_bits = 13, \ | |
233 | .m_offset = 1, \ | |
234 | .n_shift = 13, \ | |
235 | .n_bits = 6, \ | |
236 | .n_offset = 1, \ | |
237 | .od_shift = 9, \ | |
238 | .od_bits = 4, \ | |
239 | .od_max = 16, \ | |
240 | .od_encoding = pll_od_encoding, \ | |
241 | .stable_bit = 6, \ | |
242 | .bypass_bit = 1, \ | |
243 | .enable_bit = 0, \ | |
244 | } | |
245 | ||
246 | [JZ4780_CLK_APLL] = { | |
247 | "apll", CGU_CLK_PLL, | |
248 | .parents = { JZ4780_CLK_EXCLK, -1, -1, -1 }, | |
249 | .pll = DEF_PLL(APLL), | |
250 | }, | |
251 | ||
252 | [JZ4780_CLK_MPLL] = { | |
253 | "mpll", CGU_CLK_PLL, | |
254 | .parents = { JZ4780_CLK_EXCLK, -1, -1, -1 }, | |
255 | .pll = DEF_PLL(MPLL), | |
256 | }, | |
257 | ||
258 | [JZ4780_CLK_EPLL] = { | |
259 | "epll", CGU_CLK_PLL, | |
260 | .parents = { JZ4780_CLK_EXCLK, -1, -1, -1 }, | |
261 | .pll = DEF_PLL(EPLL), | |
262 | }, | |
263 | ||
264 | [JZ4780_CLK_VPLL] = { | |
265 | "vpll", CGU_CLK_PLL, | |
266 | .parents = { JZ4780_CLK_EXCLK, -1, -1, -1 }, | |
267 | .pll = DEF_PLL(VPLL), | |
268 | }, | |
269 | ||
270 | #undef DEF_PLL | |
271 | ||
272 | /* Custom (SoC-specific) OTG PHY */ | |
273 | ||
274 | [JZ4780_CLK_OTGPHY] = { | |
275 | "otg_phy", CGU_CLK_CUSTOM, | |
276 | .parents = { -1, -1, JZ4780_CLK_EXCLK, -1 }, | |
277 | .custom = { &jz4780_otg_phy_ops }, | |
278 | }, | |
279 | ||
280 | /* Muxes & dividers */ | |
281 | ||
282 | [JZ4780_CLK_SCLKA] = { | |
283 | "sclk_a", CGU_CLK_MUX, | |
284 | .parents = { -1, JZ4780_CLK_APLL, JZ4780_CLK_EXCLK, | |
285 | JZ4780_CLK_RTCLK }, | |
286 | .mux = { CGU_REG_CLOCKCONTROL, 30, 2 }, | |
287 | }, | |
288 | ||
289 | [JZ4780_CLK_CPUMUX] = { | |
290 | "cpumux", CGU_CLK_MUX, | |
291 | .parents = { -1, JZ4780_CLK_SCLKA, JZ4780_CLK_MPLL, | |
292 | JZ4780_CLK_EPLL }, | |
293 | .mux = { CGU_REG_CLOCKCONTROL, 28, 2 }, | |
294 | }, | |
295 | ||
296 | [JZ4780_CLK_CPU] = { | |
297 | "cpu", CGU_CLK_DIV, | |
298 | .parents = { JZ4780_CLK_CPUMUX, -1, -1, -1 }, | |
4afe2d1a | 299 | .div = { CGU_REG_CLOCKCONTROL, 0, 1, 4, 22, -1, -1 }, |
29136ad5 PB |
300 | }, |
301 | ||
302 | [JZ4780_CLK_L2CACHE] = { | |
303 | "l2cache", CGU_CLK_DIV, | |
304 | .parents = { JZ4780_CLK_CPUMUX, -1, -1, -1 }, | |
4afe2d1a | 305 | .div = { CGU_REG_CLOCKCONTROL, 4, 1, 4, -1, -1, -1 }, |
29136ad5 PB |
306 | }, |
307 | ||
308 | [JZ4780_CLK_AHB0] = { | |
309 | "ahb0", CGU_CLK_MUX | CGU_CLK_DIV, | |
310 | .parents = { -1, JZ4780_CLK_SCLKA, JZ4780_CLK_MPLL, | |
311 | JZ4780_CLK_EPLL }, | |
312 | .mux = { CGU_REG_CLOCKCONTROL, 26, 2 }, | |
4afe2d1a | 313 | .div = { CGU_REG_CLOCKCONTROL, 8, 1, 4, 21, -1, -1 }, |
29136ad5 PB |
314 | }, |
315 | ||
316 | [JZ4780_CLK_AHB2PMUX] = { | |
317 | "ahb2_apb_mux", CGU_CLK_MUX, | |
318 | .parents = { -1, JZ4780_CLK_SCLKA, JZ4780_CLK_MPLL, | |
319 | JZ4780_CLK_RTCLK }, | |
320 | .mux = { CGU_REG_CLOCKCONTROL, 24, 2 }, | |
321 | }, | |
322 | ||
323 | [JZ4780_CLK_AHB2] = { | |
324 | "ahb2", CGU_CLK_DIV, | |
325 | .parents = { JZ4780_CLK_AHB2PMUX, -1, -1, -1 }, | |
4afe2d1a | 326 | .div = { CGU_REG_CLOCKCONTROL, 12, 1, 4, 20, -1, -1 }, |
29136ad5 PB |
327 | }, |
328 | ||
329 | [JZ4780_CLK_PCLK] = { | |
330 | "pclk", CGU_CLK_DIV, | |
331 | .parents = { JZ4780_CLK_AHB2PMUX, -1, -1, -1 }, | |
4afe2d1a | 332 | .div = { CGU_REG_CLOCKCONTROL, 16, 1, 4, 20, -1, -1 }, |
29136ad5 PB |
333 | }, |
334 | ||
335 | [JZ4780_CLK_DDR] = { | |
336 | "ddr", CGU_CLK_MUX | CGU_CLK_DIV, | |
337 | .parents = { -1, JZ4780_CLK_SCLKA, JZ4780_CLK_MPLL, -1 }, | |
338 | .mux = { CGU_REG_DDRCDR, 30, 2 }, | |
4afe2d1a | 339 | .div = { CGU_REG_DDRCDR, 0, 1, 4, 29, 28, 27 }, |
29136ad5 PB |
340 | }, |
341 | ||
342 | [JZ4780_CLK_VPU] = { | |
343 | "vpu", CGU_CLK_MUX | CGU_CLK_DIV | CGU_CLK_GATE, | |
344 | .parents = { JZ4780_CLK_SCLKA, JZ4780_CLK_MPLL, | |
345 | JZ4780_CLK_EPLL, -1 }, | |
346 | .mux = { CGU_REG_VPUCDR, 30, 2 }, | |
4afe2d1a | 347 | .div = { CGU_REG_VPUCDR, 0, 1, 4, 29, 28, 27 }, |
29136ad5 PB |
348 | .gate = { CGU_REG_CLKGR1, 2 }, |
349 | }, | |
350 | ||
351 | [JZ4780_CLK_I2SPLL] = { | |
352 | "i2s_pll", CGU_CLK_MUX | CGU_CLK_DIV, | |
353 | .parents = { JZ4780_CLK_SCLKA, JZ4780_CLK_EPLL, -1, -1 }, | |
354 | .mux = { CGU_REG_I2SCDR, 30, 1 }, | |
4afe2d1a | 355 | .div = { CGU_REG_I2SCDR, 0, 1, 8, 29, 28, 27 }, |
29136ad5 PB |
356 | }, |
357 | ||
358 | [JZ4780_CLK_I2S] = { | |
359 | "i2s", CGU_CLK_MUX, | |
360 | .parents = { JZ4780_CLK_EXCLK, JZ4780_CLK_I2SPLL, -1, -1 }, | |
361 | .mux = { CGU_REG_I2SCDR, 31, 1 }, | |
362 | }, | |
363 | ||
364 | [JZ4780_CLK_LCD0PIXCLK] = { | |
365 | "lcd0pixclk", CGU_CLK_MUX | CGU_CLK_DIV, | |
366 | .parents = { JZ4780_CLK_SCLKA, JZ4780_CLK_MPLL, | |
367 | JZ4780_CLK_VPLL, -1 }, | |
368 | .mux = { CGU_REG_LP0CDR, 30, 2 }, | |
4afe2d1a | 369 | .div = { CGU_REG_LP0CDR, 0, 1, 8, 28, 27, 26 }, |
29136ad5 PB |
370 | }, |
371 | ||
372 | [JZ4780_CLK_LCD1PIXCLK] = { | |
373 | "lcd1pixclk", CGU_CLK_MUX | CGU_CLK_DIV, | |
374 | .parents = { JZ4780_CLK_SCLKA, JZ4780_CLK_MPLL, | |
375 | JZ4780_CLK_VPLL, -1 }, | |
376 | .mux = { CGU_REG_LP1CDR, 30, 2 }, | |
4afe2d1a | 377 | .div = { CGU_REG_LP1CDR, 0, 1, 8, 28, 27, 26 }, |
29136ad5 PB |
378 | }, |
379 | ||
380 | [JZ4780_CLK_MSCMUX] = { | |
381 | "msc_mux", CGU_CLK_MUX, | |
382 | .parents = { -1, JZ4780_CLK_SCLKA, JZ4780_CLK_MPLL, -1 }, | |
383 | .mux = { CGU_REG_MSC0CDR, 30, 2 }, | |
384 | }, | |
385 | ||
386 | [JZ4780_CLK_MSC0] = { | |
387 | "msc0", CGU_CLK_DIV | CGU_CLK_GATE, | |
388 | .parents = { JZ4780_CLK_MSCMUX, -1, -1, -1 }, | |
4afe2d1a | 389 | .div = { CGU_REG_MSC0CDR, 0, 2, 8, 29, 28, 27 }, |
29136ad5 PB |
390 | .gate = { CGU_REG_CLKGR0, 3 }, |
391 | }, | |
392 | ||
393 | [JZ4780_CLK_MSC1] = { | |
394 | "msc1", CGU_CLK_DIV | CGU_CLK_GATE, | |
395 | .parents = { JZ4780_CLK_MSCMUX, -1, -1, -1 }, | |
4afe2d1a | 396 | .div = { CGU_REG_MSC1CDR, 0, 2, 8, 29, 28, 27 }, |
29136ad5 PB |
397 | .gate = { CGU_REG_CLKGR0, 11 }, |
398 | }, | |
399 | ||
400 | [JZ4780_CLK_MSC2] = { | |
401 | "msc2", CGU_CLK_DIV | CGU_CLK_GATE, | |
402 | .parents = { JZ4780_CLK_MSCMUX, -1, -1, -1 }, | |
4afe2d1a | 403 | .div = { CGU_REG_MSC2CDR, 0, 2, 8, 29, 28, 27 }, |
29136ad5 PB |
404 | .gate = { CGU_REG_CLKGR0, 12 }, |
405 | }, | |
406 | ||
407 | [JZ4780_CLK_UHC] = { | |
408 | "uhc", CGU_CLK_MUX | CGU_CLK_DIV | CGU_CLK_GATE, | |
409 | .parents = { JZ4780_CLK_SCLKA, JZ4780_CLK_MPLL, | |
410 | JZ4780_CLK_EPLL, JZ4780_CLK_OTGPHY }, | |
411 | .mux = { CGU_REG_UHCCDR, 30, 2 }, | |
4afe2d1a | 412 | .div = { CGU_REG_UHCCDR, 0, 1, 8, 29, 28, 27 }, |
29136ad5 PB |
413 | .gate = { CGU_REG_CLKGR0, 24 }, |
414 | }, | |
415 | ||
416 | [JZ4780_CLK_SSIPLL] = { | |
417 | "ssi_pll", CGU_CLK_MUX | CGU_CLK_DIV, | |
418 | .parents = { JZ4780_CLK_SCLKA, JZ4780_CLK_MPLL, -1, -1 }, | |
419 | .mux = { CGU_REG_SSICDR, 30, 1 }, | |
4afe2d1a | 420 | .div = { CGU_REG_SSICDR, 0, 1, 8, 29, 28, 27 }, |
29136ad5 PB |
421 | }, |
422 | ||
423 | [JZ4780_CLK_SSI] = { | |
424 | "ssi", CGU_CLK_MUX, | |
425 | .parents = { JZ4780_CLK_EXCLK, JZ4780_CLK_SSIPLL, -1, -1 }, | |
426 | .mux = { CGU_REG_SSICDR, 31, 1 }, | |
427 | }, | |
428 | ||
429 | [JZ4780_CLK_CIMMCLK] = { | |
430 | "cim_mclk", CGU_CLK_MUX | CGU_CLK_DIV, | |
431 | .parents = { JZ4780_CLK_SCLKA, JZ4780_CLK_MPLL, -1, -1 }, | |
432 | .mux = { CGU_REG_CIMCDR, 31, 1 }, | |
4afe2d1a | 433 | .div = { CGU_REG_CIMCDR, 0, 1, 8, 30, 29, 28 }, |
29136ad5 PB |
434 | }, |
435 | ||
436 | [JZ4780_CLK_PCMPLL] = { | |
437 | "pcm_pll", CGU_CLK_MUX | CGU_CLK_DIV, | |
438 | .parents = { JZ4780_CLK_SCLKA, JZ4780_CLK_MPLL, | |
439 | JZ4780_CLK_EPLL, JZ4780_CLK_VPLL }, | |
440 | .mux = { CGU_REG_PCMCDR, 29, 2 }, | |
4afe2d1a | 441 | .div = { CGU_REG_PCMCDR, 0, 1, 8, 28, 27, 26 }, |
29136ad5 PB |
442 | }, |
443 | ||
444 | [JZ4780_CLK_PCM] = { | |
445 | "pcm", CGU_CLK_MUX | CGU_CLK_GATE, | |
446 | .parents = { JZ4780_CLK_EXCLK, JZ4780_CLK_PCMPLL, -1, -1 }, | |
447 | .mux = { CGU_REG_PCMCDR, 31, 1 }, | |
448 | .gate = { CGU_REG_CLKGR1, 3 }, | |
449 | }, | |
450 | ||
451 | [JZ4780_CLK_GPU] = { | |
452 | "gpu", CGU_CLK_MUX | CGU_CLK_DIV | CGU_CLK_GATE, | |
453 | .parents = { -1, JZ4780_CLK_SCLKA, JZ4780_CLK_MPLL, | |
454 | JZ4780_CLK_EPLL }, | |
455 | .mux = { CGU_REG_GPUCDR, 30, 2 }, | |
4afe2d1a | 456 | .div = { CGU_REG_GPUCDR, 0, 1, 4, 29, 28, 27 }, |
29136ad5 PB |
457 | .gate = { CGU_REG_CLKGR1, 4 }, |
458 | }, | |
459 | ||
460 | [JZ4780_CLK_HDMI] = { | |
461 | "hdmi", CGU_CLK_MUX | CGU_CLK_DIV | CGU_CLK_GATE, | |
462 | .parents = { JZ4780_CLK_SCLKA, JZ4780_CLK_MPLL, | |
463 | JZ4780_CLK_VPLL, -1 }, | |
464 | .mux = { CGU_REG_HDMICDR, 30, 2 }, | |
4afe2d1a | 465 | .div = { CGU_REG_HDMICDR, 0, 1, 8, 29, 28, 26 }, |
29136ad5 PB |
466 | .gate = { CGU_REG_CLKGR1, 9 }, |
467 | }, | |
468 | ||
469 | [JZ4780_CLK_BCH] = { | |
470 | "bch", CGU_CLK_MUX | CGU_CLK_DIV | CGU_CLK_GATE, | |
471 | .parents = { -1, JZ4780_CLK_SCLKA, JZ4780_CLK_MPLL, | |
472 | JZ4780_CLK_EPLL }, | |
473 | .mux = { CGU_REG_BCHCDR, 30, 2 }, | |
4afe2d1a | 474 | .div = { CGU_REG_BCHCDR, 0, 1, 4, 29, 28, 27 }, |
29136ad5 PB |
475 | .gate = { CGU_REG_CLKGR0, 1 }, |
476 | }, | |
477 | ||
478 | /* Gate-only clocks */ | |
479 | ||
480 | [JZ4780_CLK_NEMC] = { | |
481 | "nemc", CGU_CLK_GATE, | |
482 | .parents = { JZ4780_CLK_AHB2, -1, -1, -1 }, | |
483 | .gate = { CGU_REG_CLKGR0, 0 }, | |
484 | }, | |
485 | ||
486 | [JZ4780_CLK_OTG0] = { | |
487 | "otg0", CGU_CLK_GATE, | |
488 | .parents = { JZ4780_CLK_EXCLK, -1, -1, -1 }, | |
489 | .gate = { CGU_REG_CLKGR0, 2 }, | |
490 | }, | |
491 | ||
492 | [JZ4780_CLK_SSI0] = { | |
493 | "ssi0", CGU_CLK_GATE, | |
494 | .parents = { JZ4780_CLK_SSI, -1, -1, -1 }, | |
495 | .gate = { CGU_REG_CLKGR0, 4 }, | |
496 | }, | |
497 | ||
498 | [JZ4780_CLK_SMB0] = { | |
499 | "smb0", CGU_CLK_GATE, | |
500 | .parents = { JZ4780_CLK_PCLK, -1, -1, -1 }, | |
501 | .gate = { CGU_REG_CLKGR0, 5 }, | |
502 | }, | |
503 | ||
504 | [JZ4780_CLK_SMB1] = { | |
505 | "smb1", CGU_CLK_GATE, | |
506 | .parents = { JZ4780_CLK_PCLK, -1, -1, -1 }, | |
507 | .gate = { CGU_REG_CLKGR0, 6 }, | |
508 | }, | |
509 | ||
510 | [JZ4780_CLK_SCC] = { | |
511 | "scc", CGU_CLK_GATE, | |
512 | .parents = { JZ4780_CLK_EXCLK, -1, -1, -1 }, | |
513 | .gate = { CGU_REG_CLKGR0, 7 }, | |
514 | }, | |
515 | ||
516 | [JZ4780_CLK_AIC] = { | |
517 | "aic", CGU_CLK_GATE, | |
518 | .parents = { JZ4780_CLK_EXCLK, -1, -1, -1 }, | |
519 | .gate = { CGU_REG_CLKGR0, 8 }, | |
520 | }, | |
521 | ||
522 | [JZ4780_CLK_TSSI0] = { | |
523 | "tssi0", CGU_CLK_GATE, | |
524 | .parents = { JZ4780_CLK_EXCLK, -1, -1, -1 }, | |
525 | .gate = { CGU_REG_CLKGR0, 9 }, | |
526 | }, | |
527 | ||
528 | [JZ4780_CLK_OWI] = { | |
529 | "owi", CGU_CLK_GATE, | |
530 | .parents = { JZ4780_CLK_EXCLK, -1, -1, -1 }, | |
531 | .gate = { CGU_REG_CLKGR0, 10 }, | |
532 | }, | |
533 | ||
534 | [JZ4780_CLK_KBC] = { | |
535 | "kbc", CGU_CLK_GATE, | |
536 | .parents = { JZ4780_CLK_EXCLK, -1, -1, -1 }, | |
537 | .gate = { CGU_REG_CLKGR0, 13 }, | |
538 | }, | |
539 | ||
540 | [JZ4780_CLK_SADC] = { | |
541 | "sadc", CGU_CLK_GATE, | |
542 | .parents = { JZ4780_CLK_EXCLK, -1, -1, -1 }, | |
543 | .gate = { CGU_REG_CLKGR0, 14 }, | |
544 | }, | |
545 | ||
546 | [JZ4780_CLK_UART0] = { | |
547 | "uart0", CGU_CLK_GATE, | |
548 | .parents = { JZ4780_CLK_EXCLK, -1, -1, -1 }, | |
549 | .gate = { CGU_REG_CLKGR0, 15 }, | |
550 | }, | |
551 | ||
552 | [JZ4780_CLK_UART1] = { | |
553 | "uart1", CGU_CLK_GATE, | |
554 | .parents = { JZ4780_CLK_EXCLK, -1, -1, -1 }, | |
555 | .gate = { CGU_REG_CLKGR0, 16 }, | |
556 | }, | |
557 | ||
558 | [JZ4780_CLK_UART2] = { | |
559 | "uart2", CGU_CLK_GATE, | |
560 | .parents = { JZ4780_CLK_EXCLK, -1, -1, -1 }, | |
561 | .gate = { CGU_REG_CLKGR0, 17 }, | |
562 | }, | |
563 | ||
564 | [JZ4780_CLK_UART3] = { | |
565 | "uart3", CGU_CLK_GATE, | |
566 | .parents = { JZ4780_CLK_EXCLK, -1, -1, -1 }, | |
567 | .gate = { CGU_REG_CLKGR0, 18 }, | |
568 | }, | |
569 | ||
570 | [JZ4780_CLK_SSI1] = { | |
571 | "ssi1", CGU_CLK_GATE, | |
572 | .parents = { JZ4780_CLK_SSI, -1, -1, -1 }, | |
573 | .gate = { CGU_REG_CLKGR0, 19 }, | |
574 | }, | |
575 | ||
576 | [JZ4780_CLK_SSI2] = { | |
577 | "ssi2", CGU_CLK_GATE, | |
578 | .parents = { JZ4780_CLK_SSI, -1, -1, -1 }, | |
579 | .gate = { CGU_REG_CLKGR0, 20 }, | |
580 | }, | |
581 | ||
582 | [JZ4780_CLK_PDMA] = { | |
583 | "pdma", CGU_CLK_GATE, | |
584 | .parents = { JZ4780_CLK_EXCLK, -1, -1, -1 }, | |
585 | .gate = { CGU_REG_CLKGR0, 21 }, | |
586 | }, | |
587 | ||
588 | [JZ4780_CLK_GPS] = { | |
589 | "gps", CGU_CLK_GATE, | |
590 | .parents = { JZ4780_CLK_EXCLK, -1, -1, -1 }, | |
591 | .gate = { CGU_REG_CLKGR0, 22 }, | |
592 | }, | |
593 | ||
594 | [JZ4780_CLK_MAC] = { | |
595 | "mac", CGU_CLK_GATE, | |
596 | .parents = { JZ4780_CLK_EXCLK, -1, -1, -1 }, | |
597 | .gate = { CGU_REG_CLKGR0, 23 }, | |
598 | }, | |
599 | ||
600 | [JZ4780_CLK_SMB2] = { | |
601 | "smb2", CGU_CLK_GATE, | |
602 | .parents = { JZ4780_CLK_PCLK, -1, -1, -1 }, | |
603 | .gate = { CGU_REG_CLKGR0, 24 }, | |
604 | }, | |
605 | ||
606 | [JZ4780_CLK_CIM] = { | |
607 | "cim", CGU_CLK_GATE, | |
608 | .parents = { JZ4780_CLK_EXCLK, -1, -1, -1 }, | |
609 | .gate = { CGU_REG_CLKGR0, 26 }, | |
610 | }, | |
611 | ||
612 | [JZ4780_CLK_LCD] = { | |
613 | "lcd", CGU_CLK_GATE, | |
614 | .parents = { JZ4780_CLK_EXCLK, -1, -1, -1 }, | |
615 | .gate = { CGU_REG_CLKGR0, 28 }, | |
616 | }, | |
617 | ||
618 | [JZ4780_CLK_TVE] = { | |
619 | "tve", CGU_CLK_GATE, | |
620 | .parents = { JZ4780_CLK_LCD, -1, -1, -1 }, | |
621 | .gate = { CGU_REG_CLKGR0, 27 }, | |
622 | }, | |
623 | ||
624 | [JZ4780_CLK_IPU] = { | |
625 | "ipu", CGU_CLK_GATE, | |
626 | .parents = { JZ4780_CLK_EXCLK, -1, -1, -1 }, | |
627 | .gate = { CGU_REG_CLKGR0, 29 }, | |
628 | }, | |
629 | ||
630 | [JZ4780_CLK_DDR0] = { | |
631 | "ddr0", CGU_CLK_GATE, | |
632 | .parents = { JZ4780_CLK_DDR, -1, -1, -1 }, | |
633 | .gate = { CGU_REG_CLKGR0, 30 }, | |
634 | }, | |
635 | ||
636 | [JZ4780_CLK_DDR1] = { | |
637 | "ddr1", CGU_CLK_GATE, | |
638 | .parents = { JZ4780_CLK_DDR, -1, -1, -1 }, | |
639 | .gate = { CGU_REG_CLKGR0, 31 }, | |
640 | }, | |
641 | ||
642 | [JZ4780_CLK_SMB3] = { | |
643 | "smb3", CGU_CLK_GATE, | |
644 | .parents = { JZ4780_CLK_PCLK, -1, -1, -1 }, | |
645 | .gate = { CGU_REG_CLKGR1, 0 }, | |
646 | }, | |
647 | ||
648 | [JZ4780_CLK_TSSI1] = { | |
649 | "tssi1", CGU_CLK_GATE, | |
650 | .parents = { JZ4780_CLK_EXCLK, -1, -1, -1 }, | |
651 | .gate = { CGU_REG_CLKGR1, 1 }, | |
652 | }, | |
653 | ||
654 | [JZ4780_CLK_COMPRESS] = { | |
655 | "compress", CGU_CLK_GATE, | |
656 | .parents = { JZ4780_CLK_EXCLK, -1, -1, -1 }, | |
657 | .gate = { CGU_REG_CLKGR1, 5 }, | |
658 | }, | |
659 | ||
660 | [JZ4780_CLK_AIC1] = { | |
661 | "aic1", CGU_CLK_GATE, | |
662 | .parents = { JZ4780_CLK_EXCLK, -1, -1, -1 }, | |
663 | .gate = { CGU_REG_CLKGR1, 6 }, | |
664 | }, | |
665 | ||
666 | [JZ4780_CLK_GPVLC] = { | |
667 | "gpvlc", CGU_CLK_GATE, | |
668 | .parents = { JZ4780_CLK_EXCLK, -1, -1, -1 }, | |
669 | .gate = { CGU_REG_CLKGR1, 7 }, | |
670 | }, | |
671 | ||
672 | [JZ4780_CLK_OTG1] = { | |
673 | "otg1", CGU_CLK_GATE, | |
674 | .parents = { JZ4780_CLK_EXCLK, -1, -1, -1 }, | |
675 | .gate = { CGU_REG_CLKGR1, 8 }, | |
676 | }, | |
677 | ||
678 | [JZ4780_CLK_UART4] = { | |
679 | "uart4", CGU_CLK_GATE, | |
680 | .parents = { JZ4780_CLK_EXCLK, -1, -1, -1 }, | |
681 | .gate = { CGU_REG_CLKGR1, 10 }, | |
682 | }, | |
683 | ||
684 | [JZ4780_CLK_AHBMON] = { | |
685 | "ahb_mon", CGU_CLK_GATE, | |
686 | .parents = { JZ4780_CLK_EXCLK, -1, -1, -1 }, | |
687 | .gate = { CGU_REG_CLKGR1, 11 }, | |
688 | }, | |
689 | ||
690 | [JZ4780_CLK_SMB4] = { | |
691 | "smb4", CGU_CLK_GATE, | |
692 | .parents = { JZ4780_CLK_PCLK, -1, -1, -1 }, | |
693 | .gate = { CGU_REG_CLKGR1, 12 }, | |
694 | }, | |
695 | ||
696 | [JZ4780_CLK_DES] = { | |
697 | "des", CGU_CLK_GATE, | |
698 | .parents = { JZ4780_CLK_EXCLK, -1, -1, -1 }, | |
699 | .gate = { CGU_REG_CLKGR1, 13 }, | |
700 | }, | |
701 | ||
702 | [JZ4780_CLK_X2D] = { | |
703 | "x2d", CGU_CLK_GATE, | |
704 | .parents = { JZ4780_CLK_EXCLK, -1, -1, -1 }, | |
705 | .gate = { CGU_REG_CLKGR1, 14 }, | |
706 | }, | |
707 | ||
708 | [JZ4780_CLK_CORE1] = { | |
709 | "core1", CGU_CLK_GATE, | |
710 | .parents = { JZ4780_CLK_CPU, -1, -1, -1 }, | |
711 | .gate = { CGU_REG_CLKGR1, 15 }, | |
712 | }, | |
713 | ||
714 | }; | |
715 | ||
716 | static void __init jz4780_cgu_init(struct device_node *np) | |
717 | { | |
718 | int retval; | |
719 | ||
720 | cgu = ingenic_cgu_new(jz4780_cgu_clocks, | |
721 | ARRAY_SIZE(jz4780_cgu_clocks), np); | |
722 | if (!cgu) { | |
723 | pr_err("%s: failed to initialise CGU\n", __func__); | |
724 | return; | |
725 | } | |
726 | ||
727 | retval = ingenic_cgu_register_clocks(cgu); | |
728 | if (retval) { | |
729 | pr_err("%s: failed to register CGU Clocks\n", __func__); | |
730 | return; | |
731 | } | |
732 | } | |
733 | CLK_OF_DECLARE(jz4780_cgu, "ingenic,jz4780-cgu", jz4780_cgu_init); |