xref: /linux/drivers/clk/aspeed/clk-ast2700.c (revision bf4afc53b77aeaa48b5409da5c8da6bb4eff7f43)
1fdc1eb62SRyan Chen // SPDX-License-Identifier: GPL-2.0
2fdc1eb62SRyan Chen /*
3fdc1eb62SRyan Chen  * Copyright (c) 2024 ASPEED Technology Inc.
4fdc1eb62SRyan Chen  * Author: Ryan Chen <ryan_chen@aspeedtech.com>
5fdc1eb62SRyan Chen  */
6fdc1eb62SRyan Chen #include <linux/auxiliary_bus.h>
7fdc1eb62SRyan Chen #include <linux/bitfield.h>
8fdc1eb62SRyan Chen #include <linux/clk-provider.h>
9fdc1eb62SRyan Chen #include <linux/io.h>
10fdc1eb62SRyan Chen #include <linux/mod_devicetable.h>
11fdc1eb62SRyan Chen #include <linux/platform_device.h>
12fdc1eb62SRyan Chen #include <linux/slab.h>
13fdc1eb62SRyan Chen #include <linux/units.h>
14fdc1eb62SRyan Chen 
15fdc1eb62SRyan Chen #include <dt-bindings/clock/aspeed,ast2700-scu.h>
16fdc1eb62SRyan Chen 
17fdc1eb62SRyan Chen /* SOC0 */
18fdc1eb62SRyan Chen #define SCU0_HWSTRAP1		0x010
19fdc1eb62SRyan Chen #define SCU0_CLK_STOP		0x240
20fdc1eb62SRyan Chen #define SCU0_CLK_SEL1		0x280
21fdc1eb62SRyan Chen #define SCU0_CLK_SEL2		0x284
22fdc1eb62SRyan Chen #define GET_USB_REFCLK_DIV(x)	((GENMASK(23, 20) & (x)) >> 20)
23fdc1eb62SRyan Chen #define UART_DIV13_EN		BIT(30)
24fdc1eb62SRyan Chen #define SCU0_HPLL_PARAM		0x300
25fdc1eb62SRyan Chen #define SCU0_DPLL_PARAM		0x308
26fdc1eb62SRyan Chen #define SCU0_MPLL_PARAM		0x310
27fdc1eb62SRyan Chen #define SCU0_D0CLK_PARAM	0x320
28fdc1eb62SRyan Chen #define SCU0_D1CLK_PARAM	0x330
29fdc1eb62SRyan Chen #define SCU0_CRT0CLK_PARAM	0x340
30fdc1eb62SRyan Chen #define SCU0_CRT1CLK_PARAM	0x350
31fdc1eb62SRyan Chen #define SCU0_MPHYCLK_PARAM	0x360
32fdc1eb62SRyan Chen 
33fdc1eb62SRyan Chen /* SOC1 */
34fdc1eb62SRyan Chen #define SCU1_REVISION_ID	0x0
35fdc1eb62SRyan Chen #define REVISION_ID		GENMASK(23, 16)
36fdc1eb62SRyan Chen #define SCU1_CLK_STOP		0x240
37fdc1eb62SRyan Chen #define SCU1_CLK_STOP2		0x260
38fdc1eb62SRyan Chen #define SCU1_CLK_SEL1		0x280
39fdc1eb62SRyan Chen #define SCU1_CLK_SEL2		0x284
40fdc1eb62SRyan Chen #define SCU1_CLK_I3C_DIV_MASK	GENMASK(25, 23)
41fdc1eb62SRyan Chen #define SCU1_CLK_I3C_DIV(n)	((n) - 1)
42fdc1eb62SRyan Chen #define UXCLK_MASK		GENMASK(1, 0)
43fdc1eb62SRyan Chen #define HUXCLK_MASK		GENMASK(4, 3)
44fdc1eb62SRyan Chen #define SCU1_HPLL_PARAM		0x300
45fdc1eb62SRyan Chen #define SCU1_APLL_PARAM		0x310
46fdc1eb62SRyan Chen #define SCU1_DPLL_PARAM		0x320
47fdc1eb62SRyan Chen #define SCU1_UXCLK_CTRL		0x330
48fdc1eb62SRyan Chen #define SCU1_HUXCLK_CTRL	0x334
49fdc1eb62SRyan Chen #define SCU1_MAC12_CLK_DLY	0x390
50fdc1eb62SRyan Chen #define SCU1_MAC12_CLK_DLY_100M	0x394
51fdc1eb62SRyan Chen #define SCU1_MAC12_CLK_DLY_10M	0x398
52fdc1eb62SRyan Chen 
53fdc1eb62SRyan Chen enum ast2700_clk_type {
54fdc1eb62SRyan Chen 	CLK_MUX,
55fdc1eb62SRyan Chen 	CLK_PLL,
56fdc1eb62SRyan Chen 	CLK_HPLL,
57fdc1eb62SRyan Chen 	CLK_GATE,
58fdc1eb62SRyan Chen 	CLK_MISC,
59fdc1eb62SRyan Chen 	CLK_FIXED,
60fdc1eb62SRyan Chen 	CLK_DIVIDER,
61fdc1eb62SRyan Chen 	CLK_UART_PLL,
62fdc1eb62SRyan Chen 	CLK_GATE_ASPEED,
63fdc1eb62SRyan Chen 	CLK_FIXED_FACTOR,
64fdc1eb62SRyan Chen 	CLK_FIXED_DISPLAY,
65fdc1eb62SRyan Chen };
66fdc1eb62SRyan Chen 
67fdc1eb62SRyan Chen struct ast2700_clk_fixed_factor_data {
68fdc1eb62SRyan Chen 	unsigned int mult;
69fdc1eb62SRyan Chen 	unsigned int div;
70fdc1eb62SRyan Chen 	int parent_id;
71fdc1eb62SRyan Chen };
72fdc1eb62SRyan Chen 
73fdc1eb62SRyan Chen struct ast2700_clk_gate_data {
74fdc1eb62SRyan Chen 	int parent_id;
75fdc1eb62SRyan Chen 	u32 flags;
76fdc1eb62SRyan Chen 	u32 reg;
77fdc1eb62SRyan Chen 	u8 bit;
78fdc1eb62SRyan Chen };
79fdc1eb62SRyan Chen 
80fdc1eb62SRyan Chen struct ast2700_clk_mux_data {
81fdc1eb62SRyan Chen 	const struct clk_hw **parent_hws;
82fdc1eb62SRyan Chen 	const unsigned int *parent_ids;
83fdc1eb62SRyan Chen 	unsigned int num_parents;
84fdc1eb62SRyan Chen 	u8 bit_shift;
85fdc1eb62SRyan Chen 	u8 bit_width;
86fdc1eb62SRyan Chen 	u32 reg;
87fdc1eb62SRyan Chen };
88fdc1eb62SRyan Chen 
89fdc1eb62SRyan Chen struct ast2700_clk_div_data {
90fdc1eb62SRyan Chen 	const struct clk_div_table *div_table;
91fdc1eb62SRyan Chen 	unsigned int parent_id;
92fdc1eb62SRyan Chen 	u8 bit_shift;
93fdc1eb62SRyan Chen 	u8 bit_width;
94fdc1eb62SRyan Chen 	u32 reg;
95fdc1eb62SRyan Chen };
96fdc1eb62SRyan Chen 
97fdc1eb62SRyan Chen struct ast2700_clk_pll_data {
98fdc1eb62SRyan Chen 	unsigned int parent_id;
99fdc1eb62SRyan Chen 	u32 reg;
100fdc1eb62SRyan Chen };
101fdc1eb62SRyan Chen 
102fdc1eb62SRyan Chen struct ast2700_clk_fixed_rate_data {
103fdc1eb62SRyan Chen 	unsigned long fixed_rate;
104fdc1eb62SRyan Chen };
105fdc1eb62SRyan Chen 
106fdc1eb62SRyan Chen struct ast2700_clk_display_fixed_data {
107fdc1eb62SRyan Chen 	u32 reg;
108fdc1eb62SRyan Chen };
109fdc1eb62SRyan Chen 
110fdc1eb62SRyan Chen struct ast2700_clk_info {
111fdc1eb62SRyan Chen 	const char *name;
112fdc1eb62SRyan Chen 	u32 id;
113fdc1eb62SRyan Chen 	u32 reg;
114fdc1eb62SRyan Chen 	u32 type;
115fdc1eb62SRyan Chen 	union {
116fdc1eb62SRyan Chen 		struct ast2700_clk_fixed_factor_data factor;
117fdc1eb62SRyan Chen 		struct ast2700_clk_fixed_rate_data rate;
118fdc1eb62SRyan Chen 		struct ast2700_clk_display_fixed_data display_rate;
119fdc1eb62SRyan Chen 		struct ast2700_clk_gate_data gate;
120fdc1eb62SRyan Chen 		struct ast2700_clk_div_data div;
121fdc1eb62SRyan Chen 		struct ast2700_clk_pll_data pll;
122fdc1eb62SRyan Chen 		struct ast2700_clk_mux_data mux;
123fdc1eb62SRyan Chen 	} data;
124fdc1eb62SRyan Chen };
125fdc1eb62SRyan Chen 
126fdc1eb62SRyan Chen struct ast2700_clk_data {
127fdc1eb62SRyan Chen 	const struct ast2700_clk_info *clk_info;
128fdc1eb62SRyan Chen 	unsigned int nr_clks;
129fdc1eb62SRyan Chen 	const int scu;
130fdc1eb62SRyan Chen };
131fdc1eb62SRyan Chen 
132fdc1eb62SRyan Chen struct ast2700_clk_ctrl {
133fdc1eb62SRyan Chen 	const struct ast2700_clk_data *clk_data;
134fdc1eb62SRyan Chen 	struct device *dev;
135fdc1eb62SRyan Chen 	void __iomem *base;
136fdc1eb62SRyan Chen 	spinlock_t lock; /* clk lock */
137fdc1eb62SRyan Chen };
138fdc1eb62SRyan Chen 
139fdc1eb62SRyan Chen static const struct clk_div_table ast2700_rgmii_div_table[] = {
140fdc1eb62SRyan Chen 	{ 0x0, 4 },
141fdc1eb62SRyan Chen 	{ 0x1, 4 },
142fdc1eb62SRyan Chen 	{ 0x2, 6 },
143fdc1eb62SRyan Chen 	{ 0x3, 8 },
144fdc1eb62SRyan Chen 	{ 0x4, 10 },
145fdc1eb62SRyan Chen 	{ 0x5, 12 },
146fdc1eb62SRyan Chen 	{ 0x6, 14 },
147fdc1eb62SRyan Chen 	{ 0x7, 16 },
148fdc1eb62SRyan Chen 	{ 0 }
149fdc1eb62SRyan Chen };
150fdc1eb62SRyan Chen 
151fdc1eb62SRyan Chen static const struct clk_div_table ast2700_rmii_div_table[] = {
152fdc1eb62SRyan Chen 	{ 0x0, 8 },
153fdc1eb62SRyan Chen 	{ 0x1, 8 },
154fdc1eb62SRyan Chen 	{ 0x2, 12 },
155fdc1eb62SRyan Chen 	{ 0x3, 16 },
156fdc1eb62SRyan Chen 	{ 0x4, 20 },
157fdc1eb62SRyan Chen 	{ 0x5, 24 },
158fdc1eb62SRyan Chen 	{ 0x6, 28 },
159fdc1eb62SRyan Chen 	{ 0x7, 32 },
160fdc1eb62SRyan Chen 	{ 0 }
161fdc1eb62SRyan Chen };
162fdc1eb62SRyan Chen 
163fdc1eb62SRyan Chen static const struct clk_div_table ast2700_clk_div_table[] = {
164fdc1eb62SRyan Chen 	{ 0x0, 2 },
165fdc1eb62SRyan Chen 	{ 0x1, 2 },
166fdc1eb62SRyan Chen 	{ 0x2, 3 },
167fdc1eb62SRyan Chen 	{ 0x3, 4 },
168fdc1eb62SRyan Chen 	{ 0x4, 5 },
169fdc1eb62SRyan Chen 	{ 0x5, 6 },
170fdc1eb62SRyan Chen 	{ 0x6, 7 },
171fdc1eb62SRyan Chen 	{ 0x7, 8 },
172fdc1eb62SRyan Chen 	{ 0 }
173fdc1eb62SRyan Chen };
174fdc1eb62SRyan Chen 
175fdc1eb62SRyan Chen static const struct clk_div_table ast2700_clk_div_table2[] = {
176fdc1eb62SRyan Chen 	{ 0x0, 2 },
177fdc1eb62SRyan Chen 	{ 0x1, 4 },
178fdc1eb62SRyan Chen 	{ 0x2, 6 },
179fdc1eb62SRyan Chen 	{ 0x3, 8 },
180fdc1eb62SRyan Chen 	{ 0x4, 10 },
181fdc1eb62SRyan Chen 	{ 0x5, 12 },
182fdc1eb62SRyan Chen 	{ 0x6, 14 },
183fdc1eb62SRyan Chen 	{ 0x7, 16 },
184fdc1eb62SRyan Chen 	{ 0 }
185fdc1eb62SRyan Chen };
186fdc1eb62SRyan Chen 
187fdc1eb62SRyan Chen static const struct clk_div_table ast2700_hclk_div_table[] = {
188fdc1eb62SRyan Chen 	{ 0x0, 6 },
189fdc1eb62SRyan Chen 	{ 0x1, 5 },
190fdc1eb62SRyan Chen 	{ 0x2, 4 },
191fdc1eb62SRyan Chen 	{ 0x3, 7 },
192fdc1eb62SRyan Chen 	{ 0 }
193fdc1eb62SRyan Chen };
194fdc1eb62SRyan Chen 
195fdc1eb62SRyan Chen static const struct clk_div_table ast2700_clk_uart_div_table[] = {
196fdc1eb62SRyan Chen 	{ 0x0, 1 },
197fdc1eb62SRyan Chen 	{ 0x1, 13 },
198fdc1eb62SRyan Chen 	{ 0 }
199fdc1eb62SRyan Chen };
200fdc1eb62SRyan Chen 
201fdc1eb62SRyan Chen /* soc 0 */
202fdc1eb62SRyan Chen static const unsigned int psp_parent_ids[] = {
203fdc1eb62SRyan Chen 	SCU0_CLK_MPLL,
204fdc1eb62SRyan Chen 	SCU0_CLK_HPLL,
205fdc1eb62SRyan Chen 	SCU0_CLK_HPLL,
206fdc1eb62SRyan Chen 	SCU0_CLK_HPLL,
207fdc1eb62SRyan Chen 	SCU0_CLK_MPLL_DIV2,
208fdc1eb62SRyan Chen 	SCU0_CLK_HPLL_DIV2,
209fdc1eb62SRyan Chen 	SCU0_CLK_HPLL,
210fdc1eb62SRyan Chen 	SCU0_CLK_HPLL
211fdc1eb62SRyan Chen };
212fdc1eb62SRyan Chen 
213fdc1eb62SRyan Chen static const struct clk_hw *psp_parent_hws[ARRAY_SIZE(psp_parent_ids)];
214fdc1eb62SRyan Chen 
215fdc1eb62SRyan Chen static const unsigned int hclk_parent_ids[] = {
216fdc1eb62SRyan Chen 	SCU0_CLK_HPLL,
217fdc1eb62SRyan Chen 	SCU0_CLK_MPLL
218fdc1eb62SRyan Chen };
219fdc1eb62SRyan Chen 
220fdc1eb62SRyan Chen static const struct clk_hw *hclk_parent_hws[ARRAY_SIZE(hclk_parent_ids)];
221fdc1eb62SRyan Chen 
222fdc1eb62SRyan Chen static const unsigned int emmc_parent_ids[] = {
223fdc1eb62SRyan Chen 	SCU0_CLK_MPLL_DIV4,
224fdc1eb62SRyan Chen 	SCU0_CLK_HPLL_DIV4
225fdc1eb62SRyan Chen };
226fdc1eb62SRyan Chen 
227fdc1eb62SRyan Chen static const struct clk_hw *emmc_parent_hws[ARRAY_SIZE(emmc_parent_ids)];
228fdc1eb62SRyan Chen 
229fdc1eb62SRyan Chen static const unsigned int mphy_parent_ids[] = {
230fdc1eb62SRyan Chen 	SCU0_CLK_MPLL,
231fdc1eb62SRyan Chen 	SCU0_CLK_HPLL,
232fdc1eb62SRyan Chen 	SCU0_CLK_DPLL,
233fdc1eb62SRyan Chen 	SCU0_CLK_192M
234fdc1eb62SRyan Chen };
235fdc1eb62SRyan Chen 
236fdc1eb62SRyan Chen static const struct clk_hw *mphy_parent_hws[ARRAY_SIZE(mphy_parent_ids)];
237fdc1eb62SRyan Chen 
238fdc1eb62SRyan Chen static const unsigned int u2phy_parent_ids[] = {
239fdc1eb62SRyan Chen 	SCU0_CLK_MPLL,
240fdc1eb62SRyan Chen 	SCU0_CLK_HPLL
241fdc1eb62SRyan Chen };
242fdc1eb62SRyan Chen 
243fdc1eb62SRyan Chen static const struct clk_hw *u2phy_parent_hws[ARRAY_SIZE(u2phy_parent_ids)];
244fdc1eb62SRyan Chen 
245fdc1eb62SRyan Chen static const unsigned int uart_parent_ids[] = {
246fdc1eb62SRyan Chen 	SCU0_CLK_24M,
247fdc1eb62SRyan Chen 	SCU0_CLK_192M
248fdc1eb62SRyan Chen };
249fdc1eb62SRyan Chen 
250fdc1eb62SRyan Chen static const struct clk_hw *uart_parent_hws[ARRAY_SIZE(uart_parent_ids)];
251fdc1eb62SRyan Chen 
252fdc1eb62SRyan Chen /* soc 1 */
253fdc1eb62SRyan Chen static const unsigned int uartx_parent_ids[] = {
254fdc1eb62SRyan Chen 	SCU1_CLK_UARTX,
255fdc1eb62SRyan Chen 	SCU1_CLK_HUARTX
256fdc1eb62SRyan Chen };
257fdc1eb62SRyan Chen 
258fdc1eb62SRyan Chen static const struct clk_hw *uartx_parent_hws[ARRAY_SIZE(uartx_parent_ids)];
259fdc1eb62SRyan Chen 
260fdc1eb62SRyan Chen static const unsigned int uxclk_parent_ids[] = {
261fdc1eb62SRyan Chen 	SCU1_CLK_APLL_DIV4,
262fdc1eb62SRyan Chen 	SCU1_CLK_APLL_DIV2,
263fdc1eb62SRyan Chen 	SCU1_CLK_APLL,
264fdc1eb62SRyan Chen 	SCU1_CLK_HPLL
265fdc1eb62SRyan Chen };
266fdc1eb62SRyan Chen 
267fdc1eb62SRyan Chen static const struct clk_hw *uxclk_parent_hws[ARRAY_SIZE(uxclk_parent_ids)];
268fdc1eb62SRyan Chen 
269fdc1eb62SRyan Chen static const unsigned int sdclk_parent_ids[] = {
270fdc1eb62SRyan Chen 	SCU1_CLK_HPLL,
271fdc1eb62SRyan Chen 	SCU1_CLK_APLL
272fdc1eb62SRyan Chen };
273fdc1eb62SRyan Chen 
274fdc1eb62SRyan Chen static const struct clk_hw *sdclk_parent_hws[ARRAY_SIZE(sdclk_parent_ids)];
275fdc1eb62SRyan Chen 
276fdc1eb62SRyan Chen #define FIXED_CLK(_id, _name, _rate) \
277fdc1eb62SRyan Chen 	{ \
278fdc1eb62SRyan Chen 		.id = _id,	\
279fdc1eb62SRyan Chen 		.type = CLK_FIXED, \
280fdc1eb62SRyan Chen 		.name = _name, \
281fdc1eb62SRyan Chen 		.data = { .rate = { .fixed_rate = _rate, } }, \
282fdc1eb62SRyan Chen 	}
283fdc1eb62SRyan Chen 
284fdc1eb62SRyan Chen #define FIXED_DISPLAY_CLK(_id, _name, _reg) \
285fdc1eb62SRyan Chen 		{ \
286fdc1eb62SRyan Chen 			.id = _id, \
287fdc1eb62SRyan Chen 			.type = CLK_FIXED_DISPLAY, \
288fdc1eb62SRyan Chen 			.name = _name, \
289fdc1eb62SRyan Chen 			.data = { .display_rate = { .reg = _reg } }, \
290fdc1eb62SRyan Chen 		}
291fdc1eb62SRyan Chen 
292fdc1eb62SRyan Chen #define PLL_CLK(_id, _type, _name, _parent_id, _reg) \
293fdc1eb62SRyan Chen 	{ \
294fdc1eb62SRyan Chen 		.id = _id, \
295fdc1eb62SRyan Chen 		.type = _type, \
296fdc1eb62SRyan Chen 		.name = _name, \
297fdc1eb62SRyan Chen 		.data = { .pll = { \
298fdc1eb62SRyan Chen 			.parent_id = _parent_id, \
299fdc1eb62SRyan Chen 			.reg		= _reg, \
300fdc1eb62SRyan Chen 		} }, \
301fdc1eb62SRyan Chen 	}
302fdc1eb62SRyan Chen 
303fdc1eb62SRyan Chen #define MUX_CLK(_id, _name, _parent_ids, _num_parents, _parent_hws, _reg, _shift, _width) \
304fdc1eb62SRyan Chen 		{ \
305fdc1eb62SRyan Chen 			.id = _id, \
306fdc1eb62SRyan Chen 			.type = CLK_MUX, \
307fdc1eb62SRyan Chen 			.name = _name, \
308fdc1eb62SRyan Chen 			.data = { \
309fdc1eb62SRyan Chen 				.mux = { \
310fdc1eb62SRyan Chen 					.parent_ids  = _parent_ids, \
311fdc1eb62SRyan Chen 					.parent_hws  = _parent_hws, \
312fdc1eb62SRyan Chen 					.num_parents = _num_parents, \
313fdc1eb62SRyan Chen 					.reg = (_reg), \
314fdc1eb62SRyan Chen 					.bit_shift = _shift, \
315fdc1eb62SRyan Chen 					.bit_width = _width, \
316fdc1eb62SRyan Chen 				}, \
317fdc1eb62SRyan Chen 			}, \
318fdc1eb62SRyan Chen 		}
319fdc1eb62SRyan Chen 
320fdc1eb62SRyan Chen #define DIVIDER_CLK(_id, _name, _parent_id, _reg, _shift, _width, _div_table) \
321fdc1eb62SRyan Chen 	{ \
322fdc1eb62SRyan Chen 		.id = _id,	\
323fdc1eb62SRyan Chen 		.type = CLK_DIVIDER, \
324fdc1eb62SRyan Chen 		.name = _name, \
325fdc1eb62SRyan Chen 		.data = { \
326fdc1eb62SRyan Chen 			.div = { \
327fdc1eb62SRyan Chen 				.parent_id = _parent_id, \
328fdc1eb62SRyan Chen 				.reg = _reg, \
329fdc1eb62SRyan Chen 				.bit_shift = _shift, \
330fdc1eb62SRyan Chen 				.bit_width = _width, \
331fdc1eb62SRyan Chen 				.div_table = _div_table, \
332fdc1eb62SRyan Chen 			}, \
333fdc1eb62SRyan Chen 		}, \
334fdc1eb62SRyan Chen 	}
335fdc1eb62SRyan Chen 
336fdc1eb62SRyan Chen #define FIXED_FACTOR_CLK(_id, _name, _parent_id, _mult, _div) \
337fdc1eb62SRyan Chen 	{ \
338fdc1eb62SRyan Chen 		.id = _id,	\
339fdc1eb62SRyan Chen 		.type = CLK_FIXED_FACTOR, \
340fdc1eb62SRyan Chen 		.name = _name, \
341fdc1eb62SRyan Chen 		.data = { .factor = { .parent_id = _parent_id, .mult = _mult, .div = _div, } }, \
342fdc1eb62SRyan Chen 	}
343fdc1eb62SRyan Chen 
344fdc1eb62SRyan Chen #define GATE_CLK(_id, _type, _name, _parent_id, _reg, _bit, _flags) \
345fdc1eb62SRyan Chen 	{ \
346fdc1eb62SRyan Chen 		.id = _id,	\
347fdc1eb62SRyan Chen 		.type = _type, \
348fdc1eb62SRyan Chen 		.name = _name, \
349fdc1eb62SRyan Chen 		.data = { \
350fdc1eb62SRyan Chen 			.gate = { \
351fdc1eb62SRyan Chen 				.parent_id = _parent_id, \
352fdc1eb62SRyan Chen 				.reg = _reg, \
353fdc1eb62SRyan Chen 				.bit = _bit, \
354fdc1eb62SRyan Chen 				.flags = _flags, \
355fdc1eb62SRyan Chen 			}, \
356fdc1eb62SRyan Chen 		}, \
357fdc1eb62SRyan Chen 	}
358fdc1eb62SRyan Chen 
359fdc1eb62SRyan Chen static const struct ast2700_clk_info ast2700_scu0_clk_info[] __initconst = {
360fdc1eb62SRyan Chen 	FIXED_CLK(SCU0_CLKIN, "soc0-clkin", 25 * HZ_PER_MHZ),
361fdc1eb62SRyan Chen 	FIXED_CLK(SCU0_CLK_24M, "soc0-clk24Mhz", 24 * HZ_PER_MHZ),
362fdc1eb62SRyan Chen 	FIXED_CLK(SCU0_CLK_192M, "soc0-clk192Mhz", 192 * HZ_PER_MHZ),
363fdc1eb62SRyan Chen 	FIXED_CLK(SCU0_CLK_U2PHY_CLK12M, "u2phy_clk12m", 12 * HZ_PER_MHZ),
364fdc1eb62SRyan Chen 	FIXED_DISPLAY_CLK(SCU0_CLK_D0, "d0clk", SCU0_D0CLK_PARAM),
365fdc1eb62SRyan Chen 	FIXED_DISPLAY_CLK(SCU0_CLK_D1, "d1clk", SCU0_D1CLK_PARAM),
366fdc1eb62SRyan Chen 	FIXED_DISPLAY_CLK(SCU0_CLK_CRT0, "crt0clk", SCU0_CRT0CLK_PARAM),
367fdc1eb62SRyan Chen 	FIXED_DISPLAY_CLK(SCU0_CLK_CRT1, "crt1clk", SCU0_CRT1CLK_PARAM),
368fdc1eb62SRyan Chen 	PLL_CLK(SCU0_CLK_HPLL, CLK_HPLL, "soc0-hpll", SCU0_CLKIN, SCU0_HPLL_PARAM),
369fdc1eb62SRyan Chen 	PLL_CLK(SCU0_CLK_DPLL, CLK_PLL, "soc0-dpll", SCU0_CLKIN, SCU0_DPLL_PARAM),
370fdc1eb62SRyan Chen 	PLL_CLK(SCU0_CLK_MPLL, CLK_PLL, "soc0-mpll", SCU0_CLKIN, SCU0_MPLL_PARAM),
371fdc1eb62SRyan Chen 	FIXED_FACTOR_CLK(SCU0_CLK_HPLL_DIV2, "soc0-hpll_div2", SCU0_CLK_HPLL, 1, 2),
372fdc1eb62SRyan Chen 	FIXED_FACTOR_CLK(SCU0_CLK_HPLL_DIV4, "soc0-hpll_div4", SCU0_CLK_HPLL, 1, 4),
373fdc1eb62SRyan Chen 	FIXED_FACTOR_CLK(SCU0_CLK_MPLL_DIV2, "soc0-mpll_div2", SCU0_CLK_MPLL, 1, 2),
374fdc1eb62SRyan Chen 	FIXED_FACTOR_CLK(SCU0_CLK_MPLL_DIV4, "soc0-mpll_div4", SCU0_CLK_MPLL, 1, 4),
375fdc1eb62SRyan Chen 	FIXED_FACTOR_CLK(SCU0_CLK_MPLL_DIV8, "soc0-mpll_div8", SCU0_CLK_MPLL, 1, 8),
376fdc1eb62SRyan Chen 	FIXED_FACTOR_CLK(SCU0_CLK_AXI1, "axi1clk", SCU0_CLK_MPLL, 1, 4),
377fdc1eb62SRyan Chen 	MUX_CLK(SCU0_CLK_PSP, "pspclk", psp_parent_ids, ARRAY_SIZE(psp_parent_ids),
378fdc1eb62SRyan Chen 		psp_parent_hws, SCU0_HWSTRAP1, 2, 3),
379fdc1eb62SRyan Chen 	FIXED_FACTOR_CLK(SCU0_CLK_AXI0, "axi0clk", SCU0_CLK_PSP, 1, 2),
380fdc1eb62SRyan Chen 	MUX_CLK(SCU0_CLK_AHBMUX, "soc0-ahbmux", hclk_parent_ids, ARRAY_SIZE(hclk_parent_ids),
381fdc1eb62SRyan Chen 		hclk_parent_hws, SCU0_HWSTRAP1, 7, 1),
382fdc1eb62SRyan Chen 	MUX_CLK(SCU0_CLK_EMMCMUX, "emmcsrc-mux", emmc_parent_ids, ARRAY_SIZE(emmc_parent_ids),
383fdc1eb62SRyan Chen 		emmc_parent_hws, SCU0_CLK_SEL1, 11, 1),
384fdc1eb62SRyan Chen 	MUX_CLK(SCU0_CLK_MPHYSRC, "mphysrc", mphy_parent_ids, ARRAY_SIZE(mphy_parent_ids),
385fdc1eb62SRyan Chen 		mphy_parent_hws, SCU0_CLK_SEL2, 18, 2),
386fdc1eb62SRyan Chen 	MUX_CLK(SCU0_CLK_U2PHY_REFCLKSRC, "u2phy_refclksrc", u2phy_parent_ids,
387fdc1eb62SRyan Chen 		ARRAY_SIZE(u2phy_parent_ids), u2phy_parent_hws, SCU0_CLK_SEL2, 23, 1),
388fdc1eb62SRyan Chen 	MUX_CLK(SCU0_CLK_UART, "soc0-uartclk", uart_parent_ids, ARRAY_SIZE(uart_parent_ids),
389fdc1eb62SRyan Chen 		uart_parent_hws, SCU0_CLK_SEL2, 14, 1),
390fdc1eb62SRyan Chen 	PLL_CLK(SCU0_CLK_MPHY, CLK_MISC, "mphyclk", SCU0_CLK_MPHYSRC, SCU0_MPHYCLK_PARAM),
391fdc1eb62SRyan Chen 	PLL_CLK(SCU0_CLK_U2PHY_REFCLK, CLK_MISC, "u2phy_refclk", SCU0_CLK_U2PHY_REFCLKSRC,
392fdc1eb62SRyan Chen 		SCU0_CLK_SEL2),
393fdc1eb62SRyan Chen 	DIVIDER_CLK(SCU0_CLK_AHB, "soc0-ahb", SCU0_CLK_AHBMUX,
394fdc1eb62SRyan Chen 		    SCU0_HWSTRAP1, 5, 2, ast2700_hclk_div_table),
395fdc1eb62SRyan Chen 	DIVIDER_CLK(SCU0_CLK_EMMC, "emmcclk", SCU0_CLK_EMMCMUX,
396fdc1eb62SRyan Chen 		    SCU0_CLK_SEL1, 12, 3, ast2700_clk_div_table2),
397fdc1eb62SRyan Chen 	DIVIDER_CLK(SCU0_CLK_APB, "soc0-apb", SCU0_CLK_AXI0,
398fdc1eb62SRyan Chen 		    SCU0_CLK_SEL1, 23, 3, ast2700_clk_div_table2),
399fdc1eb62SRyan Chen 	DIVIDER_CLK(SCU0_CLK_HPLL_DIV_AHB, "soc0-hpll-ahb", SCU0_CLK_HPLL,
400fdc1eb62SRyan Chen 		    SCU0_HWSTRAP1, 5, 2, ast2700_hclk_div_table),
401fdc1eb62SRyan Chen 	DIVIDER_CLK(SCU0_CLK_MPLL_DIV_AHB, "soc0-mpll-ahb", SCU0_CLK_MPLL,
402fdc1eb62SRyan Chen 		    SCU0_HWSTRAP1, 5, 2, ast2700_hclk_div_table),
403fdc1eb62SRyan Chen 	DIVIDER_CLK(SCU0_CLK_UART4, "uart4clk", SCU0_CLK_UART,
404fdc1eb62SRyan Chen 		    SCU0_CLK_SEL2, 30, 1, ast2700_clk_uart_div_table),
405fdc1eb62SRyan Chen 	GATE_CLK(SCU0_CLK_GATE_MCLK, CLK_GATE_ASPEED, "mclk-gate", SCU0_CLK_MPLL,
406fdc1eb62SRyan Chen 		 SCU0_CLK_STOP, 0, CLK_IS_CRITICAL),
407fdc1eb62SRyan Chen 	GATE_CLK(SCU0_CLK_GATE_ECLK, CLK_GATE_ASPEED, "eclk-gate", -1, SCU0_CLK_STOP, 1, 0),
408fdc1eb62SRyan Chen 	GATE_CLK(SCU0_CLK_GATE_2DCLK, CLK_GATE_ASPEED, "gclk-gate", -1, SCU0_CLK_STOP, 2, 0),
409fdc1eb62SRyan Chen 	GATE_CLK(SCU0_CLK_GATE_VCLK, CLK_GATE_ASPEED, "vclk-gate", -1, SCU0_CLK_STOP, 3, 0),
410fdc1eb62SRyan Chen 	GATE_CLK(SCU0_CLK_GATE_BCLK, CLK_GATE_ASPEED, "bclk-gate", -1,
411fdc1eb62SRyan Chen 		 SCU0_CLK_STOP, 4, CLK_IS_CRITICAL),
412fdc1eb62SRyan Chen 	GATE_CLK(SCU0_CLK_GATE_VGA0CLK,  CLK_GATE_ASPEED, "vga0clk-gate", -1,
413fdc1eb62SRyan Chen 		 SCU0_CLK_STOP, 5, CLK_IS_CRITICAL),
414fdc1eb62SRyan Chen 	GATE_CLK(SCU0_CLK_GATE_REFCLK,  CLK_GATE_ASPEED, "soc0-refclk-gate", SCU0_CLKIN,
415fdc1eb62SRyan Chen 		 SCU0_CLK_STOP, 6, CLK_IS_CRITICAL),
416fdc1eb62SRyan Chen 	GATE_CLK(SCU0_CLK_GATE_PORTBUSB2CLK, CLK_GATE_ASPEED, "portb-usb2clk-gate", -1,
417fdc1eb62SRyan Chen 		 SCU0_CLK_STOP, 7, 0),
418fdc1eb62SRyan Chen 	GATE_CLK(SCU0_CLK_GATE_UHCICLK, CLK_GATE_ASPEED, "uhciclk-gate", -1, SCU0_CLK_STOP, 9, 0),
419fdc1eb62SRyan Chen 	GATE_CLK(SCU0_CLK_GATE_VGA1CLK, CLK_GATE_ASPEED, "vga1clk-gate", -1,
420fdc1eb62SRyan Chen 		 SCU0_CLK_STOP, 10, CLK_IS_CRITICAL),
421fdc1eb62SRyan Chen 	GATE_CLK(SCU0_CLK_GATE_DDRPHYCLK, CLK_GATE_ASPEED, "ddrphy-gate", -1,
422fdc1eb62SRyan Chen 		 SCU0_CLK_STOP, 11, CLK_IS_CRITICAL),
423fdc1eb62SRyan Chen 	GATE_CLK(SCU0_CLK_GATE_E2M0CLK, CLK_GATE_ASPEED, "e2m0clk-gate", -1,
424fdc1eb62SRyan Chen 		 SCU0_CLK_STOP, 12, CLK_IS_CRITICAL),
425fdc1eb62SRyan Chen 	GATE_CLK(SCU0_CLK_GATE_HACCLK, CLK_GATE_ASPEED, "hacclk-gate", -1, SCU0_CLK_STOP, 13, 0),
426fdc1eb62SRyan Chen 	GATE_CLK(SCU0_CLK_GATE_PORTAUSB2CLK, CLK_GATE_ASPEED, "porta-usb2clk-gate", -1,
427fdc1eb62SRyan Chen 		 SCU0_CLK_STOP, 14, 0),
428fdc1eb62SRyan Chen 	GATE_CLK(SCU0_CLK_GATE_UART4CLK, CLK_GATE_ASPEED, "uart4clk-gate", SCU0_CLK_UART4,
429fdc1eb62SRyan Chen 		 SCU0_CLK_STOP, 15, CLK_IS_CRITICAL),
430fdc1eb62SRyan Chen 	GATE_CLK(SCU0_CLK_GATE_SLICLK, CLK_GATE_ASPEED, "soc0-sliclk-gate", -1,
431fdc1eb62SRyan Chen 		 SCU0_CLK_STOP, 16, CLK_IS_CRITICAL),
432fdc1eb62SRyan Chen 	GATE_CLK(SCU0_CLK_GATE_DACCLK, CLK_GATE_ASPEED, "dacclk-gate", -1,
433fdc1eb62SRyan Chen 		 SCU0_CLK_STOP, 17, CLK_IS_CRITICAL),
434fdc1eb62SRyan Chen 	GATE_CLK(SCU0_CLK_GATE_DP, CLK_GATE_ASPEED, "dpclk-gate", -1,
435fdc1eb62SRyan Chen 		 SCU0_CLK_STOP, 18, CLK_IS_CRITICAL),
436fdc1eb62SRyan Chen 	GATE_CLK(SCU0_CLK_GATE_E2M1CLK, CLK_GATE_ASPEED, "e2m1clk-gate", -1,
437fdc1eb62SRyan Chen 		 SCU0_CLK_STOP, 19, CLK_IS_CRITICAL),
438fdc1eb62SRyan Chen 	GATE_CLK(SCU0_CLK_GATE_CRT0CLK, CLK_GATE_ASPEED, "crt0clk-gate", -1,
439fdc1eb62SRyan Chen 		 SCU0_CLK_STOP, 20, 0),
440fdc1eb62SRyan Chen 	GATE_CLK(SCU0_CLK_GATE_CRT1CLK, CLK_GATE_ASPEED, "crt1clk-gate", -1,
441fdc1eb62SRyan Chen 		 SCU0_CLK_STOP, 21, 0),
442fdc1eb62SRyan Chen 	GATE_CLK(SCU0_CLK_GATE_ECDSACLK, CLK_GATE_ASPEED, "eccclk-gate", -1,
443fdc1eb62SRyan Chen 		 SCU0_CLK_STOP, 23, 0),
444fdc1eb62SRyan Chen 	GATE_CLK(SCU0_CLK_GATE_RSACLK, CLK_GATE_ASPEED, "rsaclk-gate", -1,
445fdc1eb62SRyan Chen 		 SCU0_CLK_STOP, 24, 0),
446fdc1eb62SRyan Chen 	GATE_CLK(SCU0_CLK_GATE_RVAS0CLK, CLK_GATE_ASPEED, "rvas0clk-gate", -1,
447fdc1eb62SRyan Chen 		 SCU0_CLK_STOP, 25, 0),
448fdc1eb62SRyan Chen 	GATE_CLK(SCU0_CLK_GATE_UFSCLK, CLK_GATE_ASPEED, "ufsclk-gate", -1,
449fdc1eb62SRyan Chen 		 SCU0_CLK_STOP, 26, 0),
450fdc1eb62SRyan Chen 	GATE_CLK(SCU0_CLK_GATE_EMMCCLK, CLK_GATE_ASPEED, "emmcclk-gate", SCU0_CLK_EMMC,
451fdc1eb62SRyan Chen 		 SCU0_CLK_STOP, 27, 0),
452fdc1eb62SRyan Chen 	GATE_CLK(SCU0_CLK_GATE_RVAS1CLK, CLK_GATE_ASPEED, "rvas1clk-gate", -1,
453fdc1eb62SRyan Chen 		 SCU0_CLK_STOP, 28, 0),
454fdc1eb62SRyan Chen };
455fdc1eb62SRyan Chen 
456fdc1eb62SRyan Chen static const struct ast2700_clk_info ast2700_scu1_clk_info[] __initconst = {
457fdc1eb62SRyan Chen 	FIXED_CLK(SCU1_CLKIN, "soc1-clkin", 25 * HZ_PER_MHZ),
458fdc1eb62SRyan Chen 	PLL_CLK(SCU1_CLK_HPLL, CLK_PLL, "soc1-hpll", SCU1_CLKIN, SCU1_HPLL_PARAM),
459fdc1eb62SRyan Chen 	PLL_CLK(SCU1_CLK_APLL, CLK_PLL, "soc1-apll", SCU1_CLKIN, SCU1_APLL_PARAM),
460fdc1eb62SRyan Chen 	PLL_CLK(SCU1_CLK_DPLL, CLK_PLL, "soc1-dpll", SCU1_CLKIN, SCU1_DPLL_PARAM),
461fdc1eb62SRyan Chen 	FIXED_FACTOR_CLK(SCU1_CLK_APLL_DIV2, "soc1-apll_div2", SCU1_CLK_APLL, 1, 2),
462fdc1eb62SRyan Chen 	FIXED_FACTOR_CLK(SCU1_CLK_APLL_DIV4, "soc1-apll_div4", SCU1_CLK_APLL, 1, 4),
463fdc1eb62SRyan Chen 	FIXED_FACTOR_CLK(SCU1_CLK_CAN, "canclk", SCU1_CLK_APLL, 1, 10),
464fdc1eb62SRyan Chen 	DIVIDER_CLK(SCU1_CLK_APB, "soc1-apb", SCU1_CLK_HPLL,
465fdc1eb62SRyan Chen 		    SCU1_CLK_SEL1, 18, 3, ast2700_clk_div_table2),
466fdc1eb62SRyan Chen 	DIVIDER_CLK(SCU1_CLK_RMII, "rmii", SCU1_CLK_HPLL,
467fdc1eb62SRyan Chen 		    SCU1_CLK_SEL1, 21, 3, ast2700_rmii_div_table),
468fdc1eb62SRyan Chen 	DIVIDER_CLK(SCU1_CLK_RGMII, "rgmii", SCU1_CLK_HPLL,
469fdc1eb62SRyan Chen 		    SCU1_CLK_SEL1, 25, 3, ast2700_rgmii_div_table),
470fdc1eb62SRyan Chen 	DIVIDER_CLK(SCU1_CLK_MACHCLK, "machclk", SCU1_CLK_HPLL,
471fdc1eb62SRyan Chen 		    SCU1_CLK_SEL1, 29, 3, ast2700_clk_div_table),
472fdc1eb62SRyan Chen 	DIVIDER_CLK(SCU1_CLK_APLL_DIVN, "soc1-apll_divn",
473fdc1eb62SRyan Chen 		    SCU1_CLK_APLL, SCU1_CLK_SEL2, 8, 3, ast2700_clk_div_table),
474fdc1eb62SRyan Chen 	DIVIDER_CLK(SCU1_CLK_AHB, "soc1-ahb", SCU1_CLK_HPLL,
475fdc1eb62SRyan Chen 		    SCU1_CLK_SEL2, 20, 3, ast2700_clk_div_table),
476fdc1eb62SRyan Chen 	DIVIDER_CLK(SCU1_CLK_I3C, "soc1-i3c", SCU1_CLK_HPLL,
477fdc1eb62SRyan Chen 		    SCU1_CLK_SEL2, 23, 3, ast2700_clk_div_table),
478fdc1eb62SRyan Chen 	MUX_CLK(SCU1_CLK_SDMUX, "sdclk-mux", sdclk_parent_ids, ARRAY_SIZE(sdclk_parent_ids),
479fdc1eb62SRyan Chen 		sdclk_parent_hws, SCU1_CLK_SEL1, 13, 1),
480fdc1eb62SRyan Chen 	MUX_CLK(SCU1_CLK_UXCLK, "uxclk", uxclk_parent_ids, ARRAY_SIZE(uxclk_parent_ids),
481fdc1eb62SRyan Chen 		uxclk_parent_hws, SCU1_CLK_SEL2, 0, 2),
482fdc1eb62SRyan Chen 	MUX_CLK(SCU1_CLK_HUXCLK, "huxclk", uxclk_parent_ids, ARRAY_SIZE(uxclk_parent_ids),
483fdc1eb62SRyan Chen 		uxclk_parent_hws, SCU1_CLK_SEL2, 3, 2),
484fdc1eb62SRyan Chen 	DIVIDER_CLK(SCU1_CLK_SDCLK, "sdclk", SCU1_CLK_SDMUX,
485fdc1eb62SRyan Chen 		    SCU1_CLK_SEL1, 14, 3, ast2700_clk_div_table),
486fdc1eb62SRyan Chen 	PLL_CLK(SCU1_CLK_UARTX, CLK_UART_PLL, "uartxclk", SCU1_CLK_UXCLK, SCU1_UXCLK_CTRL),
487fdc1eb62SRyan Chen 	PLL_CLK(SCU1_CLK_HUARTX, CLK_UART_PLL, "huartxclk", SCU1_CLK_HUXCLK, SCU1_HUXCLK_CTRL),
488fdc1eb62SRyan Chen 	MUX_CLK(SCU1_CLK_UART0, "uart0clk", uartx_parent_ids, ARRAY_SIZE(uartx_parent_ids),
489fdc1eb62SRyan Chen 		uartx_parent_hws, SCU1_CLK_SEL1, 0, 1),
490fdc1eb62SRyan Chen 	MUX_CLK(SCU1_CLK_UART1, "uart1clk", uartx_parent_ids, ARRAY_SIZE(uartx_parent_ids),
491fdc1eb62SRyan Chen 		uartx_parent_hws, SCU1_CLK_SEL1, 1, 1),
492fdc1eb62SRyan Chen 	MUX_CLK(SCU1_CLK_UART2, "uart2clk", uartx_parent_ids, ARRAY_SIZE(uartx_parent_ids),
493fdc1eb62SRyan Chen 		uartx_parent_hws, SCU1_CLK_SEL1, 2, 1),
494fdc1eb62SRyan Chen 	MUX_CLK(SCU1_CLK_UART3, "uart3clk", uartx_parent_ids, ARRAY_SIZE(uartx_parent_ids),
495fdc1eb62SRyan Chen 		uartx_parent_hws, SCU1_CLK_SEL1, 3, 1),
496fdc1eb62SRyan Chen 	MUX_CLK(SCU1_CLK_UART5, "uart5clk", uartx_parent_ids, ARRAY_SIZE(uartx_parent_ids),
497fdc1eb62SRyan Chen 		uartx_parent_hws, SCU1_CLK_SEL1, 5, 1),
498fdc1eb62SRyan Chen 	MUX_CLK(SCU1_CLK_UART6, "uart6clk", uartx_parent_ids, ARRAY_SIZE(uartx_parent_ids),
499fdc1eb62SRyan Chen 		uartx_parent_hws, SCU1_CLK_SEL1, 6, 1),
500fdc1eb62SRyan Chen 	MUX_CLK(SCU1_CLK_UART7, "uart7clk", uartx_parent_ids, ARRAY_SIZE(uartx_parent_ids),
501fdc1eb62SRyan Chen 		uartx_parent_hws, SCU1_CLK_SEL1, 7, 1),
502fdc1eb62SRyan Chen 	MUX_CLK(SCU1_CLK_UART8, "uart8clk", uartx_parent_ids, ARRAY_SIZE(uartx_parent_ids),
503fdc1eb62SRyan Chen 		uartx_parent_hws, SCU1_CLK_SEL1, 8, 1),
504fdc1eb62SRyan Chen 	MUX_CLK(SCU1_CLK_UART9, "uart9clk", uartx_parent_ids, ARRAY_SIZE(uartx_parent_ids),
505fdc1eb62SRyan Chen 		uartx_parent_hws, SCU1_CLK_SEL1, 9, 1),
506fdc1eb62SRyan Chen 	MUX_CLK(SCU1_CLK_UART10, "uart10clk", uartx_parent_ids, ARRAY_SIZE(uartx_parent_ids),
507fdc1eb62SRyan Chen 		uartx_parent_hws, SCU1_CLK_SEL1, 10, 1),
508fdc1eb62SRyan Chen 	MUX_CLK(SCU1_CLK_UART11, "uart11clk", uartx_parent_ids, ARRAY_SIZE(uartx_parent_ids),
509fdc1eb62SRyan Chen 		uartx_parent_hws, SCU1_CLK_SEL1, 11, 1),
510fdc1eb62SRyan Chen 	MUX_CLK(SCU1_CLK_UART12, "uart12clk", uartx_parent_ids, ARRAY_SIZE(uartx_parent_ids),
511fdc1eb62SRyan Chen 		uartx_parent_hws, SCU1_CLK_SEL1, 12, 1),
512fdc1eb62SRyan Chen 	FIXED_FACTOR_CLK(SCU1_CLK_UART13, "uart13clk", SCU1_CLK_HUARTX, 1, 1),
513fdc1eb62SRyan Chen 	FIXED_FACTOR_CLK(SCU1_CLK_UART14, "uart14clk", SCU1_CLK_HUARTX, 1, 1),
514fdc1eb62SRyan Chen 	GATE_CLK(SCU1_CLK_MAC0RCLK, CLK_GATE, "mac0rclk-gate", SCU1_CLK_RMII,
515fdc1eb62SRyan Chen 		 SCU1_MAC12_CLK_DLY, 29, 0),
516fdc1eb62SRyan Chen 	GATE_CLK(SCU1_CLK_MAC1RCLK, CLK_GATE, "mac1rclk-gate", SCU1_CLK_RMII,
517fdc1eb62SRyan Chen 		 SCU1_MAC12_CLK_DLY, 30, 0),
518fdc1eb62SRyan Chen 	GATE_CLK(SCU1_CLK_GATE_LCLK0, CLK_GATE_ASPEED, "lclk0-gate", -1,
519fdc1eb62SRyan Chen 		 SCU1_CLK_STOP, 0, CLK_IS_CRITICAL),
520fdc1eb62SRyan Chen 	GATE_CLK(SCU1_CLK_GATE_LCLK1, CLK_GATE_ASPEED, "lclk1-gate", -1,
521fdc1eb62SRyan Chen 		 SCU1_CLK_STOP, 1, CLK_IS_CRITICAL),
522fdc1eb62SRyan Chen 	GATE_CLK(SCU1_CLK_GATE_ESPI0CLK, CLK_GATE_ASPEED, "espi0clk-gate", -1,
523fdc1eb62SRyan Chen 		 SCU1_CLK_STOP, 2, CLK_IS_CRITICAL),
524fdc1eb62SRyan Chen 	GATE_CLK(SCU1_CLK_GATE_ESPI1CLK, CLK_GATE_ASPEED, "espi1clk-gate", -1,
525fdc1eb62SRyan Chen 		 SCU1_CLK_STOP, 3, CLK_IS_CRITICAL),
526fdc1eb62SRyan Chen 	GATE_CLK(SCU1_CLK_GATE_SDCLK, CLK_GATE_ASPEED, "sdclk-gate", SCU1_CLK_SDCLK,
527fdc1eb62SRyan Chen 		 SCU1_CLK_STOP, 4, CLK_IS_CRITICAL),
528fdc1eb62SRyan Chen 	GATE_CLK(SCU1_CLK_GATE_IPEREFCLK, CLK_GATE_ASPEED, "soc1-iperefclk-gate", -1,
529fdc1eb62SRyan Chen 		 SCU1_CLK_STOP, 5, CLK_IS_CRITICAL),
530fdc1eb62SRyan Chen 	GATE_CLK(SCU1_CLK_GATE_REFCLK, CLK_GATE_ASPEED, "soc1-refclk-gate", -1,
531fdc1eb62SRyan Chen 		 SCU1_CLK_STOP, 6, CLK_IS_CRITICAL),
532fdc1eb62SRyan Chen 	GATE_CLK(SCU1_CLK_GATE_LPCHCLK, CLK_GATE_ASPEED, "lpchclk-gate", -1,
533fdc1eb62SRyan Chen 		 SCU1_CLK_STOP, 7, CLK_IS_CRITICAL),
534fdc1eb62SRyan Chen 	GATE_CLK(SCU1_CLK_GATE_MAC0CLK, CLK_GATE_ASPEED, "mac0clk-gate", -1,
535fdc1eb62SRyan Chen 		 SCU1_CLK_STOP, 8, 0),
536fdc1eb62SRyan Chen 	GATE_CLK(SCU1_CLK_GATE_MAC1CLK, CLK_GATE_ASPEED, "mac1clk-gate", -1,
537fdc1eb62SRyan Chen 		 SCU1_CLK_STOP, 9, 0),
538fdc1eb62SRyan Chen 	GATE_CLK(SCU1_CLK_GATE_MAC2CLK, CLK_GATE_ASPEED, "mac2clk-gate", -1,
539fdc1eb62SRyan Chen 		 SCU1_CLK_STOP, 10, 0),
540fdc1eb62SRyan Chen 	GATE_CLK(SCU1_CLK_GATE_UART0CLK, CLK_GATE_ASPEED, "uart0clk-gate", SCU1_CLK_UART0,
541fdc1eb62SRyan Chen 		 SCU1_CLK_STOP, 11, CLK_IS_CRITICAL),
542fdc1eb62SRyan Chen 	GATE_CLK(SCU1_CLK_GATE_UART1CLK, CLK_GATE_ASPEED, "uart1clk-gate", SCU1_CLK_UART1,
543fdc1eb62SRyan Chen 		 SCU1_CLK_STOP, 12, CLK_IS_CRITICAL),
544fdc1eb62SRyan Chen 	GATE_CLK(SCU1_CLK_GATE_UART2CLK, CLK_GATE_ASPEED, "uart2clk-gate", SCU1_CLK_UART2,
545fdc1eb62SRyan Chen 		 SCU1_CLK_STOP, 13, CLK_IS_CRITICAL),
546fdc1eb62SRyan Chen 	GATE_CLK(SCU1_CLK_GATE_UART3CLK, CLK_GATE_ASPEED, "uart3clk-gate", SCU1_CLK_UART3,
547fdc1eb62SRyan Chen 		 SCU1_CLK_STOP, 14, CLK_IS_CRITICAL),
548fdc1eb62SRyan Chen 	GATE_CLK(SCU1_CLK_GATE_I2CCLK, CLK_GATE_ASPEED, "i2cclk-gate", -1, SCU1_CLK_STOP, 15, 0),
549fdc1eb62SRyan Chen 	GATE_CLK(SCU1_CLK_GATE_I3C0CLK, CLK_GATE_ASPEED, "i3c0clk-gate", SCU1_CLK_I3C,
550fdc1eb62SRyan Chen 		 SCU1_CLK_STOP, 16, 0),
551fdc1eb62SRyan Chen 	GATE_CLK(SCU1_CLK_GATE_I3C1CLK, CLK_GATE_ASPEED, "i3c1clk-gate", SCU1_CLK_I3C,
552fdc1eb62SRyan Chen 		 SCU1_CLK_STOP, 17, 0),
553fdc1eb62SRyan Chen 	GATE_CLK(SCU1_CLK_GATE_I3C2CLK, CLK_GATE_ASPEED, "i3c2clk-gate", SCU1_CLK_I3C,
554fdc1eb62SRyan Chen 		 SCU1_CLK_STOP, 18, 0),
555fdc1eb62SRyan Chen 	GATE_CLK(SCU1_CLK_GATE_I3C3CLK, CLK_GATE_ASPEED, "i3c3clk-gate", SCU1_CLK_I3C,
556fdc1eb62SRyan Chen 		 SCU1_CLK_STOP, 19, 0),
557fdc1eb62SRyan Chen 	GATE_CLK(SCU1_CLK_GATE_I3C4CLK, CLK_GATE_ASPEED, "i3c4clk-gate", SCU1_CLK_I3C,
558fdc1eb62SRyan Chen 		 SCU1_CLK_STOP, 20, 0),
559fdc1eb62SRyan Chen 	GATE_CLK(SCU1_CLK_GATE_I3C5CLK, CLK_GATE_ASPEED, "i3c5clk-gate", SCU1_CLK_I3C,
560fdc1eb62SRyan Chen 		 SCU1_CLK_STOP, 21, 0),
561fdc1eb62SRyan Chen 	GATE_CLK(SCU1_CLK_GATE_I3C6CLK, CLK_GATE_ASPEED, "i3c6clk-gate", SCU1_CLK_I3C,
562fdc1eb62SRyan Chen 		 SCU1_CLK_STOP, 22, 0),
563fdc1eb62SRyan Chen 	GATE_CLK(SCU1_CLK_GATE_I3C7CLK, CLK_GATE_ASPEED, "i3c7clk-gate", SCU1_CLK_I3C,
564fdc1eb62SRyan Chen 		 SCU1_CLK_STOP, 23, 0),
565fdc1eb62SRyan Chen 	GATE_CLK(SCU1_CLK_GATE_I3C8CLK, CLK_GATE_ASPEED, "i3c8clk-gate", SCU1_CLK_I3C,
566fdc1eb62SRyan Chen 		 SCU1_CLK_STOP, 24, 0),
567fdc1eb62SRyan Chen 	GATE_CLK(SCU1_CLK_GATE_I3C9CLK, CLK_GATE_ASPEED, "i3c9clk-gate", SCU1_CLK_I3C,
568fdc1eb62SRyan Chen 		 SCU1_CLK_STOP, 25, 0),
569fdc1eb62SRyan Chen 	GATE_CLK(SCU1_CLK_GATE_I3C10CLK, CLK_GATE_ASPEED, "i3c10clk-gate", SCU1_CLK_I3C,
570fdc1eb62SRyan Chen 		 SCU1_CLK_STOP, 26, 0),
571fdc1eb62SRyan Chen 	GATE_CLK(SCU1_CLK_GATE_I3C11CLK, CLK_GATE_ASPEED, "i3c11clk-gate", SCU1_CLK_I3C,
572fdc1eb62SRyan Chen 		 SCU1_CLK_STOP, 27, 0),
573fdc1eb62SRyan Chen 	GATE_CLK(SCU1_CLK_GATE_I3C12CLK, CLK_GATE_ASPEED, "i3c12clk-gate", SCU1_CLK_I3C,
574fdc1eb62SRyan Chen 		 SCU1_CLK_STOP, 28, 0),
575fdc1eb62SRyan Chen 	GATE_CLK(SCU1_CLK_GATE_I3C13CLK, CLK_GATE_ASPEED, "i3c13clk-gate", SCU1_CLK_I3C,
576fdc1eb62SRyan Chen 		 SCU1_CLK_STOP, 29, 0),
577fdc1eb62SRyan Chen 	GATE_CLK(SCU1_CLK_GATE_I3C14CLK, CLK_GATE_ASPEED, "i3c14clk-gate", SCU1_CLK_I3C,
578fdc1eb62SRyan Chen 		 SCU1_CLK_STOP, 30, 0),
579fdc1eb62SRyan Chen 	GATE_CLK(SCU1_CLK_GATE_I3C15CLK, CLK_GATE_ASPEED, "i3c15clk-gate", SCU1_CLK_I3C,
580fdc1eb62SRyan Chen 		 SCU1_CLK_STOP, 31, 0),
581fdc1eb62SRyan Chen 	GATE_CLK(SCU1_CLK_GATE_UART5CLK, CLK_GATE_ASPEED, "uart5clk-gate", SCU1_CLK_UART5,
582fdc1eb62SRyan Chen 		 SCU1_CLK_STOP2, 0, CLK_IS_CRITICAL),
583fdc1eb62SRyan Chen 	GATE_CLK(SCU1_CLK_GATE_UART6CLK, CLK_GATE_ASPEED, "uart6clk-gate", SCU1_CLK_UART6,
584fdc1eb62SRyan Chen 		 SCU1_CLK_STOP2, 1, CLK_IS_CRITICAL),
585fdc1eb62SRyan Chen 	GATE_CLK(SCU1_CLK_GATE_UART7CLK, CLK_GATE_ASPEED, "uart7clk-gate", SCU1_CLK_UART7,
586fdc1eb62SRyan Chen 		 SCU1_CLK_STOP2, 2, CLK_IS_CRITICAL),
587fdc1eb62SRyan Chen 	GATE_CLK(SCU1_CLK_GATE_UART8CLK, CLK_GATE_ASPEED, "uart8clk-gate", SCU1_CLK_UART8,
588fdc1eb62SRyan Chen 		 SCU1_CLK_STOP2, 3, CLK_IS_CRITICAL),
589fdc1eb62SRyan Chen 	GATE_CLK(SCU1_CLK_GATE_UART9CLK, CLK_GATE_ASPEED, "uart9clk-gate", SCU1_CLK_UART9,
590fdc1eb62SRyan Chen 		 SCU1_CLK_STOP2, 4, 0),
591fdc1eb62SRyan Chen 	GATE_CLK(SCU1_CLK_GATE_UART10CLK, CLK_GATE_ASPEED, "uart10clk-gate", SCU1_CLK_UART10,
592fdc1eb62SRyan Chen 		 SCU1_CLK_STOP2, 5, 0),
593fdc1eb62SRyan Chen 	GATE_CLK(SCU1_CLK_GATE_UART11CLK, CLK_GATE_ASPEED, "uart11clk-gate", SCU1_CLK_UART11,
594fdc1eb62SRyan Chen 		 SCU1_CLK_STOP2, 6, 0),
595fdc1eb62SRyan Chen 	GATE_CLK(SCU1_CLK_GATE_UART12CLK, CLK_GATE_ASPEED, "uart12clk-gate", SCU1_CLK_UART12,
596fdc1eb62SRyan Chen 		 SCU1_CLK_STOP2, 7, 0),
597fdc1eb62SRyan Chen 	GATE_CLK(SCU1_CLK_GATE_FSICLK, CLK_GATE_ASPEED, "fsiclk-gate", -1, SCU1_CLK_STOP2, 8, 0),
598fdc1eb62SRyan Chen 	GATE_CLK(SCU1_CLK_GATE_LTPIPHYCLK, CLK_GATE_ASPEED, "ltpiphyclk-gate", -1,
599fdc1eb62SRyan Chen 		 SCU1_CLK_STOP2, 9, 0),
600fdc1eb62SRyan Chen 	GATE_CLK(SCU1_CLK_GATE_LTPICLK, CLK_GATE_ASPEED, "ltpiclk-gate", -1,
601fdc1eb62SRyan Chen 		 SCU1_CLK_STOP2, 10, 0),
602fdc1eb62SRyan Chen 	GATE_CLK(SCU1_CLK_GATE_VGALCLK, CLK_GATE_ASPEED, "vgalclk-gate", -1,
603fdc1eb62SRyan Chen 		 SCU1_CLK_STOP2, 11, CLK_IS_CRITICAL),
604fdc1eb62SRyan Chen 	GATE_CLK(SCU1_CLK_GATE_UHCICLK, CLK_GATE_ASPEED, "usbuartclk-gate", -1,
605fdc1eb62SRyan Chen 		 SCU1_CLK_STOP2, 12, 0),
606fdc1eb62SRyan Chen 	GATE_CLK(SCU1_CLK_GATE_CANCLK, CLK_GATE_ASPEED, "canclk-gate", SCU1_CLK_CAN,
607fdc1eb62SRyan Chen 		 SCU1_CLK_STOP2, 13, 0),
608fdc1eb62SRyan Chen 	GATE_CLK(SCU1_CLK_GATE_PCICLK, CLK_GATE_ASPEED, "pciclk-gate", -1,
609fdc1eb62SRyan Chen 		 SCU1_CLK_STOP2, 14, 0),
610fdc1eb62SRyan Chen 	GATE_CLK(SCU1_CLK_GATE_SLICLK, CLK_GATE_ASPEED, "soc1-sliclk-gate", -1,
611fdc1eb62SRyan Chen 		 SCU1_CLK_STOP2, 15, CLK_IS_CRITICAL),
612fdc1eb62SRyan Chen 	GATE_CLK(SCU1_CLK_GATE_E2MCLK, CLK_GATE_ASPEED, "soc1-e2m-gate", -1,
613fdc1eb62SRyan Chen 		 SCU1_CLK_STOP2, 16, CLK_IS_CRITICAL),
614fdc1eb62SRyan Chen 	GATE_CLK(SCU1_CLK_GATE_PORTCUSB2CLK, CLK_GATE_ASPEED, "portcusb2-gate", -1,
615fdc1eb62SRyan Chen 		 SCU1_CLK_STOP2, 17, 0),
616fdc1eb62SRyan Chen 	GATE_CLK(SCU1_CLK_GATE_PORTDUSB2CLK, CLK_GATE_ASPEED, "portdusb2-gate", -1,
617fdc1eb62SRyan Chen 		 SCU1_CLK_STOP2, 18, 0),
618fdc1eb62SRyan Chen 	GATE_CLK(SCU1_CLK_GATE_LTPI1TXCLK, CLK_GATE_ASPEED, "ltp1tx-gate", -1,
619fdc1eb62SRyan Chen 		 SCU1_CLK_STOP2, 19, 0),
620fdc1eb62SRyan Chen };
621fdc1eb62SRyan Chen 
ast2700_clk_hw_register_fixed_display(void __iomem * reg,const char * name,struct ast2700_clk_ctrl * clk_ctrl)622fdc1eb62SRyan Chen static struct clk_hw *ast2700_clk_hw_register_fixed_display(void __iomem *reg, const char *name,
623fdc1eb62SRyan Chen 							    struct ast2700_clk_ctrl *clk_ctrl)
624fdc1eb62SRyan Chen {
625fdc1eb62SRyan Chen 	unsigned int mult, div, r, n;
626fdc1eb62SRyan Chen 	u32 xdclk;
627fdc1eb62SRyan Chen 	u32 val;
628fdc1eb62SRyan Chen 
629fdc1eb62SRyan Chen 	val = readl(clk_ctrl->base + SCU0_CLK_SEL2);
630fdc1eb62SRyan Chen 	if (val & BIT(29))
631fdc1eb62SRyan Chen 		xdclk = 800 * HZ_PER_MHZ;
632fdc1eb62SRyan Chen 	else
633fdc1eb62SRyan Chen 		xdclk = 1000 * HZ_PER_MHZ;
634fdc1eb62SRyan Chen 
635fdc1eb62SRyan Chen 	val = readl(reg);
636fdc1eb62SRyan Chen 	r = val & GENMASK(15, 0);
637fdc1eb62SRyan Chen 	n = (val >> 16) & GENMASK(15, 0);
638fdc1eb62SRyan Chen 	mult = r;
639fdc1eb62SRyan Chen 	div = 2 * n;
640fdc1eb62SRyan Chen 
641fdc1eb62SRyan Chen 	return devm_clk_hw_register_fixed_rate(clk_ctrl->dev, name, NULL, 0, (xdclk * mult) / div);
642fdc1eb62SRyan Chen }
643fdc1eb62SRyan Chen 
ast2700_clk_hw_register_hpll(void __iomem * reg,const char * name,const struct clk_hw * parent_hw,struct ast2700_clk_ctrl * clk_ctrl)644fdc1eb62SRyan Chen static struct clk_hw *ast2700_clk_hw_register_hpll(void __iomem *reg,
645fdc1eb62SRyan Chen 						   const char *name, const struct clk_hw *parent_hw,
646fdc1eb62SRyan Chen 						   struct ast2700_clk_ctrl *clk_ctrl)
647fdc1eb62SRyan Chen {
648fdc1eb62SRyan Chen 	unsigned int mult, div;
649fdc1eb62SRyan Chen 	u32 val;
650fdc1eb62SRyan Chen 
651fdc1eb62SRyan Chen 	val = readl(clk_ctrl->base + SCU0_HWSTRAP1);
652fdc1eb62SRyan Chen 	if ((readl(clk_ctrl->base) & REVISION_ID) && (val & BIT(3))) {
653fdc1eb62SRyan Chen 		switch ((val & GENMASK(4, 2)) >> 2) {
654fdc1eb62SRyan Chen 		case 2:
655fdc1eb62SRyan Chen 			return devm_clk_hw_register_fixed_rate(clk_ctrl->dev, name, NULL,
656fdc1eb62SRyan Chen 							       0, 1800 * HZ_PER_MHZ);
657fdc1eb62SRyan Chen 		case 3:
658fdc1eb62SRyan Chen 			return devm_clk_hw_register_fixed_rate(clk_ctrl->dev, name, NULL,
659fdc1eb62SRyan Chen 							       0, 1700 * HZ_PER_MHZ);
660fdc1eb62SRyan Chen 		case 6:
661fdc1eb62SRyan Chen 			return devm_clk_hw_register_fixed_rate(clk_ctrl->dev, name, NULL,
662fdc1eb62SRyan Chen 							       0, 1200 * HZ_PER_MHZ);
663fdc1eb62SRyan Chen 		case 7:
664fdc1eb62SRyan Chen 			return devm_clk_hw_register_fixed_rate(clk_ctrl->dev, name, NULL,
665fdc1eb62SRyan Chen 							       0, 800 * HZ_PER_MHZ);
666fdc1eb62SRyan Chen 		default:
667fdc1eb62SRyan Chen 			return ERR_PTR(-EINVAL);
668fdc1eb62SRyan Chen 		}
669fdc1eb62SRyan Chen 	} else if ((val & GENMASK(3, 2)) != 0) {
670fdc1eb62SRyan Chen 		switch ((val & GENMASK(3, 2)) >> 2) {
671fdc1eb62SRyan Chen 		case 1:
672fdc1eb62SRyan Chen 			return devm_clk_hw_register_fixed_rate(clk_ctrl->dev, name, NULL,
673fdc1eb62SRyan Chen 							       0, 1900 * HZ_PER_MHZ);
674fdc1eb62SRyan Chen 		case 2:
675fdc1eb62SRyan Chen 			return devm_clk_hw_register_fixed_rate(clk_ctrl->dev, name, NULL,
676fdc1eb62SRyan Chen 							       0, 1800 * HZ_PER_MHZ);
677fdc1eb62SRyan Chen 		case 3:
678fdc1eb62SRyan Chen 			return devm_clk_hw_register_fixed_rate(clk_ctrl->dev, name, NULL,
679fdc1eb62SRyan Chen 							       0, 1700 * HZ_PER_MHZ);
680fdc1eb62SRyan Chen 		default:
681fdc1eb62SRyan Chen 			return ERR_PTR(-EINVAL);
682fdc1eb62SRyan Chen 		}
683fdc1eb62SRyan Chen 	} else {
684fdc1eb62SRyan Chen 		val = readl(reg);
685fdc1eb62SRyan Chen 
686fdc1eb62SRyan Chen 		if (val & BIT(24)) {
687fdc1eb62SRyan Chen 			/* Pass through mode */
688fdc1eb62SRyan Chen 			mult = 1;
689fdc1eb62SRyan Chen 			div = 1;
690fdc1eb62SRyan Chen 		} else {
691fdc1eb62SRyan Chen 			u32 m = val & 0x1fff;
692fdc1eb62SRyan Chen 			u32 n = (val >> 13) & 0x3f;
693fdc1eb62SRyan Chen 			u32 p = (val >> 19) & 0xf;
694fdc1eb62SRyan Chen 
695fdc1eb62SRyan Chen 			mult = (m + 1) / (2 * (n + 1));
696fdc1eb62SRyan Chen 			div = p + 1;
697fdc1eb62SRyan Chen 		}
698fdc1eb62SRyan Chen 	}
699fdc1eb62SRyan Chen 
700fdc1eb62SRyan Chen 	return devm_clk_hw_register_fixed_factor_parent_hw(clk_ctrl->dev, name,
701fdc1eb62SRyan Chen 							   parent_hw, 0, mult, div);
702fdc1eb62SRyan Chen }
703fdc1eb62SRyan Chen 
ast2700_clk_hw_register_pll(int clk_idx,void __iomem * reg,const char * name,const struct clk_hw * parent_hw,struct ast2700_clk_ctrl * clk_ctrl)704fdc1eb62SRyan Chen static struct clk_hw *ast2700_clk_hw_register_pll(int clk_idx, void __iomem *reg,
705fdc1eb62SRyan Chen 						  const char *name, const struct clk_hw *parent_hw,
706fdc1eb62SRyan Chen 						  struct ast2700_clk_ctrl *clk_ctrl)
707fdc1eb62SRyan Chen {
708fdc1eb62SRyan Chen 	int scu = clk_ctrl->clk_data->scu;
709fdc1eb62SRyan Chen 	unsigned int mult, div;
710fdc1eb62SRyan Chen 	u32 val = readl(reg);
711fdc1eb62SRyan Chen 
712fdc1eb62SRyan Chen 	if (val & BIT(24)) {
713fdc1eb62SRyan Chen 		/* Pass through mode */
714fdc1eb62SRyan Chen 		mult = 1;
715fdc1eb62SRyan Chen 		div = 1;
716fdc1eb62SRyan Chen 	} else {
717fdc1eb62SRyan Chen 		u32 m = val & 0x1fff;
718fdc1eb62SRyan Chen 		u32 n = (val >> 13) & 0x3f;
719fdc1eb62SRyan Chen 		u32 p = (val >> 19) & 0xf;
720fdc1eb62SRyan Chen 
721fdc1eb62SRyan Chen 		if (scu) {
722fdc1eb62SRyan Chen 			mult = (m + 1) / (n + 1);
723fdc1eb62SRyan Chen 			div = p + 1;
724fdc1eb62SRyan Chen 		} else {
725fdc1eb62SRyan Chen 			if (clk_idx == SCU0_CLK_MPLL) {
726fdc1eb62SRyan Chen 				mult = m / (n + 1);
727fdc1eb62SRyan Chen 				div = p + 1;
728fdc1eb62SRyan Chen 			} else {
729fdc1eb62SRyan Chen 				mult = (m + 1) / (2 * (n + 1));
730fdc1eb62SRyan Chen 				div = p + 1;
731fdc1eb62SRyan Chen 			}
732fdc1eb62SRyan Chen 		}
733fdc1eb62SRyan Chen 	}
734fdc1eb62SRyan Chen 
735fdc1eb62SRyan Chen 	return devm_clk_hw_register_fixed_factor_parent_hw(clk_ctrl->dev, name,
736fdc1eb62SRyan Chen 							   parent_hw, 0, mult, div);
737fdc1eb62SRyan Chen }
738fdc1eb62SRyan Chen 
ast2700_clk_hw_register_uartpll(void __iomem * reg,const char * name,const struct clk_hw * parent_hw,struct ast2700_clk_ctrl * clk_ctrl)739fdc1eb62SRyan Chen static struct clk_hw *ast2700_clk_hw_register_uartpll(void __iomem *reg, const char *name,
740fdc1eb62SRyan Chen 						      const struct clk_hw *parent_hw,
741fdc1eb62SRyan Chen 						      struct ast2700_clk_ctrl *clk_ctrl)
742fdc1eb62SRyan Chen {
743fdc1eb62SRyan Chen 	unsigned int mult, div;
744fdc1eb62SRyan Chen 	u32 val = readl(reg);
745fdc1eb62SRyan Chen 	u32 r = val & 0xff;
746fdc1eb62SRyan Chen 	u32 n = (val >> 8) & 0x3ff;
747fdc1eb62SRyan Chen 
748fdc1eb62SRyan Chen 	mult = r;
749fdc1eb62SRyan Chen 	div = n * 2;
750fdc1eb62SRyan Chen 
751fdc1eb62SRyan Chen 	return devm_clk_hw_register_fixed_factor_parent_hw(clk_ctrl->dev, name,
752fdc1eb62SRyan Chen 							   parent_hw, 0, mult, div);
753fdc1eb62SRyan Chen }
754fdc1eb62SRyan Chen 
ast2700_clk_hw_register_misc(int clk_idx,void __iomem * reg,const char * name,const struct clk_hw * parent_hw,struct ast2700_clk_ctrl * clk_ctrl)755fdc1eb62SRyan Chen static struct clk_hw *ast2700_clk_hw_register_misc(int clk_idx, void __iomem *reg,
756fdc1eb62SRyan Chen 						   const char *name, const struct clk_hw *parent_hw,
757fdc1eb62SRyan Chen 						   struct ast2700_clk_ctrl *clk_ctrl)
758fdc1eb62SRyan Chen {
759fdc1eb62SRyan Chen 	u32 div = 0;
760fdc1eb62SRyan Chen 
761fdc1eb62SRyan Chen 	if (clk_idx == SCU0_CLK_MPHY) {
762fdc1eb62SRyan Chen 		div = readl(reg) + 1;
763fdc1eb62SRyan Chen 	} else if (clk_idx == SCU0_CLK_U2PHY_REFCLK) {
764fdc1eb62SRyan Chen 		if (readl(clk_ctrl->base) & REVISION_ID)
765fdc1eb62SRyan Chen 			div = (GET_USB_REFCLK_DIV(readl(reg)) + 1) << 4;
766fdc1eb62SRyan Chen 		else
767fdc1eb62SRyan Chen 			div = (GET_USB_REFCLK_DIV(readl(reg)) + 1) << 1;
768fdc1eb62SRyan Chen 	} else {
769fdc1eb62SRyan Chen 		return ERR_PTR(-EINVAL);
770fdc1eb62SRyan Chen 	}
771fdc1eb62SRyan Chen 
772fdc1eb62SRyan Chen 	return devm_clk_hw_register_fixed_factor_parent_hw(clk_ctrl->dev, name,
773fdc1eb62SRyan Chen 							   parent_hw, 0, 1, div);
774fdc1eb62SRyan Chen }
775fdc1eb62SRyan Chen 
ast2700_clk_is_enabled(struct clk_hw * hw)776fdc1eb62SRyan Chen static int ast2700_clk_is_enabled(struct clk_hw *hw)
777fdc1eb62SRyan Chen {
778fdc1eb62SRyan Chen 	struct clk_gate *gate = to_clk_gate(hw);
779fdc1eb62SRyan Chen 	u32 clk = BIT(gate->bit_idx);
780fdc1eb62SRyan Chen 	u32 reg;
781fdc1eb62SRyan Chen 
782fdc1eb62SRyan Chen 	reg = readl(gate->reg);
783fdc1eb62SRyan Chen 
784fdc1eb62SRyan Chen 	return !(reg & clk);
785fdc1eb62SRyan Chen }
786fdc1eb62SRyan Chen 
ast2700_clk_enable(struct clk_hw * hw)787fdc1eb62SRyan Chen static int ast2700_clk_enable(struct clk_hw *hw)
788fdc1eb62SRyan Chen {
789fdc1eb62SRyan Chen 	struct clk_gate *gate = to_clk_gate(hw);
790fdc1eb62SRyan Chen 	u32 clk = BIT(gate->bit_idx);
791fdc1eb62SRyan Chen 
792fdc1eb62SRyan Chen 	if (readl(gate->reg) & clk)
793fdc1eb62SRyan Chen 		writel(clk, gate->reg + 0x04);
794fdc1eb62SRyan Chen 
795fdc1eb62SRyan Chen 	return 0;
796fdc1eb62SRyan Chen }
797fdc1eb62SRyan Chen 
ast2700_clk_disable(struct clk_hw * hw)798fdc1eb62SRyan Chen static void ast2700_clk_disable(struct clk_hw *hw)
799fdc1eb62SRyan Chen {
800fdc1eb62SRyan Chen 	struct clk_gate *gate = to_clk_gate(hw);
801fdc1eb62SRyan Chen 	u32 clk = BIT(gate->bit_idx);
802fdc1eb62SRyan Chen 
803fdc1eb62SRyan Chen 	/* Clock is set to enable, so use write to set register */
804fdc1eb62SRyan Chen 	writel(clk, gate->reg);
805fdc1eb62SRyan Chen }
806fdc1eb62SRyan Chen 
807fdc1eb62SRyan Chen static const struct clk_ops ast2700_clk_gate_ops = {
808fdc1eb62SRyan Chen 	.enable = ast2700_clk_enable,
809fdc1eb62SRyan Chen 	.disable = ast2700_clk_disable,
810fdc1eb62SRyan Chen 	.is_enabled = ast2700_clk_is_enabled,
811fdc1eb62SRyan Chen };
812fdc1eb62SRyan Chen 
ast2700_clk_hw_register_gate(struct device * dev,const char * name,const struct clk_hw * parent_hw,void __iomem * reg,u8 clock_idx,unsigned long flags,spinlock_t * lock)813fdc1eb62SRyan Chen static struct clk_hw *ast2700_clk_hw_register_gate(struct device *dev, const char *name,
814fdc1eb62SRyan Chen 						   const struct clk_hw *parent_hw,
815fdc1eb62SRyan Chen 						   void __iomem *reg, u8 clock_idx,
816fdc1eb62SRyan Chen 						   unsigned long flags, spinlock_t *lock)
817fdc1eb62SRyan Chen {
818fdc1eb62SRyan Chen 	struct clk_init_data init;
819fdc1eb62SRyan Chen 	struct clk_gate *gate;
820fdc1eb62SRyan Chen 	struct clk_hw *hw;
821fdc1eb62SRyan Chen 	int ret = -EINVAL;
822fdc1eb62SRyan Chen 
823*bf4afc53SLinus Torvalds 	gate = kzalloc_obj(*gate);
824fdc1eb62SRyan Chen 	if (!gate)
825fdc1eb62SRyan Chen 		return ERR_PTR(-ENOMEM);
826fdc1eb62SRyan Chen 
827fdc1eb62SRyan Chen 	init.name = name;
828fdc1eb62SRyan Chen 	init.ops = &ast2700_clk_gate_ops;
829fdc1eb62SRyan Chen 	init.flags = flags;
830fdc1eb62SRyan Chen 	init.parent_names = NULL;
831fdc1eb62SRyan Chen 	init.parent_hws = parent_hw ? &parent_hw : NULL;
832fdc1eb62SRyan Chen 	init.parent_data = NULL;
833fdc1eb62SRyan Chen 	init.num_parents = parent_hw ? 1 : 0;
834fdc1eb62SRyan Chen 
835fdc1eb62SRyan Chen 	gate->reg = reg;
836fdc1eb62SRyan Chen 	gate->bit_idx = clock_idx;
837fdc1eb62SRyan Chen 	gate->flags = 0;
838fdc1eb62SRyan Chen 	gate->lock = lock;
839fdc1eb62SRyan Chen 	gate->hw.init = &init;
840fdc1eb62SRyan Chen 
841fdc1eb62SRyan Chen 	hw = &gate->hw;
842fdc1eb62SRyan Chen 	ret = clk_hw_register(dev, hw);
843fdc1eb62SRyan Chen 	if (ret) {
844fdc1eb62SRyan Chen 		kfree(gate);
845fdc1eb62SRyan Chen 		hw = ERR_PTR(ret);
846fdc1eb62SRyan Chen 	}
847fdc1eb62SRyan Chen 
848fdc1eb62SRyan Chen 	return hw;
849fdc1eb62SRyan Chen }
850fdc1eb62SRyan Chen 
ast2700_soc1_configure_i3c_clk(struct ast2700_clk_ctrl * clk_ctrl)851fdc1eb62SRyan Chen static void ast2700_soc1_configure_i3c_clk(struct ast2700_clk_ctrl *clk_ctrl)
852fdc1eb62SRyan Chen {
853fdc1eb62SRyan Chen 	if (readl(clk_ctrl->base) & REVISION_ID) {
854fdc1eb62SRyan Chen 		u32 val;
855fdc1eb62SRyan Chen 
856fdc1eb62SRyan Chen 		/* I3C 250MHz = HPLL/4 */
857fdc1eb62SRyan Chen 		val = readl(clk_ctrl->base + SCU1_CLK_SEL2) & ~SCU1_CLK_I3C_DIV_MASK;
858fdc1eb62SRyan Chen 		val |= FIELD_PREP(SCU1_CLK_I3C_DIV_MASK, SCU1_CLK_I3C_DIV(4));
859fdc1eb62SRyan Chen 		writel(val, clk_ctrl->base + SCU1_CLK_SEL2);
860fdc1eb62SRyan Chen 	}
861fdc1eb62SRyan Chen }
862fdc1eb62SRyan Chen 
get_parent_hw_or_null(struct clk_hw ** hws,int idx)863fdc1eb62SRyan Chen static inline const struct clk_hw *get_parent_hw_or_null(struct clk_hw **hws, int idx)
864fdc1eb62SRyan Chen {
865fdc1eb62SRyan Chen 	if (idx < 0)
866fdc1eb62SRyan Chen 		return NULL;
867fdc1eb62SRyan Chen 	else
868fdc1eb62SRyan Chen 		return hws[idx];
869fdc1eb62SRyan Chen }
870fdc1eb62SRyan Chen 
ast2700_soc_clk_probe(struct platform_device * pdev)871fdc1eb62SRyan Chen static int ast2700_soc_clk_probe(struct platform_device *pdev)
872fdc1eb62SRyan Chen {
873fdc1eb62SRyan Chen 	const struct ast2700_clk_data *clk_data;
874fdc1eb62SRyan Chen 	struct clk_hw_onecell_data *clk_hw_data;
875fdc1eb62SRyan Chen 	struct ast2700_clk_ctrl *clk_ctrl;
876fdc1eb62SRyan Chen 	struct device *dev = &pdev->dev;
877fdc1eb62SRyan Chen 	struct auxiliary_device *adev;
878fdc1eb62SRyan Chen 	void __iomem *clk_base;
879fdc1eb62SRyan Chen 	struct clk_hw **hws;
880fdc1eb62SRyan Chen 	char *reset_name;
881fdc1eb62SRyan Chen 	int ret;
882fdc1eb62SRyan Chen 	int i;
883fdc1eb62SRyan Chen 
884fdc1eb62SRyan Chen 	clk_ctrl = devm_kzalloc(dev, sizeof(*clk_ctrl), GFP_KERNEL);
885fdc1eb62SRyan Chen 	if (!clk_ctrl)
886fdc1eb62SRyan Chen 		return -ENOMEM;
887fdc1eb62SRyan Chen 	clk_ctrl->dev = dev;
888fdc1eb62SRyan Chen 	dev_set_drvdata(&pdev->dev, clk_ctrl);
889fdc1eb62SRyan Chen 
890fdc1eb62SRyan Chen 	spin_lock_init(&clk_ctrl->lock);
891fdc1eb62SRyan Chen 
892fdc1eb62SRyan Chen 	clk_base = devm_platform_ioremap_resource(pdev, 0);
893fdc1eb62SRyan Chen 	if (IS_ERR(clk_base))
894fdc1eb62SRyan Chen 		return PTR_ERR(clk_base);
895fdc1eb62SRyan Chen 
896fdc1eb62SRyan Chen 	clk_ctrl->base = clk_base;
897fdc1eb62SRyan Chen 
898fdc1eb62SRyan Chen 	clk_data = device_get_match_data(dev);
899fdc1eb62SRyan Chen 	if (!clk_data)
900fdc1eb62SRyan Chen 		return -ENODEV;
901fdc1eb62SRyan Chen 
902fdc1eb62SRyan Chen 	clk_ctrl->clk_data = clk_data;
903fdc1eb62SRyan Chen 	reset_name = devm_kasprintf(dev, GFP_KERNEL, "reset%d", clk_data->scu);
904fdc1eb62SRyan Chen 
905fdc1eb62SRyan Chen 	clk_hw_data = devm_kzalloc(dev, struct_size(clk_hw_data, hws, clk_data->nr_clks),
906fdc1eb62SRyan Chen 				   GFP_KERNEL);
907fdc1eb62SRyan Chen 	if (!clk_hw_data)
908fdc1eb62SRyan Chen 		return -ENOMEM;
909fdc1eb62SRyan Chen 
910fdc1eb62SRyan Chen 	clk_hw_data->num = clk_data->nr_clks;
911fdc1eb62SRyan Chen 	hws = clk_hw_data->hws;
912fdc1eb62SRyan Chen 
913fdc1eb62SRyan Chen 	if (clk_data->scu)
914fdc1eb62SRyan Chen 		ast2700_soc1_configure_i3c_clk(clk_ctrl);
915fdc1eb62SRyan Chen 
916fdc1eb62SRyan Chen 	for (i = 0; i < clk_data->nr_clks; i++) {
917fdc1eb62SRyan Chen 		const struct ast2700_clk_info *clk = &clk_data->clk_info[i];
918fdc1eb62SRyan Chen 		const struct clk_hw *phw = NULL;
919fdc1eb62SRyan Chen 		unsigned int id = clk->id;
920fdc1eb62SRyan Chen 		void __iomem *reg = NULL;
921fdc1eb62SRyan Chen 
922fdc1eb62SRyan Chen 		if (id >= clk_hw_data->num || hws[id]) {
923fdc1eb62SRyan Chen 			dev_err(dev, "clk id %u invalid for %s\n", id, clk->name);
924fdc1eb62SRyan Chen 			return -EINVAL;
925fdc1eb62SRyan Chen 		}
926fdc1eb62SRyan Chen 
927fdc1eb62SRyan Chen 		if (clk->type == CLK_FIXED) {
928fdc1eb62SRyan Chen 			const struct ast2700_clk_fixed_rate_data *fixed_rate = &clk->data.rate;
929fdc1eb62SRyan Chen 
930fdc1eb62SRyan Chen 			hws[id] = devm_clk_hw_register_fixed_rate(dev, clk->name, NULL, 0,
931fdc1eb62SRyan Chen 								  fixed_rate->fixed_rate);
932fdc1eb62SRyan Chen 		} else if (clk->type == CLK_FIXED_FACTOR) {
933fdc1eb62SRyan Chen 			const struct ast2700_clk_fixed_factor_data *factor = &clk->data.factor;
934fdc1eb62SRyan Chen 
935fdc1eb62SRyan Chen 			phw = hws[factor->parent_id];
936fdc1eb62SRyan Chen 			hws[id] = devm_clk_hw_register_fixed_factor_parent_hw(dev, clk->name,
937fdc1eb62SRyan Chen 									      phw, 0, factor->mult,
938fdc1eb62SRyan Chen 									      factor->div);
939fdc1eb62SRyan Chen 		} else if (clk->type == CLK_FIXED_DISPLAY) {
940fdc1eb62SRyan Chen 			reg = clk_ctrl->base + clk->data.display_rate.reg;
941fdc1eb62SRyan Chen 
942fdc1eb62SRyan Chen 			hws[id] = ast2700_clk_hw_register_fixed_display(reg, clk->name, clk_ctrl);
943fdc1eb62SRyan Chen 		} else if (clk->type == CLK_HPLL) {
944fdc1eb62SRyan Chen 			const struct ast2700_clk_pll_data *pll = &clk->data.pll;
945fdc1eb62SRyan Chen 
946fdc1eb62SRyan Chen 			reg = clk_ctrl->base + pll->reg;
947fdc1eb62SRyan Chen 			phw = hws[pll->parent_id];
948fdc1eb62SRyan Chen 			hws[id] = ast2700_clk_hw_register_hpll(reg, clk->name, phw, clk_ctrl);
949fdc1eb62SRyan Chen 		} else if (clk->type == CLK_PLL) {
950fdc1eb62SRyan Chen 			const struct ast2700_clk_pll_data *pll = &clk->data.pll;
951fdc1eb62SRyan Chen 
952fdc1eb62SRyan Chen 			reg = clk_ctrl->base + pll->reg;
953fdc1eb62SRyan Chen 			phw = hws[pll->parent_id];
954fdc1eb62SRyan Chen 			hws[id] = ast2700_clk_hw_register_pll(id, reg, clk->name, phw, clk_ctrl);
955fdc1eb62SRyan Chen 		} else if (clk->type == CLK_UART_PLL) {
956fdc1eb62SRyan Chen 			const struct ast2700_clk_pll_data *pll = &clk->data.pll;
957fdc1eb62SRyan Chen 
958fdc1eb62SRyan Chen 			reg = clk_ctrl->base + pll->reg;
959fdc1eb62SRyan Chen 			phw = hws[pll->parent_id];
960fdc1eb62SRyan Chen 			hws[id] = ast2700_clk_hw_register_uartpll(reg, clk->name, phw, clk_ctrl);
961fdc1eb62SRyan Chen 		} else if (clk->type == CLK_MUX) {
962fdc1eb62SRyan Chen 			const struct ast2700_clk_mux_data *mux = &clk->data.mux;
963fdc1eb62SRyan Chen 
964fdc1eb62SRyan Chen 			reg = clk_ctrl->base + mux->reg;
965fdc1eb62SRyan Chen 			for (int j = 0; j < mux->num_parents; j++) {
966fdc1eb62SRyan Chen 				unsigned int pid = mux->parent_ids[j];
967fdc1eb62SRyan Chen 
968fdc1eb62SRyan Chen 				mux->parent_hws[j] = hws[pid];
969fdc1eb62SRyan Chen 			}
970fdc1eb62SRyan Chen 
971fdc1eb62SRyan Chen 			hws[id] = devm_clk_hw_register_mux_parent_hws(dev, clk->name,
972fdc1eb62SRyan Chen 								      mux->parent_hws,
973fdc1eb62SRyan Chen 								      mux->num_parents, 0,
974fdc1eb62SRyan Chen 								      reg, mux->bit_shift,
975fdc1eb62SRyan Chen 								      mux->bit_width, 0,
976fdc1eb62SRyan Chen 								      &clk_ctrl->lock);
977fdc1eb62SRyan Chen 		} else if (clk->type == CLK_MISC) {
978fdc1eb62SRyan Chen 			const struct ast2700_clk_pll_data *pll = &clk->data.pll;
979fdc1eb62SRyan Chen 
980fdc1eb62SRyan Chen 			reg = clk_ctrl->base + pll->reg;
981fdc1eb62SRyan Chen 			phw = hws[pll->parent_id];
982fdc1eb62SRyan Chen 			hws[id] = ast2700_clk_hw_register_misc(id, reg, clk->name, phw, clk_ctrl);
983fdc1eb62SRyan Chen 		} else if (clk->type == CLK_DIVIDER) {
984fdc1eb62SRyan Chen 			const struct ast2700_clk_div_data *divider = &clk->data.div;
985fdc1eb62SRyan Chen 
986fdc1eb62SRyan Chen 			reg = clk_ctrl->base + divider->reg;
987fdc1eb62SRyan Chen 			phw = hws[divider->parent_id];
988fdc1eb62SRyan Chen 			hws[id] = clk_hw_register_divider_table_parent_hw(dev, clk->name,
989fdc1eb62SRyan Chen 									  phw,
990fdc1eb62SRyan Chen 									  0, reg,
991fdc1eb62SRyan Chen 									  divider->bit_shift,
992fdc1eb62SRyan Chen 									  divider->bit_width, 0,
993fdc1eb62SRyan Chen 									  divider->div_table,
994fdc1eb62SRyan Chen 									  &clk_ctrl->lock);
995fdc1eb62SRyan Chen 		} else if (clk->type == CLK_GATE_ASPEED) {
996fdc1eb62SRyan Chen 			const struct ast2700_clk_gate_data *gate = &clk->data.gate;
997fdc1eb62SRyan Chen 
998fdc1eb62SRyan Chen 			phw = get_parent_hw_or_null(hws, gate->parent_id);
999fdc1eb62SRyan Chen 			reg = clk_ctrl->base + gate->reg;
1000fdc1eb62SRyan Chen 			hws[id] = ast2700_clk_hw_register_gate(dev, clk->name, phw, reg, gate->bit,
1001fdc1eb62SRyan Chen 							       gate->flags, &clk_ctrl->lock);
1002fdc1eb62SRyan Chen 		} else {
1003fdc1eb62SRyan Chen 			const struct ast2700_clk_gate_data *gate = &clk->data.gate;
1004fdc1eb62SRyan Chen 
1005fdc1eb62SRyan Chen 			phw = get_parent_hw_or_null(hws, gate->parent_id);
1006fdc1eb62SRyan Chen 			reg = clk_ctrl->base + gate->reg;
1007fdc1eb62SRyan Chen 			hws[id] = devm_clk_hw_register_gate_parent_hw(dev, clk->name, phw,
1008fdc1eb62SRyan Chen 								      gate->flags, reg, gate->bit,
1009fdc1eb62SRyan Chen 								      0, &clk_ctrl->lock);
1010fdc1eb62SRyan Chen 		}
1011fdc1eb62SRyan Chen 
1012fdc1eb62SRyan Chen 		if (IS_ERR(hws[id]))
1013fdc1eb62SRyan Chen 			return PTR_ERR(hws[id]);
1014fdc1eb62SRyan Chen 	}
1015fdc1eb62SRyan Chen 
1016fdc1eb62SRyan Chen 	ret = devm_of_clk_add_hw_provider(dev, of_clk_hw_onecell_get, clk_hw_data);
1017fdc1eb62SRyan Chen 	if (ret)
1018fdc1eb62SRyan Chen 		return ret;
1019fdc1eb62SRyan Chen 
1020fdc1eb62SRyan Chen 	adev = devm_auxiliary_device_create(dev, reset_name, (__force void *)clk_base);
1021fdc1eb62SRyan Chen 	if (!adev)
1022fdc1eb62SRyan Chen 		return -ENODEV;
1023fdc1eb62SRyan Chen 
1024fdc1eb62SRyan Chen 	return 0;
1025fdc1eb62SRyan Chen }
1026fdc1eb62SRyan Chen 
1027fdc1eb62SRyan Chen static const struct ast2700_clk_data ast2700_clk0_data = {
1028fdc1eb62SRyan Chen 	.scu = 0,
1029fdc1eb62SRyan Chen 	.nr_clks = ARRAY_SIZE(ast2700_scu0_clk_info),
1030fdc1eb62SRyan Chen 	.clk_info = ast2700_scu0_clk_info,
1031fdc1eb62SRyan Chen };
1032fdc1eb62SRyan Chen 
1033fdc1eb62SRyan Chen static const struct ast2700_clk_data ast2700_clk1_data = {
1034fdc1eb62SRyan Chen 	.scu = 1,
1035fdc1eb62SRyan Chen 	.nr_clks = ARRAY_SIZE(ast2700_scu1_clk_info),
1036fdc1eb62SRyan Chen 	.clk_info = ast2700_scu1_clk_info,
1037fdc1eb62SRyan Chen };
1038fdc1eb62SRyan Chen 
1039fdc1eb62SRyan Chen static const struct of_device_id ast2700_scu_match[] = {
1040fdc1eb62SRyan Chen 	{ .compatible = "aspeed,ast2700-scu0", .data = &ast2700_clk0_data },
1041fdc1eb62SRyan Chen 	{ .compatible = "aspeed,ast2700-scu1", .data = &ast2700_clk1_data },
1042fdc1eb62SRyan Chen 	{ /* sentinel */ }
1043fdc1eb62SRyan Chen };
1044fdc1eb62SRyan Chen 
1045fdc1eb62SRyan Chen MODULE_DEVICE_TABLE(of, ast2700_scu_match);
1046fdc1eb62SRyan Chen 
1047fdc1eb62SRyan Chen static struct platform_driver ast2700_scu_driver = {
1048fdc1eb62SRyan Chen 	.probe = ast2700_soc_clk_probe,
1049fdc1eb62SRyan Chen 	.driver = {
1050fdc1eb62SRyan Chen 		.name = "clk-ast2700",
1051fdc1eb62SRyan Chen 		.of_match_table = ast2700_scu_match,
1052fdc1eb62SRyan Chen 	},
1053fdc1eb62SRyan Chen };
1054fdc1eb62SRyan Chen 
1055fdc1eb62SRyan Chen module_platform_driver(ast2700_scu_driver);
1056