1// SPDX-License-Identifier: GPL-2.0
2/*
3 * Ingenic JZ4755 SoC CGU driver
4 * Heavily based on JZ4725b CGU driver
5 *
6 * Copyright (C) 2022 Siarhei Volkau
7 * Author: Siarhei Volkau <lis8215@gmail.com>
8 */
9
10#include <linux/clk-provider.h>
11#include <linux/delay.h>
12#include <linux/of.h>
13
14#include <dt-bindings/clock/ingenic,jz4755-cgu.h>
15
16#include "cgu.h"
17#include "pm.h"
18
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
29
30static struct ingenic_cgu *cgu;
31
32static const s8 pll_od_encoding[4] = {
33	0x0, 0x1, -1, 0x3,
34};
35
36static const u8 jz4755_cgu_cpccr_div_table[] = {
37	1, 2, 3, 4, 6, 8,
38};
39
40static const u8 jz4755_cgu_pll_half_div_table[] = {
41	2, 1,
42};
43
44static const struct ingenic_cgu_clk_info jz4755_cgu_clocks[] = {
45
46	/* External clocks */
47
48	[JZ4755_CLK_EXT] = { "ext", CGU_CLK_EXT },
49	[JZ4755_CLK_OSC32K] = { "osc32k", CGU_CLK_EXT },
50
51	[JZ4755_CLK_PLL] = {
52		"pll", CGU_CLK_PLL,
53		.parents = { JZ4755_CLK_EXT, },
54		.pll = {
55			.reg = CGU_REG_CPPCR,
56			.rate_multiplier = 1,
57			.m_shift = 23,
58			.m_bits = 9,
59			.m_offset = 2,
60			.n_shift = 18,
61			.n_bits = 5,
62			.n_offset = 2,
63			.od_shift = 16,
64			.od_bits = 2,
65			.od_max = 4,
66			.od_encoding = pll_od_encoding,
67			.stable_bit = 10,
68			.bypass_reg = CGU_REG_CPPCR,
69			.bypass_bit = 9,
70			.enable_bit = 8,
71		},
72	},
73
74	/* Muxes & dividers */
75
76	[JZ4755_CLK_PLL_HALF] = {
77		"pll half", CGU_CLK_DIV,
78		.parents = { JZ4755_CLK_PLL, },
79		.div = {
80			CGU_REG_CPCCR, 21, 1, 1, -1, -1, -1, 0,
81			jz4755_cgu_pll_half_div_table,
82		},
83	},
84
85	[JZ4755_CLK_EXT_HALF] = {
86		"ext half", CGU_CLK_DIV,
87		.parents = { JZ4755_CLK_EXT, },
88		.div = {
89			CGU_REG_CPCCR, 30, 1, 1, -1, -1, -1, 0,
90			NULL,
91		},
92	},
93
94	[JZ4755_CLK_CCLK] = {
95		"cclk", CGU_CLK_DIV,
96		.parents = { JZ4755_CLK_PLL, },
97		.div = {
98			CGU_REG_CPCCR, 0, 1, 4, 22, -1, -1, 0,
99			jz4755_cgu_cpccr_div_table,
100		},
101	},
102
103	[JZ4755_CLK_H0CLK] = {
104		"hclk", CGU_CLK_DIV,
105		.parents = { JZ4755_CLK_PLL, },
106		.div = {
107			CGU_REG_CPCCR, 4, 1, 4, 22, -1, -1, 0,
108			jz4755_cgu_cpccr_div_table,
109		},
110	},
111
112	[JZ4755_CLK_PCLK] = {
113		"pclk", CGU_CLK_DIV,
114		.parents = { JZ4755_CLK_PLL, },
115		.div = {
116			CGU_REG_CPCCR, 8, 1, 4, 22, -1, -1, 0,
117			jz4755_cgu_cpccr_div_table,
118		},
119	},
120
121	[JZ4755_CLK_MCLK] = {
122		"mclk", CGU_CLK_DIV,
123		.parents = { JZ4755_CLK_PLL, },
124		.div = {
125			CGU_REG_CPCCR, 12, 1, 4, 22, -1, -1, 0,
126			jz4755_cgu_cpccr_div_table,
127		},
128	},
129
130	[JZ4755_CLK_H1CLK] = {
131		"h1clk", CGU_CLK_DIV,
132		.parents = { JZ4755_CLK_PLL, },
133		.div = {
134			CGU_REG_CPCCR, 16, 1, 4, 22, -1, -1, 0,
135			jz4755_cgu_cpccr_div_table,
136		},
137	},
138
139	[JZ4755_CLK_UDC] = {
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 },
145	},
146
147	[JZ4755_CLK_LCD] = {
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 },
152	},
153
154	[JZ4755_CLK_MMC] = {
155		"mmc", CGU_CLK_DIV,
156		.parents = { JZ4755_CLK_PLL_HALF, },
157		.div = { CGU_REG_MSCCDR, 0, 1, 5, -1, -1, -1 },
158	},
159
160	[JZ4755_CLK_I2S] = {
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 },
165	},
166
167	[JZ4755_CLK_SPI] = {
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 },
172	},
173
174	[JZ4755_CLK_TVE] = {
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 },
179	},
180
181	[JZ4755_CLK_RTC] = {
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 },
186	},
187
188	[JZ4755_CLK_CIM] = {
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 },
193	},
194
195	/* Gate-only clocks */
196
197	[JZ4755_CLK_UART0] = {
198		"uart0", CGU_CLK_GATE,
199		.parents = { JZ4755_CLK_EXT_HALF, },
200		.gate = { CGU_REG_CLKGR, 0 },
201	},
202
203	[JZ4755_CLK_UART1] = {
204		"uart1", CGU_CLK_GATE,
205		.parents = { JZ4755_CLK_EXT_HALF, },
206		.gate = { CGU_REG_CLKGR, 14 },
207	},
208
209	[JZ4755_CLK_UART2] = {
210		"uart2", CGU_CLK_GATE,
211		.parents = { JZ4755_CLK_EXT_HALF, },
212		.gate = { CGU_REG_CLKGR, 15 },
213	},
214
215	[JZ4755_CLK_ADC] = {
216		"adc", CGU_CLK_GATE,
217		.parents = { JZ4755_CLK_EXT_HALF, },
218		.gate = { CGU_REG_CLKGR, 7 },
219	},
220
221	[JZ4755_CLK_AIC] = {
222		"aic", CGU_CLK_GATE,
223		.parents = { JZ4755_CLK_EXT_HALF, },
224		.gate = { CGU_REG_CLKGR, 5 },
225	},
226
227	[JZ4755_CLK_I2C] = {
228		"i2c", CGU_CLK_GATE,
229		.parents = { JZ4755_CLK_EXT_HALF, },
230		.gate = { CGU_REG_CLKGR, 3 },
231	},
232
233	[JZ4755_CLK_BCH] = {
234		"bch", CGU_CLK_GATE,
235		.parents = { JZ4755_CLK_H1CLK, },
236		.gate = { CGU_REG_CLKGR, 11 },
237	},
238
239	[JZ4755_CLK_TCU] = {
240		"tcu", CGU_CLK_GATE,
241		.parents = { JZ4755_CLK_EXT, },
242		.gate = { CGU_REG_CLKGR, 1 },
243	},
244
245	[JZ4755_CLK_DMA] = {
246		"dma", CGU_CLK_GATE,
247		.parents = { JZ4755_CLK_PCLK, },
248		.gate = { CGU_REG_CLKGR, 12 },
249	},
250
251	[JZ4755_CLK_MMC0] = {
252		"mmc0", CGU_CLK_GATE,
253		.parents = { JZ4755_CLK_MMC, },
254		.gate = { CGU_REG_CLKGR, 6 },
255	},
256
257	[JZ4755_CLK_MMC1] = {
258		"mmc1", CGU_CLK_GATE,
259		.parents = { JZ4755_CLK_MMC, },
260		.gate = { CGU_REG_CLKGR, 16 },
261	},
262
263	[JZ4755_CLK_AUX_CPU] = {
264		"aux_cpu", CGU_CLK_GATE,
265		.parents = { JZ4755_CLK_H1CLK, },
266		.gate = { CGU_REG_CLKGR, 24 },
267	},
268
269	[JZ4755_CLK_AHB1] = {
270		"ahb1", CGU_CLK_GATE,
271		.parents = { JZ4755_CLK_H1CLK, },
272		.gate = { CGU_REG_CLKGR, 23 },
273	},
274
275	[JZ4755_CLK_IDCT] = {
276		"idct", CGU_CLK_GATE,
277		.parents = { JZ4755_CLK_H1CLK, },
278		.gate = { CGU_REG_CLKGR, 22 },
279	},
280
281	[JZ4755_CLK_DB] = {
282		"db", CGU_CLK_GATE,
283		.parents = { JZ4755_CLK_H1CLK, },
284		.gate = { CGU_REG_CLKGR, 21 },
285	},
286
287	[JZ4755_CLK_ME] = {
288		"me", CGU_CLK_GATE,
289		.parents = { JZ4755_CLK_H1CLK, },
290		.gate = { CGU_REG_CLKGR, 20 },
291	},
292
293	[JZ4755_CLK_MC] = {
294		"mc", CGU_CLK_GATE,
295		.parents = { JZ4755_CLK_H1CLK, },
296		.gate = { CGU_REG_CLKGR, 19 },
297	},
298
299	[JZ4755_CLK_TSSI] = {
300		"tssi", CGU_CLK_GATE,
301		.parents = { JZ4755_CLK_EXT_HALF/* not sure */, },
302		.gate = { CGU_REG_CLKGR, 17 },
303	},
304
305	[JZ4755_CLK_IPU] = {
306		"ipu", CGU_CLK_GATE,
307		.parents = { JZ4755_CLK_PLL_HALF/* not sure */, },
308		.gate = { CGU_REG_CLKGR, 13 },
309	},
310
311	[JZ4755_CLK_EXT512] = {
312		"ext/512", CGU_CLK_FIXDIV,
313		.parents = { JZ4755_CLK_EXT, },
314
315		.fixdiv = { 512 },
316	},
317
318	[JZ4755_CLK_UDC_PHY] = {
319		"udc_phy", CGU_CLK_GATE,
320		.parents = { JZ4755_CLK_EXT_HALF, },
321		.gate = { CGU_REG_OPCR, 6, true },
322	},
323};
324
325static void __init jz4755_cgu_init(struct device_node *np)
326{
327	int retval;
328
329	cgu = ingenic_cgu_new(jz4755_cgu_clocks,
330			      ARRAY_SIZE(jz4755_cgu_clocks), np);
331	if (!cgu) {
332		pr_err("%s: failed to initialise CGU\n", __func__);
333		return;
334	}
335
336	retval = ingenic_cgu_register_clocks(cgu);
337	if (retval)
338		pr_err("%s: failed to register CGU Clocks\n", __func__);
339
340	ingenic_cgu_register_syscore_ops(cgu);
341}
342/*
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".
345 */
346CLK_OF_DECLARE_DRIVER(jz4755_cgu, "ingenic,jz4755-cgu", jz4755_cgu_init);
347