1 // SPDX-License-Identifier: GPL-2.0
3 * Ingenic JZ4755 SoC CGU driver
4 * Heavily based on JZ4725b CGU driver
6 * Copyright (C) 2022 Siarhei Volkau
7 * Author: Siarhei Volkau <lis8215@gmail.com>
10 #include <linux/clk-provider.h>
11 #include <linux/delay.h>
14 #include <dt-bindings/clock/ingenic,jz4755-cgu.h>
19 /* CGU register offsets */
20 #define CGU_REG_CPCCR 0x00
21 #define CGU_REG_CPPCR 0x10
22 #define CGU_REG_CLKGR 0x20
23 #define CGU_REG_OPCR 0x24
24 #define CGU_REG_I2SCDR 0x60
25 #define CGU_REG_LPCDR 0x64
26 #define CGU_REG_MSCCDR 0x68
27 #define CGU_REG_SSICDR 0x74
28 #define CGU_REG_CIMCDR 0x7C
30 static struct ingenic_cgu
*cgu
;
32 static const s8 pll_od_encoding
[4] = {
36 static const u8 jz4755_cgu_cpccr_div_table
[] = {
40 static const u8 jz4755_cgu_pll_half_div_table
[] = {
44 static const struct ingenic_cgu_clk_info jz4755_cgu_clocks
[] = {
48 [JZ4755_CLK_EXT
] = { "ext", CGU_CLK_EXT
},
49 [JZ4755_CLK_OSC32K
] = { "osc32k", CGU_CLK_EXT
},
53 .parents
= { JZ4755_CLK_EXT
, },
66 .od_encoding
= pll_od_encoding
,
68 .bypass_reg
= CGU_REG_CPPCR
,
74 /* Muxes & dividers */
76 [JZ4755_CLK_PLL_HALF
] = {
77 "pll half", CGU_CLK_DIV
,
78 .parents
= { JZ4755_CLK_PLL
, },
80 CGU_REG_CPCCR
, 21, 1, 1, -1, -1, -1, 0,
81 jz4755_cgu_pll_half_div_table
,
85 [JZ4755_CLK_EXT_HALF
] = {
86 "ext half", CGU_CLK_DIV
,
87 .parents
= { JZ4755_CLK_EXT
, },
89 CGU_REG_CPCCR
, 30, 1, 1, -1, -1, -1, 0,
96 .parents
= { JZ4755_CLK_PLL
, },
98 CGU_REG_CPCCR
, 0, 1, 4, 22, -1, -1, 0,
99 jz4755_cgu_cpccr_div_table
,
103 [JZ4755_CLK_H0CLK
] = {
105 .parents
= { JZ4755_CLK_PLL
, },
107 CGU_REG_CPCCR
, 4, 1, 4, 22, -1, -1, 0,
108 jz4755_cgu_cpccr_div_table
,
112 [JZ4755_CLK_PCLK
] = {
114 .parents
= { JZ4755_CLK_PLL
, },
116 CGU_REG_CPCCR
, 8, 1, 4, 22, -1, -1, 0,
117 jz4755_cgu_cpccr_div_table
,
121 [JZ4755_CLK_MCLK
] = {
123 .parents
= { JZ4755_CLK_PLL
, },
125 CGU_REG_CPCCR
, 12, 1, 4, 22, -1, -1, 0,
126 jz4755_cgu_cpccr_div_table
,
130 [JZ4755_CLK_H1CLK
] = {
131 "h1clk", CGU_CLK_DIV
,
132 .parents
= { JZ4755_CLK_PLL
, },
134 CGU_REG_CPCCR
, 16, 1, 4, 22, -1, -1, 0,
135 jz4755_cgu_cpccr_div_table
,
140 "udc", CGU_CLK_MUX
| CGU_CLK_DIV
| CGU_CLK_GATE
,
141 .parents
= { JZ4755_CLK_EXT_HALF
, JZ4755_CLK_PLL_HALF
, },
142 .mux
= { CGU_REG_CPCCR
, 29, 1 },
143 .div
= { CGU_REG_CPCCR
, 23, 1, 6, -1, -1, -1 },
144 .gate
= { CGU_REG_CLKGR
, 10 },
148 "lcd", CGU_CLK_DIV
| CGU_CLK_GATE
,
149 .parents
= { JZ4755_CLK_PLL_HALF
, },
150 .div
= { CGU_REG_LPCDR
, 0, 1, 11, -1, -1, -1 },
151 .gate
= { CGU_REG_CLKGR
, 9 },
156 .parents
= { JZ4755_CLK_PLL_HALF
, },
157 .div
= { CGU_REG_MSCCDR
, 0, 1, 5, -1, -1, -1 },
161 "i2s", CGU_CLK_MUX
| CGU_CLK_DIV
,
162 .parents
= { JZ4755_CLK_EXT_HALF
, JZ4755_CLK_PLL_HALF
, },
163 .mux
= { CGU_REG_CPCCR
, 31, 1 },
164 .div
= { CGU_REG_I2SCDR
, 0, 1, 9, -1, -1, -1 },
168 "spi", CGU_CLK_DIV
| CGU_CLK_GATE
,
169 .parents
= { JZ4755_CLK_PLL_HALF
, },
170 .div
= { CGU_REG_SSICDR
, 0, 1, 4, -1, -1, -1 },
171 .gate
= { CGU_REG_CLKGR
, 4 },
175 "tve", CGU_CLK_MUX
| CGU_CLK_GATE
,
176 .parents
= { JZ4755_CLK_LCD
, JZ4755_CLK_EXT
, },
177 .mux
= { CGU_REG_LPCDR
, 31, 1 },
178 .gate
= { CGU_REG_CLKGR
, 18 },
182 "rtc", CGU_CLK_MUX
| CGU_CLK_GATE
,
183 .parents
= { JZ4755_CLK_EXT512
, JZ4755_CLK_OSC32K
, },
184 .mux
= { CGU_REG_OPCR
, 2, 1},
185 .gate
= { CGU_REG_CLKGR
, 2 },
189 "cim", CGU_CLK_DIV
| CGU_CLK_GATE
,
190 .parents
= { JZ4755_CLK_PLL_HALF
, },
191 .div
= { CGU_REG_CIMCDR
, 0, 1, 8, -1, -1, -1 },
192 .gate
= { CGU_REG_CLKGR
, 8 },
195 /* Gate-only clocks */
197 [JZ4755_CLK_UART0
] = {
198 "uart0", CGU_CLK_GATE
,
199 .parents
= { JZ4755_CLK_EXT_HALF
, },
200 .gate
= { CGU_REG_CLKGR
, 0 },
203 [JZ4755_CLK_UART1
] = {
204 "uart1", CGU_CLK_GATE
,
205 .parents
= { JZ4755_CLK_EXT_HALF
, },
206 .gate
= { CGU_REG_CLKGR
, 14 },
209 [JZ4755_CLK_UART2
] = {
210 "uart2", CGU_CLK_GATE
,
211 .parents
= { JZ4755_CLK_EXT_HALF
, },
212 .gate
= { CGU_REG_CLKGR
, 15 },
217 .parents
= { JZ4755_CLK_EXT_HALF
, },
218 .gate
= { CGU_REG_CLKGR
, 7 },
223 .parents
= { JZ4755_CLK_EXT_HALF
, },
224 .gate
= { CGU_REG_CLKGR
, 5 },
229 .parents
= { JZ4755_CLK_EXT_HALF
, },
230 .gate
= { CGU_REG_CLKGR
, 3 },
235 .parents
= { JZ4755_CLK_H1CLK
, },
236 .gate
= { CGU_REG_CLKGR
, 11 },
241 .parents
= { JZ4755_CLK_EXT
, },
242 .gate
= { CGU_REG_CLKGR
, 1 },
247 .parents
= { JZ4755_CLK_PCLK
, },
248 .gate
= { CGU_REG_CLKGR
, 12 },
251 [JZ4755_CLK_MMC0
] = {
252 "mmc0", CGU_CLK_GATE
,
253 .parents
= { JZ4755_CLK_MMC
, },
254 .gate
= { CGU_REG_CLKGR
, 6 },
257 [JZ4755_CLK_MMC1
] = {
258 "mmc1", CGU_CLK_GATE
,
259 .parents
= { JZ4755_CLK_MMC
, },
260 .gate
= { CGU_REG_CLKGR
, 16 },
263 [JZ4755_CLK_AUX_CPU
] = {
264 "aux_cpu", CGU_CLK_GATE
,
265 .parents
= { JZ4755_CLK_H1CLK
, },
266 .gate
= { CGU_REG_CLKGR
, 24 },
269 [JZ4755_CLK_AHB1
] = {
270 "ahb1", CGU_CLK_GATE
,
271 .parents
= { JZ4755_CLK_H1CLK
, },
272 .gate
= { CGU_REG_CLKGR
, 23 },
275 [JZ4755_CLK_IDCT
] = {
276 "idct", CGU_CLK_GATE
,
277 .parents
= { JZ4755_CLK_H1CLK
, },
278 .gate
= { CGU_REG_CLKGR
, 22 },
283 .parents
= { JZ4755_CLK_H1CLK
, },
284 .gate
= { CGU_REG_CLKGR
, 21 },
289 .parents
= { JZ4755_CLK_H1CLK
, },
290 .gate
= { CGU_REG_CLKGR
, 20 },
295 .parents
= { JZ4755_CLK_H1CLK
, },
296 .gate
= { CGU_REG_CLKGR
, 19 },
299 [JZ4755_CLK_TSSI
] = {
300 "tssi", CGU_CLK_GATE
,
301 .parents
= { JZ4755_CLK_EXT_HALF
/* not sure */, },
302 .gate
= { CGU_REG_CLKGR
, 17 },
307 .parents
= { JZ4755_CLK_PLL_HALF
/* not sure */, },
308 .gate
= { CGU_REG_CLKGR
, 13 },
311 [JZ4755_CLK_EXT512
] = {
312 "ext/512", CGU_CLK_FIXDIV
,
313 .parents
= { JZ4755_CLK_EXT
, },
318 [JZ4755_CLK_UDC_PHY
] = {
319 "udc_phy", CGU_CLK_GATE
,
320 .parents
= { JZ4755_CLK_EXT_HALF
, },
321 .gate
= { CGU_REG_OPCR
, 6, true },
325 static void __init
jz4755_cgu_init(struct device_node
*np
)
329 cgu
= ingenic_cgu_new(jz4755_cgu_clocks
,
330 ARRAY_SIZE(jz4755_cgu_clocks
), np
);
332 pr_err("%s: failed to initialise CGU\n", __func__
);
336 retval
= ingenic_cgu_register_clocks(cgu
);
338 pr_err("%s: failed to register CGU Clocks\n", __func__
);
340 ingenic_cgu_register_syscore_ops(cgu
);
343 * CGU has some children devices, this is useful for probing children devices
344 * in the case where the device node is compatible with "simple-mfd".
346 CLK_OF_DECLARE_DRIVER(jz4755_cgu
, "ingenic,jz4755-cgu", jz4755_cgu_init
);