xref: /openbmc/linux/drivers/clk/nuvoton/clk-ma35d1.c (revision 6e3edb0f)
1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3  * Copyright (C) 2023 Nuvoton Technology Corp.
4  * Author: Chi-Fang Li <cfli0@nuvoton.com>
5  */
6 
7 #include <linux/clk-provider.h>
8 #include <linux/mfd/syscon.h>
9 #include <linux/module.h>
10 #include <linux/of.h>
11 #include <linux/platform_device.h>
12 #include <linux/spinlock.h>
13 #include <dt-bindings/clock/nuvoton,ma35d1-clk.h>
14 
15 #include "clk-ma35d1.h"
16 
17 static DEFINE_SPINLOCK(ma35d1_lock);
18 
19 #define PLL_MAX_NUM		5
20 
21 /* Clock Control Registers Offset */
22 #define REG_CLK_PWRCTL		0x00
23 #define REG_CLK_SYSCLK0		0x04
24 #define REG_CLK_SYSCLK1		0x08
25 #define REG_CLK_APBCLK0		0x0c
26 #define REG_CLK_APBCLK1		0x10
27 #define REG_CLK_APBCLK2		0x14
28 #define REG_CLK_CLKSEL0		0x18
29 #define REG_CLK_CLKSEL1		0x1c
30 #define REG_CLK_CLKSEL2		0x20
31 #define REG_CLK_CLKSEL3		0x24
32 #define REG_CLK_CLKSEL4		0x28
33 #define REG_CLK_CLKDIV0		0x2c
34 #define REG_CLK_CLKDIV1		0x30
35 #define REG_CLK_CLKDIV2		0x34
36 #define REG_CLK_CLKDIV3		0x38
37 #define REG_CLK_CLKDIV4		0x3c
38 #define REG_CLK_CLKOCTL		0x40
39 #define REG_CLK_STATUS		0x50
40 #define REG_CLK_PLL0CTL0	0x60
41 #define REG_CLK_PLL2CTL0	0x80
42 #define REG_CLK_PLL2CTL1	0x84
43 #define REG_CLK_PLL2CTL2	0x88
44 #define REG_CLK_PLL3CTL0	0x90
45 #define REG_CLK_PLL3CTL1	0x94
46 #define REG_CLK_PLL3CTL2	0x98
47 #define REG_CLK_PLL4CTL0	0xa0
48 #define REG_CLK_PLL4CTL1	0xa4
49 #define REG_CLK_PLL4CTL2	0xa8
50 #define REG_CLK_PLL5CTL0	0xb0
51 #define REG_CLK_PLL5CTL1	0xb4
52 #define REG_CLK_PLL5CTL2	0xb8
53 #define REG_CLK_CLKDCTL		0xc0
54 #define REG_CLK_CLKDSTS		0xc4
55 #define REG_CLK_CDUPB		0xc8
56 #define REG_CLK_CDLOWB		0xcc
57 #define REG_CLK_CKFLTRCTL	0xd0
58 #define REG_CLK_TESTCLK		0xf0
59 #define REG_CLK_PLLCTL		0x40
60 
61 #define PLL_MODE_INT            0
62 #define PLL_MODE_FRAC           1
63 #define PLL_MODE_SS             2
64 
65 static const struct clk_parent_data ca35clk_sel_clks[] = {
66 	{ .fw_name = "hxt", },
67 	{ .fw_name = "capll", },
68 	{ .fw_name = "ddrpll", },
69 };
70 
71 static const struct clk_parent_data sysclk0_sel_clks[] = {
72 	{ .fw_name = "epll_div2", },
73 	{ .fw_name = "syspll", },
74 };
75 
76 static const struct clk_parent_data sysclk1_sel_clks[] = {
77 	{ .fw_name = "hxt", },
78 	{ .fw_name = "syspll", },
79 };
80 
81 static const struct clk_parent_data axiclk_sel_clks[] = {
82 	{ .fw_name = "capll_div2", },
83 	{ .fw_name = "capll_div4", },
84 };
85 
86 static const struct clk_parent_data ccap_sel_clks[] = {
87 	{ .fw_name = "hxt", },
88 	{ .fw_name = "vpll", },
89 	{ .fw_name = "apll", },
90 	{ .fw_name = "syspll", },
91 };
92 
93 static const struct clk_parent_data sdh_sel_clks[] = {
94 	{ .fw_name = "syspll", },
95 	{ .fw_name = "apll", },
96 };
97 
98 static const struct clk_parent_data dcu_sel_clks[] = {
99 	{ .fw_name = "epll_div2", },
100 	{ .fw_name = "syspll", },
101 };
102 
103 static const struct clk_parent_data gfx_sel_clks[] = {
104 	{ .fw_name = "epll", },
105 	{ .fw_name = "syspll", },
106 };
107 
108 static const struct clk_parent_data dbg_sel_clks[] = {
109 	{ .fw_name = "hirc", },
110 	{ .fw_name = "syspll", },
111 };
112 
113 static const struct clk_parent_data timer0_sel_clks[] = {
114 	{ .fw_name = "hxt", },
115 	{ .fw_name = "lxt", },
116 	{ .fw_name = "pclk0", },
117 	{ .index = -1, },
118 	{ .index = -1, },
119 	{ .fw_name = "lirc", },
120 	{ .index = -1, },
121 	{ .fw_name = "hirc", },
122 };
123 
124 static const struct clk_parent_data timer1_sel_clks[] = {
125 	{ .fw_name = "hxt", },
126 	{ .fw_name = "lxt", },
127 	{ .fw_name = "pclk0", },
128 	{ .index = -1, },
129 	{ .index = -1, },
130 	{ .fw_name = "lirc", },
131 	{ .index = -1, },
132 	{ .fw_name = "hirc", },
133 };
134 
135 static const struct clk_parent_data timer2_sel_clks[] = {
136 	{ .fw_name = "hxt", },
137 	{ .fw_name = "lxt", },
138 	{ .fw_name = "pclk1", },
139 	{ .index = -1, },
140 	{ .index = -1, },
141 	{ .fw_name = "lirc", },
142 	{ .index = -1, },
143 	{ .fw_name = "hirc", },
144 };
145 
146 static const struct clk_parent_data timer3_sel_clks[] = {
147 	{ .fw_name = "hxt", },
148 	{ .fw_name = "lxt", },
149 	{ .fw_name = "pclk1", },
150 	{ .index = -1, },
151 	{ .index = -1, },
152 	{ .fw_name = "lirc", },
153 	{ .index = -1, },
154 	{ .fw_name = "hirc", },
155 };
156 
157 static const struct clk_parent_data timer4_sel_clks[] = {
158 	{ .fw_name = "hxt", },
159 	{ .fw_name = "lxt", },
160 	{ .fw_name = "pclk2", },
161 	{ .index = -1, },
162 	{ .index = -1, },
163 	{ .fw_name = "lirc", },
164 	{ .index = -1, },
165 	{ .fw_name = "hirc", },
166 };
167 
168 static const struct clk_parent_data timer5_sel_clks[] = {
169 	{ .fw_name = "hxt", },
170 	{ .fw_name = "lxt", },
171 	{ .fw_name = "pclk2", },
172 	{ .index = -1, },
173 	{ .index = -1, },
174 	{ .fw_name = "lirc", },
175 	{ .index = -1, },
176 	{ .fw_name = "hirc", },
177 };
178 
179 static const struct clk_parent_data timer6_sel_clks[] = {
180 	{ .fw_name = "hxt", },
181 	{ .fw_name = "lxt", },
182 	{ .fw_name = "pclk0", },
183 	{ .index = -1, },
184 	{ .index = -1, },
185 	{ .fw_name = "lirc", },
186 	{ .index = -1, },
187 	{ .fw_name = "hirc", },
188 };
189 
190 static const struct clk_parent_data timer7_sel_clks[] = {
191 	{ .fw_name = "hxt", },
192 	{ .fw_name = "lxt", },
193 	{ .fw_name = "pclk0", },
194 	{ .index = -1, },
195 	{ .index = -1, },
196 	{ .fw_name = "lirc", },
197 	{ .index = -1, },
198 	{ .fw_name = "hirc", },
199 };
200 
201 static const struct clk_parent_data timer8_sel_clks[] = {
202 	{ .fw_name = "hxt", },
203 	{ .fw_name = "lxt", },
204 	{ .fw_name = "pclk1", },
205 	{ .index = -1, },
206 	{ .index = -1, },
207 	{ .fw_name = "lirc", },
208 	{ .index = -1, },
209 	{ .fw_name = "hirc", },
210 };
211 
212 static const struct clk_parent_data timer9_sel_clks[] = {
213 	{ .fw_name = "hxt", },
214 	{ .fw_name = "lxt", },
215 	{ .fw_name = "pclk1", },
216 	{ .index = -1, },
217 	{ .index = -1, },
218 	{ .fw_name = "lirc", },
219 	{ .index = -1, },
220 	{ .fw_name = "hirc", },
221 };
222 
223 static const struct clk_parent_data timer10_sel_clks[] = {
224 	{ .fw_name = "hxt", },
225 	{ .fw_name = "lxt", },
226 	{ .fw_name = "pclk2", },
227 	{ .index = -1, },
228 	{ .index = -1, },
229 	{ .fw_name = "lirc", },
230 	{ .index = -1, },
231 	{ .fw_name = "hirc", },
232 };
233 
234 static const struct clk_parent_data timer11_sel_clks[] = {
235 	{ .fw_name = "hxt", },
236 	{ .fw_name = "lxt", },
237 	{ .fw_name = "pclk2", },
238 	{ .index = -1, },
239 	{ .index = -1, },
240 	{ .fw_name = "lirc", },
241 	{ .index = -1, },
242 	{ .fw_name = "hirc", },
243 };
244 
245 static const struct clk_parent_data uart_sel_clks[] = {
246 	{ .fw_name = "hxt", },
247 	{ .fw_name = "sysclk1_div2", },
248 };
249 
250 static const struct clk_parent_data wdt0_sel_clks[] = {
251 	{ .index = -1, },
252 	{ .fw_name = "lxt", },
253 	{ .fw_name = "pclk3_div4096", },
254 	{ .fw_name = "lirc", },
255 };
256 
257 static const struct clk_parent_data wdt1_sel_clks[] = {
258 	{ .index = -1, },
259 	{ .fw_name = "lxt", },
260 	{ .fw_name = "pclk3_div4096", },
261 	{ .fw_name = "lirc", },
262 };
263 
264 static const struct clk_parent_data wdt2_sel_clks[] = {
265 	{ .index = -1, },
266 	{ .fw_name = "lxt", },
267 	{ .fw_name = "pclk4_div4096", },
268 	{ .fw_name = "lirc", },
269 };
270 
271 static const struct clk_parent_data wwdt0_sel_clks[] = {
272 	{ .index = -1, },
273 	{ .index = -1, },
274 	{ .fw_name = "pclk3_div4096", },
275 	{ .fw_name = "lirc", },
276 };
277 
278 static const struct clk_parent_data wwdt1_sel_clks[] = {
279 	{ .index = -1, },
280 	{ .index = -1, },
281 	{ .fw_name = "pclk3_div4096", },
282 	{ .fw_name = "lirc", },
283 };
284 
285 static const struct clk_parent_data wwdt2_sel_clks[] = {
286 	{ .index = -1, },
287 	{ .index = -1, },
288 	{ .fw_name = "pclk4_div4096", },
289 	{ .fw_name = "lirc", },
290 };
291 
292 static const struct clk_parent_data spi0_sel_clks[] = {
293 	{ .fw_name = "pclk1", },
294 	{ .fw_name = "apll", },
295 };
296 
297 static const struct clk_parent_data spi1_sel_clks[] = {
298 	{ .fw_name = "pclk2", },
299 	{ .fw_name = "apll", },
300 };
301 
302 static const struct clk_parent_data spi2_sel_clks[] = {
303 	{ .fw_name = "pclk1", },
304 	{ .fw_name = "apll", },
305 };
306 
307 static const struct clk_parent_data spi3_sel_clks[] = {
308 	{ .fw_name = "pclk2", },
309 	{ .fw_name = "apll", },
310 };
311 
312 static const struct clk_parent_data qspi0_sel_clks[] = {
313 	{ .fw_name = "pclk0", },
314 	{ .fw_name = "apll", },
315 };
316 
317 static const struct clk_parent_data qspi1_sel_clks[] = {
318 	{ .fw_name = "pclk0", },
319 	{ .fw_name = "apll", },
320 };
321 
322 static const struct clk_parent_data i2s0_sel_clks[] = {
323 	{ .fw_name = "apll", },
324 	{ .fw_name = "sysclk1_div2", },
325 };
326 
327 static const struct clk_parent_data i2s1_sel_clks[] = {
328 	{ .fw_name = "apll", },
329 	{ .fw_name = "sysclk1_div2", },
330 };
331 
332 static const struct clk_parent_data can_sel_clks[] = {
333 	{ .fw_name = "apll", },
334 	{ .fw_name = "vpll", },
335 };
336 
337 static const struct clk_parent_data cko_sel_clks[] = {
338 	{ .fw_name = "hxt", },
339 	{ .fw_name = "lxt", },
340 	{ .fw_name = "hirc", },
341 	{ .fw_name = "lirc", },
342 	{ .fw_name = "capll_div4", },
343 	{ .fw_name = "syspll", },
344 	{ .fw_name = "ddrpll", },
345 	{ .fw_name = "epll_div2", },
346 	{ .fw_name = "apll", },
347 	{ .fw_name = "vpll", },
348 };
349 
350 static const struct clk_parent_data smc_sel_clks[] = {
351 	{ .fw_name = "hxt", },
352 	{ .fw_name = "pclk4", },
353 };
354 
355 static const struct clk_parent_data kpi_sel_clks[] = {
356 	{ .fw_name = "hxt", },
357 	{ .fw_name = "lxt", },
358 };
359 
360 static const struct clk_div_table ip_div_table[] = {
361 	{0, 2}, {1, 4}, {2, 6}, {3, 8}, {4, 10},
362 	{5, 12}, {6, 14}, {7, 16}, {0, 0},
363 };
364 
365 static const struct clk_div_table eadc_div_table[] = {
366 	{0, 2}, {1, 4}, {2, 6}, {3, 8}, {4, 10},
367 	{5, 12}, {6, 14}, {7, 16}, {8, 18},
368 	{9, 20}, {10, 22}, {11, 24}, {12, 26},
369 	{13, 28}, {14, 30}, {15, 32}, {0, 0},
370 };
371 
372 static struct clk_hw *ma35d1_clk_fixed(const char *name, int rate)
373 {
374 	return clk_hw_register_fixed_rate(NULL, name, NULL, 0, rate);
375 }
376 
377 static struct clk_hw *ma35d1_clk_mux_parent(struct device *dev, const char *name,
378 					    void __iomem *reg, u8 shift, u8 width,
379 					    const struct clk_parent_data *pdata,
380 					    int num_pdata)
381 {
382 	return clk_hw_register_mux_parent_data(dev, name, pdata, num_pdata,
383 					       CLK_SET_RATE_NO_REPARENT, reg, shift,
384 					       width, 0, &ma35d1_lock);
385 }
386 
387 static struct clk_hw *ma35d1_clk_mux(struct device *dev, const char *name,
388 				     void __iomem *reg, u8 shift, u8 width,
389 				     const struct clk_parent_data *pdata,
390 				     int num_pdata)
391 {
392 	return clk_hw_register_mux_parent_data(dev, name, pdata, num_pdata,
393 					       CLK_SET_RATE_NO_REPARENT, reg, shift,
394 					       width, 0, &ma35d1_lock);
395 }
396 
397 static struct clk_hw *ma35d1_clk_divider(struct device *dev, const char *name,
398 					 const char *parent, void __iomem *reg,
399 					 u8 shift, u8 width)
400 {
401 	return devm_clk_hw_register_divider(dev, name, parent, CLK_SET_RATE_PARENT,
402 					    reg, shift, width, 0, &ma35d1_lock);
403 }
404 
405 static struct clk_hw *ma35d1_clk_divider_pow2(struct device *dev, const char *name,
406 					      const char *parent, void __iomem *reg,
407 					      u8 shift, u8 width)
408 {
409 	return devm_clk_hw_register_divider(dev, name, parent,
410 					    CLK_DIVIDER_POWER_OF_TWO, reg, shift,
411 					    width, 0, &ma35d1_lock);
412 }
413 
414 static struct clk_hw *ma35d1_clk_divider_table(struct device *dev, const char *name,
415 					       const char *parent, void __iomem *reg,
416 					       u8 shift, u8 width,
417 					       const struct clk_div_table *table)
418 {
419 	return devm_clk_hw_register_divider_table(dev, name, parent, 0,
420 						  reg, shift, width, 0,
421 						  table, &ma35d1_lock);
422 }
423 
424 static struct clk_hw *ma35d1_clk_fixed_factor(struct device *dev, const char *name,
425 					      const char *parent, unsigned int mult,
426 					      unsigned int div)
427 {
428 	return devm_clk_hw_register_fixed_factor(dev, name, parent,
429 					    CLK_SET_RATE_PARENT, mult, div);
430 }
431 
432 static struct clk_hw *ma35d1_clk_gate(struct device *dev, const char *name, const char *parent,
433 				      void __iomem *reg, u8 shift)
434 {
435 	return devm_clk_hw_register_gate(dev, name, parent, CLK_SET_RATE_PARENT,
436 				    reg, shift, 0, &ma35d1_lock);
437 }
438 
439 static int ma35d1_get_pll_setting(struct device_node *clk_node, u32 *pllmode)
440 {
441 	const char *of_str;
442 	int i;
443 
444 	for (i = 0; i < PLL_MAX_NUM; i++) {
445 		if (of_property_read_string_index(clk_node, "nuvoton,pll-mode", i, &of_str))
446 			return -EINVAL;
447 		if (!strcmp(of_str, "integer"))
448 			pllmode[i] = PLL_MODE_INT;
449 		else if (!strcmp(of_str, "fractional"))
450 			pllmode[i] = PLL_MODE_FRAC;
451 		else if (!strcmp(of_str, "spread-spectrum"))
452 			pllmode[i] = PLL_MODE_SS;
453 		else
454 			return -EINVAL;
455 	}
456 	return 0;
457 }
458 
459 static int ma35d1_clocks_probe(struct platform_device *pdev)
460 {
461 	struct device *dev = &pdev->dev;
462 	struct device_node *clk_node = pdev->dev.of_node;
463 	struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
464 	void __iomem *clk_base;
465 	static struct clk_hw **hws;
466 	static struct clk_hw_onecell_data *ma35d1_hw_data;
467 	u32 pllmode[PLL_MAX_NUM];
468 	int ret;
469 
470 	ma35d1_hw_data = devm_kzalloc(dev,
471 				      struct_size(ma35d1_hw_data, hws, CLK_MAX_IDX),
472 				      GFP_KERNEL);
473 	if (!ma35d1_hw_data)
474 		return -ENOMEM;
475 
476 	ma35d1_hw_data->num = CLK_MAX_IDX;
477 	hws = ma35d1_hw_data->hws;
478 
479 	clk_base = devm_ioremap_resource(dev, res);
480 	if (IS_ERR(clk_base))
481 		return PTR_ERR(clk_base);
482 
483 	ret = ma35d1_get_pll_setting(clk_node, pllmode);
484 	if (ret < 0) {
485 		dev_err(dev, "Invalid PLL setting!\n");
486 		return -EINVAL;
487 	}
488 
489 	hws[HXT] = ma35d1_clk_fixed("hxt", 24000000);
490 	hws[HXT_GATE] = ma35d1_clk_gate(dev, "hxt_gate", "hxt",
491 					clk_base + REG_CLK_PWRCTL, 0);
492 	hws[LXT] = ma35d1_clk_fixed("lxt", 32768);
493 	hws[LXT_GATE] = ma35d1_clk_gate(dev, "lxt_gate", "lxt",
494 					clk_base + REG_CLK_PWRCTL, 1);
495 	hws[HIRC] = ma35d1_clk_fixed("hirc", 12000000);
496 	hws[HIRC_GATE] = ma35d1_clk_gate(dev, "hirc_gate", "hirc",
497 					 clk_base + REG_CLK_PWRCTL, 2);
498 	hws[LIRC] = ma35d1_clk_fixed("lirc", 32000);
499 	hws[LIRC_GATE] = ma35d1_clk_gate(dev, "lirc_gate", "lirc",
500 					 clk_base + REG_CLK_PWRCTL, 3);
501 
502 	hws[CAPLL] = ma35d1_reg_clk_pll(dev, CAPLL, pllmode[0], "capll",
503 					hws[HXT], clk_base + REG_CLK_PLL0CTL0);
504 	hws[SYSPLL] = ma35d1_clk_fixed("syspll", 180000000);
505 	hws[DDRPLL] = ma35d1_reg_clk_pll(dev, DDRPLL, pllmode[1], "ddrpll",
506 					hws[HXT], clk_base + REG_CLK_PLL2CTL0);
507 	hws[APLL] = ma35d1_reg_clk_pll(dev, APLL, pllmode[2], "apll",
508 				       hws[HXT], clk_base + REG_CLK_PLL3CTL0);
509 	hws[EPLL] = ma35d1_reg_clk_pll(dev, EPLL, pllmode[3], "epll",
510 				       hws[HXT], clk_base + REG_CLK_PLL4CTL0);
511 	hws[VPLL] = ma35d1_reg_clk_pll(dev, VPLL, pllmode[4], "vpll",
512 				       hws[HXT], clk_base + REG_CLK_PLL5CTL0);
513 
514 	hws[EPLL_DIV2] = ma35d1_clk_fixed_factor(dev, "epll_div2", "epll", 1, 2);
515 	hws[EPLL_DIV4] = ma35d1_clk_fixed_factor(dev, "epll_div4", "epll", 1, 4);
516 	hws[EPLL_DIV8] = ma35d1_clk_fixed_factor(dev, "epll_div8", "epll", 1, 8);
517 
518 	hws[CA35CLK_MUX] = ma35d1_clk_mux_parent(dev, "ca35clk_mux",
519 						 clk_base + REG_CLK_CLKSEL0, 0, 2,
520 						 ca35clk_sel_clks,
521 						 ARRAY_SIZE(ca35clk_sel_clks));
522 	hws[AXICLK_DIV2] = ma35d1_clk_fixed_factor(dev, "capll_div2", "ca35clk_mux", 1, 2);
523 	hws[AXICLK_DIV4] = ma35d1_clk_fixed_factor(dev, "capll_div4", "ca35clk_mux", 1, 4);
524 
525 	hws[AXICLK_MUX] = ma35d1_clk_mux(dev, "axiclk_mux", clk_base + REG_CLK_CLKDIV0,
526 					 26, 1, axiclk_sel_clks,
527 					 ARRAY_SIZE(axiclk_sel_clks));
528 	hws[SYSCLK0_MUX] = ma35d1_clk_mux(dev, "sysclk0_mux", clk_base + REG_CLK_CLKSEL0,
529 					  2, 1, sysclk0_sel_clks,
530 					  ARRAY_SIZE(sysclk0_sel_clks));
531 	hws[SYSCLK1_MUX] = ma35d1_clk_mux(dev, "sysclk1_mux", clk_base + REG_CLK_CLKSEL0,
532 					  4, 1, sysclk1_sel_clks,
533 					  ARRAY_SIZE(sysclk1_sel_clks));
534 	hws[SYSCLK1_DIV2] = ma35d1_clk_fixed_factor(dev, "sysclk1_div2", "sysclk1_mux", 1, 2);
535 
536 	/* HCLK0~3 & PCLK0~4 */
537 	hws[HCLK0] = ma35d1_clk_fixed_factor(dev, "hclk0", "sysclk1_mux", 1, 1);
538 	hws[HCLK1] = ma35d1_clk_fixed_factor(dev, "hclk1", "sysclk1_mux", 1, 1);
539 	hws[HCLK2] = ma35d1_clk_fixed_factor(dev, "hclk2", "sysclk1_mux", 1, 1);
540 	hws[PCLK0] = ma35d1_clk_fixed_factor(dev, "pclk0", "sysclk1_mux", 1, 1);
541 	hws[PCLK1] = ma35d1_clk_fixed_factor(dev, "pclk1", "sysclk1_mux", 1, 1);
542 	hws[PCLK2] = ma35d1_clk_fixed_factor(dev, "pclk2", "sysclk1_mux", 1, 1);
543 
544 	hws[HCLK3] = ma35d1_clk_fixed_factor(dev, "hclk3", "sysclk1_mux", 1, 2);
545 	hws[PCLK3] = ma35d1_clk_fixed_factor(dev, "pclk3", "sysclk1_mux", 1, 2);
546 	hws[PCLK4] = ma35d1_clk_fixed_factor(dev, "pclk4", "sysclk1_mux", 1, 2);
547 
548 	hws[USBPHY0] = ma35d1_clk_fixed("usbphy0", 480000000);
549 	hws[USBPHY1] = ma35d1_clk_fixed("usbphy1", 480000000);
550 
551 	/* DDR */
552 	hws[DDR0_GATE] = ma35d1_clk_gate(dev, "ddr0_gate", "ddrpll",
553 					 clk_base + REG_CLK_SYSCLK0, 4);
554 	hws[DDR6_GATE] = ma35d1_clk_gate(dev, "ddr6_gate", "ddrpll",
555 					 clk_base + REG_CLK_SYSCLK0, 5);
556 
557 	hws[CAN0_MUX] = ma35d1_clk_mux(dev, "can0_mux", clk_base + REG_CLK_CLKSEL4,
558 				       16, 1, can_sel_clks, ARRAY_SIZE(can_sel_clks));
559 	hws[CAN0_DIV] = ma35d1_clk_divider_table(dev, "can0_div", "can0_mux",
560 						 clk_base + REG_CLK_CLKDIV0,
561 						 0, 3, ip_div_table);
562 	hws[CAN0_GATE] = ma35d1_clk_gate(dev, "can0_gate", "can0_div",
563 					 clk_base + REG_CLK_SYSCLK0, 8);
564 	hws[CAN1_MUX] = ma35d1_clk_mux(dev, "can1_mux", clk_base + REG_CLK_CLKSEL4,
565 				       17, 1, can_sel_clks, ARRAY_SIZE(can_sel_clks));
566 	hws[CAN1_DIV] = ma35d1_clk_divider_table(dev, "can1_div", "can1_mux",
567 						 clk_base + REG_CLK_CLKDIV0,
568 						 4, 3, ip_div_table);
569 	hws[CAN1_GATE] = ma35d1_clk_gate(dev, "can1_gate", "can1_div",
570 					 clk_base + REG_CLK_SYSCLK0, 9);
571 	hws[CAN2_MUX] = ma35d1_clk_mux(dev, "can2_mux", clk_base + REG_CLK_CLKSEL4,
572 				       18, 1, can_sel_clks, ARRAY_SIZE(can_sel_clks));
573 	hws[CAN2_DIV] = ma35d1_clk_divider_table(dev, "can2_div", "can2_mux",
574 						 clk_base + REG_CLK_CLKDIV0,
575 						 8, 3, ip_div_table);
576 	hws[CAN2_GATE] = ma35d1_clk_gate(dev, "can2_gate", "can2_div",
577 					 clk_base + REG_CLK_SYSCLK0, 10);
578 	hws[CAN3_MUX] = ma35d1_clk_mux(dev, "can3_mux", clk_base + REG_CLK_CLKSEL4,
579 				       19, 1, can_sel_clks, ARRAY_SIZE(can_sel_clks));
580 	hws[CAN3_DIV] = ma35d1_clk_divider_table(dev, "can3_div", "can3_mux",
581 						 clk_base + REG_CLK_CLKDIV0,
582 						 12, 3, ip_div_table);
583 	hws[CAN3_GATE] = ma35d1_clk_gate(dev, "can3_gate", "can3_div",
584 					 clk_base + REG_CLK_SYSCLK0, 11);
585 
586 	hws[SDH0_MUX] = ma35d1_clk_mux(dev, "sdh0_mux", clk_base + REG_CLK_CLKSEL0,
587 				       16, 2, sdh_sel_clks, ARRAY_SIZE(sdh_sel_clks));
588 	hws[SDH0_GATE] = ma35d1_clk_gate(dev, "sdh0_gate", "sdh0_mux",
589 					 clk_base + REG_CLK_SYSCLK0, 16);
590 	hws[SDH1_MUX] = ma35d1_clk_mux(dev, "sdh1_mux", clk_base + REG_CLK_CLKSEL0,
591 				       18, 2, sdh_sel_clks, ARRAY_SIZE(sdh_sel_clks));
592 	hws[SDH1_GATE] = ma35d1_clk_gate(dev, "sdh1_gate", "sdh1_mux",
593 					 clk_base + REG_CLK_SYSCLK0, 17);
594 
595 	hws[NAND_GATE] = ma35d1_clk_gate(dev, "nand_gate", "hclk1",
596 					 clk_base + REG_CLK_SYSCLK0, 18);
597 
598 	hws[USBD_GATE] = ma35d1_clk_gate(dev, "usbd_gate", "usbphy0",
599 					 clk_base + REG_CLK_SYSCLK0, 19);
600 	hws[USBH_GATE] = ma35d1_clk_gate(dev, "usbh_gate", "usbphy0",
601 					 clk_base + REG_CLK_SYSCLK0, 20);
602 	hws[HUSBH0_GATE] = ma35d1_clk_gate(dev, "husbh0_gate", "usbphy0",
603 					   clk_base + REG_CLK_SYSCLK0, 21);
604 	hws[HUSBH1_GATE] = ma35d1_clk_gate(dev, "husbh1_gate", "usbphy0",
605 					   clk_base + REG_CLK_SYSCLK0, 22);
606 
607 	hws[GFX_MUX] = ma35d1_clk_mux(dev, "gfx_mux", clk_base + REG_CLK_CLKSEL0,
608 				      26, 1, gfx_sel_clks, ARRAY_SIZE(gfx_sel_clks));
609 	hws[GFX_GATE] = ma35d1_clk_gate(dev, "gfx_gate", "gfx_mux",
610 					clk_base + REG_CLK_SYSCLK0, 24);
611 	hws[VC8K_GATE] = ma35d1_clk_gate(dev, "vc8k_gate", "sysclk0_mux",
612 					 clk_base + REG_CLK_SYSCLK0, 25);
613 	hws[DCU_MUX] = ma35d1_clk_mux(dev, "dcu_mux", clk_base + REG_CLK_CLKSEL0,
614 				      24, 1, dcu_sel_clks, ARRAY_SIZE(dcu_sel_clks));
615 	hws[DCU_GATE] = ma35d1_clk_gate(dev, "dcu_gate", "dcu_mux",
616 					clk_base + REG_CLK_SYSCLK0, 26);
617 	hws[DCUP_DIV] = ma35d1_clk_divider_table(dev, "dcup_div", "vpll",
618 						 clk_base + REG_CLK_CLKDIV0,
619 						 16, 3, ip_div_table);
620 
621 	hws[EMAC0_GATE] = ma35d1_clk_gate(dev, "emac0_gate", "epll_div2",
622 					  clk_base + REG_CLK_SYSCLK0, 27);
623 	hws[EMAC1_GATE] = ma35d1_clk_gate(dev, "emac1_gate", "epll_div2",
624 					  clk_base + REG_CLK_SYSCLK0, 28);
625 
626 	hws[CCAP0_MUX] = ma35d1_clk_mux(dev, "ccap0_mux", clk_base + REG_CLK_CLKSEL0,
627 					12, 1, ccap_sel_clks, ARRAY_SIZE(ccap_sel_clks));
628 	hws[CCAP0_DIV] = ma35d1_clk_divider(dev, "ccap0_div", "ccap0_mux",
629 					    clk_base + REG_CLK_CLKDIV1, 8, 4);
630 	hws[CCAP0_GATE] = ma35d1_clk_gate(dev, "ccap0_gate", "ccap0_div",
631 					  clk_base + REG_CLK_SYSCLK0, 29);
632 	hws[CCAP1_MUX] = ma35d1_clk_mux(dev, "ccap1_mux", clk_base + REG_CLK_CLKSEL0,
633 					14, 1, ccap_sel_clks, ARRAY_SIZE(ccap_sel_clks));
634 	hws[CCAP1_DIV] = ma35d1_clk_divider(dev, "ccap1_div", "ccap1_mux",
635 					    clk_base + REG_CLK_CLKDIV1,
636 					    12, 4);
637 	hws[CCAP1_GATE] = ma35d1_clk_gate(dev, "ccap1_gate", "ccap1_div",
638 					  clk_base + REG_CLK_SYSCLK0, 30);
639 
640 	hws[PDMA0_GATE] = ma35d1_clk_gate(dev, "pdma0_gate", "hclk0",
641 					  clk_base + REG_CLK_SYSCLK1, 0);
642 	hws[PDMA1_GATE] = ma35d1_clk_gate(dev, "pdma1_gate", "hclk0",
643 					  clk_base + REG_CLK_SYSCLK1, 1);
644 	hws[PDMA2_GATE] = ma35d1_clk_gate(dev, "pdma2_gate", "hclk0",
645 					  clk_base + REG_CLK_SYSCLK1, 2);
646 	hws[PDMA3_GATE] = ma35d1_clk_gate(dev, "pdma3_gate", "hclk0",
647 					  clk_base + REG_CLK_SYSCLK1, 3);
648 
649 	hws[WH0_GATE] = ma35d1_clk_gate(dev, "wh0_gate", "hclk0",
650 					clk_base + REG_CLK_SYSCLK1, 4);
651 	hws[WH1_GATE] = ma35d1_clk_gate(dev, "wh1_gate", "hclk0",
652 					clk_base + REG_CLK_SYSCLK1, 5);
653 
654 	hws[HWS_GATE] = ma35d1_clk_gate(dev, "hws_gate", "hclk0",
655 					clk_base + REG_CLK_SYSCLK1, 6);
656 
657 	hws[EBI_GATE] = ma35d1_clk_gate(dev, "ebi_gate", "hclk0",
658 					clk_base + REG_CLK_SYSCLK1, 7);
659 
660 	hws[SRAM0_GATE] = ma35d1_clk_gate(dev, "sram0_gate", "hclk0",
661 					  clk_base + REG_CLK_SYSCLK1, 8);
662 	hws[SRAM1_GATE] = ma35d1_clk_gate(dev, "sram1_gate", "hclk0",
663 					  clk_base + REG_CLK_SYSCLK1, 9);
664 
665 	hws[ROM_GATE] = ma35d1_clk_gate(dev, "rom_gate", "hclk0",
666 					clk_base + REG_CLK_SYSCLK1, 10);
667 
668 	hws[TRA_GATE] = ma35d1_clk_gate(dev, "tra_gate", "hclk0",
669 					clk_base + REG_CLK_SYSCLK1, 11);
670 
671 	hws[DBG_MUX] = ma35d1_clk_mux(dev, "dbg_mux", clk_base + REG_CLK_CLKSEL0,
672 				      27, 1, dbg_sel_clks, ARRAY_SIZE(dbg_sel_clks));
673 	hws[DBG_GATE] = ma35d1_clk_gate(dev, "dbg_gate", "hclk0",
674 					clk_base + REG_CLK_SYSCLK1, 12);
675 
676 	hws[CKO_MUX] = ma35d1_clk_mux(dev, "cko_mux", clk_base + REG_CLK_CLKSEL4,
677 				      24, 4, cko_sel_clks, ARRAY_SIZE(cko_sel_clks));
678 	hws[CKO_DIV] = ma35d1_clk_divider_pow2(dev, "cko_div", "cko_mux",
679 					       clk_base + REG_CLK_CLKOCTL, 0, 4);
680 	hws[CKO_GATE] = ma35d1_clk_gate(dev, "cko_gate", "cko_div",
681 					clk_base + REG_CLK_SYSCLK1, 13);
682 
683 	hws[GTMR_GATE] = ma35d1_clk_gate(dev, "gtmr_gate", "hirc",
684 					 clk_base + REG_CLK_SYSCLK1, 14);
685 
686 	hws[GPA_GATE] = ma35d1_clk_gate(dev, "gpa_gate", "hclk0",
687 					clk_base + REG_CLK_SYSCLK1, 16);
688 	hws[GPB_GATE] = ma35d1_clk_gate(dev, "gpb_gate", "hclk0",
689 					clk_base + REG_CLK_SYSCLK1, 17);
690 	hws[GPC_GATE] = ma35d1_clk_gate(dev, "gpc_gate", "hclk0",
691 					clk_base + REG_CLK_SYSCLK1, 18);
692 	hws[GPD_GATE] = ma35d1_clk_gate(dev, "gpd_gate", "hclk0",
693 					clk_base + REG_CLK_SYSCLK1, 19);
694 	hws[GPE_GATE] = ma35d1_clk_gate(dev, "gpe_gate", "hclk0",
695 					clk_base + REG_CLK_SYSCLK1, 20);
696 	hws[GPF_GATE] = ma35d1_clk_gate(dev, "gpf_gate", "hclk0",
697 					clk_base + REG_CLK_SYSCLK1, 21);
698 	hws[GPG_GATE] = ma35d1_clk_gate(dev, "gpg_gate", "hclk0",
699 					clk_base + REG_CLK_SYSCLK1, 22);
700 	hws[GPH_GATE] = ma35d1_clk_gate(dev, "gph_gate", "hclk0",
701 					clk_base + REG_CLK_SYSCLK1, 23);
702 	hws[GPI_GATE] = ma35d1_clk_gate(dev, "gpi_gate", "hclk0",
703 					clk_base + REG_CLK_SYSCLK1, 24);
704 	hws[GPJ_GATE] = ma35d1_clk_gate(dev, "gpj_gate", "hclk0",
705 					clk_base + REG_CLK_SYSCLK1, 25);
706 	hws[GPK_GATE] = ma35d1_clk_gate(dev, "gpk_gate", "hclk0",
707 					clk_base + REG_CLK_SYSCLK1, 26);
708 	hws[GPL_GATE] = ma35d1_clk_gate(dev, "gpl_gate", "hclk0",
709 					clk_base + REG_CLK_SYSCLK1, 27);
710 	hws[GPM_GATE] = ma35d1_clk_gate(dev, "gpm_gate", "hclk0",
711 					clk_base + REG_CLK_SYSCLK1, 28);
712 	hws[GPN_GATE] = ma35d1_clk_gate(dev, "gpn_gate", "hclk0",
713 					clk_base + REG_CLK_SYSCLK1, 29);
714 
715 	hws[TMR0_MUX] = ma35d1_clk_mux(dev, "tmr0_mux", clk_base + REG_CLK_CLKSEL1,
716 				       0, 3, timer0_sel_clks,
717 				       ARRAY_SIZE(timer0_sel_clks));
718 	hws[TMR0_GATE] = ma35d1_clk_gate(dev, "tmr0_gate", "tmr0_mux",
719 					 clk_base + REG_CLK_APBCLK0, 0);
720 	hws[TMR1_MUX] = ma35d1_clk_mux(dev, "tmr1_mux", clk_base + REG_CLK_CLKSEL1,
721 				       4, 3, timer1_sel_clks,
722 				       ARRAY_SIZE(timer1_sel_clks));
723 	hws[TMR1_GATE] = ma35d1_clk_gate(dev, "tmr1_gate", "tmr1_mux",
724 					 clk_base + REG_CLK_APBCLK0, 1);
725 	hws[TMR2_MUX] = ma35d1_clk_mux(dev, "tmr2_mux", clk_base + REG_CLK_CLKSEL1,
726 				       8, 3, timer2_sel_clks,
727 				       ARRAY_SIZE(timer2_sel_clks));
728 	hws[TMR2_GATE] = ma35d1_clk_gate(dev, "tmr2_gate", "tmr2_mux",
729 					 clk_base + REG_CLK_APBCLK0, 2);
730 	hws[TMR3_MUX] = ma35d1_clk_mux(dev, "tmr3_mux", clk_base + REG_CLK_CLKSEL1,
731 				       12, 3, timer3_sel_clks,
732 				       ARRAY_SIZE(timer3_sel_clks));
733 	hws[TMR3_GATE] = ma35d1_clk_gate(dev, "tmr3_gate", "tmr3_mux",
734 					 clk_base + REG_CLK_APBCLK0, 3);
735 	hws[TMR4_MUX] = ma35d1_clk_mux(dev, "tmr4_mux", clk_base + REG_CLK_CLKSEL1,
736 				       16, 3, timer4_sel_clks,
737 				       ARRAY_SIZE(timer4_sel_clks));
738 	hws[TMR4_GATE] = ma35d1_clk_gate(dev, "tmr4_gate", "tmr4_mux",
739 					 clk_base + REG_CLK_APBCLK0, 4);
740 	hws[TMR5_MUX] = ma35d1_clk_mux(dev, "tmr5_mux", clk_base + REG_CLK_CLKSEL1,
741 				       20, 3, timer5_sel_clks,
742 				       ARRAY_SIZE(timer5_sel_clks));
743 	hws[TMR5_GATE] = ma35d1_clk_gate(dev, "tmr5_gate", "tmr5_mux",
744 					 clk_base + REG_CLK_APBCLK0, 5);
745 	hws[TMR6_MUX] = ma35d1_clk_mux(dev, "tmr6_mux", clk_base + REG_CLK_CLKSEL1,
746 				       24, 3, timer6_sel_clks,
747 				       ARRAY_SIZE(timer6_sel_clks));
748 	hws[TMR6_GATE] = ma35d1_clk_gate(dev, "tmr6_gate", "tmr6_mux",
749 					 clk_base + REG_CLK_APBCLK0, 6);
750 	hws[TMR7_MUX] = ma35d1_clk_mux(dev, "tmr7_mux", clk_base + REG_CLK_CLKSEL1,
751 				       28, 3, timer7_sel_clks,
752 				       ARRAY_SIZE(timer7_sel_clks));
753 	hws[TMR7_GATE] = ma35d1_clk_gate(dev, "tmr7_gate", "tmr7_mux",
754 					 clk_base + REG_CLK_APBCLK0, 7);
755 	hws[TMR8_MUX] = ma35d1_clk_mux(dev, "tmr8_mux", clk_base + REG_CLK_CLKSEL2,
756 				       0, 3, timer8_sel_clks,
757 				       ARRAY_SIZE(timer8_sel_clks));
758 	hws[TMR8_GATE] = ma35d1_clk_gate(dev, "tmr8_gate", "tmr8_mux",
759 					 clk_base + REG_CLK_APBCLK0, 8);
760 	hws[TMR9_MUX] = ma35d1_clk_mux(dev, "tmr9_mux", clk_base + REG_CLK_CLKSEL2,
761 				       4, 3, timer9_sel_clks,
762 				       ARRAY_SIZE(timer9_sel_clks));
763 	hws[TMR9_GATE] = ma35d1_clk_gate(dev, "tmr9_gate", "tmr9_mux",
764 					 clk_base + REG_CLK_APBCLK0, 9);
765 	hws[TMR10_MUX] = ma35d1_clk_mux(dev, "tmr10_mux", clk_base + REG_CLK_CLKSEL2,
766 					8, 3, timer10_sel_clks,
767 					ARRAY_SIZE(timer10_sel_clks));
768 	hws[TMR10_GATE] = ma35d1_clk_gate(dev, "tmr10_gate", "tmr10_mux",
769 					  clk_base + REG_CLK_APBCLK0, 10);
770 	hws[TMR11_MUX] = ma35d1_clk_mux(dev, "tmr11_mux", clk_base + REG_CLK_CLKSEL2,
771 					12, 3, timer11_sel_clks,
772 					ARRAY_SIZE(timer11_sel_clks));
773 	hws[TMR11_GATE] = ma35d1_clk_gate(dev, "tmr11_gate", "tmr11_mux",
774 					  clk_base + REG_CLK_APBCLK0, 11);
775 
776 	hws[UART0_MUX] = ma35d1_clk_mux(dev, "uart0_mux", clk_base + REG_CLK_CLKSEL2,
777 					16, 2, uart_sel_clks, ARRAY_SIZE(uart_sel_clks));
778 	hws[UART0_DIV] = ma35d1_clk_divider(dev, "uart0_div", "uart0_mux",
779 					    clk_base + REG_CLK_CLKDIV1,
780 					    16, 4);
781 	hws[UART0_GATE] = ma35d1_clk_gate(dev, "uart0_gate", "uart0_div",
782 					  clk_base + REG_CLK_APBCLK0, 12);
783 	hws[UART1_MUX] = ma35d1_clk_mux(dev, "uart1_mux", clk_base + REG_CLK_CLKSEL2,
784 					18, 2, uart_sel_clks, ARRAY_SIZE(uart_sel_clks));
785 	hws[UART1_DIV] = ma35d1_clk_divider(dev, "uart1_div", "uart1_mux",
786 					    clk_base + REG_CLK_CLKDIV1,
787 					    20, 4);
788 	hws[UART1_GATE] = ma35d1_clk_gate(dev, "uart1_gate", "uart1_div",
789 					  clk_base + REG_CLK_APBCLK0, 13);
790 	hws[UART2_MUX] = ma35d1_clk_mux(dev, "uart2_mux", clk_base + REG_CLK_CLKSEL2,
791 					20, 2, uart_sel_clks, ARRAY_SIZE(uart_sel_clks));
792 	hws[UART2_DIV] = ma35d1_clk_divider(dev, "uart2_div", "uart2_mux",
793 					    clk_base + REG_CLK_CLKDIV1,
794 					    24, 4);
795 	hws[UART2_GATE] = ma35d1_clk_gate(dev, "uart2_gate", "uart2_div",
796 					  clk_base + REG_CLK_APBCLK0, 14);
797 	hws[UART3_MUX] = ma35d1_clk_mux(dev, "uart3_mux", clk_base + REG_CLK_CLKSEL2,
798 					22, 2, uart_sel_clks, ARRAY_SIZE(uart_sel_clks));
799 	hws[UART3_DIV] = ma35d1_clk_divider(dev, "uart3_div", "uart3_mux",
800 					    clk_base + REG_CLK_CLKDIV1,
801 					    28, 4);
802 	hws[UART3_GATE] = ma35d1_clk_gate(dev, "uart3_gate", "uart3_div",
803 					  clk_base + REG_CLK_APBCLK0, 15);
804 	hws[UART4_MUX] = ma35d1_clk_mux(dev, "uart4_mux", clk_base + REG_CLK_CLKSEL2,
805 					24, 2, uart_sel_clks, ARRAY_SIZE(uart_sel_clks));
806 	hws[UART4_DIV] = ma35d1_clk_divider(dev, "uart4_div", "uart4_mux",
807 					    clk_base + REG_CLK_CLKDIV2,
808 					    0, 4);
809 	hws[UART4_GATE] = ma35d1_clk_gate(dev, "uart4_gate", "uart4_div",
810 					  clk_base + REG_CLK_APBCLK0, 16);
811 	hws[UART5_MUX] = ma35d1_clk_mux(dev, "uart5_mux", clk_base + REG_CLK_CLKSEL2,
812 					26, 2, uart_sel_clks, ARRAY_SIZE(uart_sel_clks));
813 	hws[UART5_DIV] = ma35d1_clk_divider(dev, "uart5_div", "uart5_mux",
814 					    clk_base + REG_CLK_CLKDIV2,
815 					    4, 4);
816 	hws[UART5_GATE] = ma35d1_clk_gate(dev, "uart5_gate", "uart5_div",
817 					  clk_base + REG_CLK_APBCLK0, 17);
818 	hws[UART6_MUX] = ma35d1_clk_mux(dev, "uart6_mux", clk_base + REG_CLK_CLKSEL2,
819 					28, 2, uart_sel_clks, ARRAY_SIZE(uart_sel_clks));
820 	hws[UART6_DIV] = ma35d1_clk_divider(dev, "uart6_div", "uart6_mux",
821 					    clk_base + REG_CLK_CLKDIV2,
822 					    8, 4);
823 	hws[UART6_GATE] = ma35d1_clk_gate(dev, "uart6_gate", "uart6_div",
824 					  clk_base + REG_CLK_APBCLK0, 18);
825 	hws[UART7_MUX] = ma35d1_clk_mux(dev, "uart7_mux", clk_base + REG_CLK_CLKSEL2,
826 					30, 2, uart_sel_clks, ARRAY_SIZE(uart_sel_clks));
827 	hws[UART7_DIV] = ma35d1_clk_divider(dev, "uart7_div", "uart7_mux",
828 					    clk_base + REG_CLK_CLKDIV2,
829 					    12, 4);
830 	hws[UART7_GATE] = ma35d1_clk_gate(dev, "uart7_gate", "uart7_div",
831 					  clk_base + REG_CLK_APBCLK0, 19);
832 	hws[UART8_MUX] = ma35d1_clk_mux(dev, "uart8_mux", clk_base + REG_CLK_CLKSEL3,
833 					0, 2, uart_sel_clks, ARRAY_SIZE(uart_sel_clks));
834 	hws[UART8_DIV] = ma35d1_clk_divider(dev, "uart8_div", "uart8_mux",
835 					    clk_base + REG_CLK_CLKDIV2,
836 					    16, 4);
837 	hws[UART8_GATE] = ma35d1_clk_gate(dev, "uart8_gate", "uart8_div",
838 					  clk_base + REG_CLK_APBCLK0, 20);
839 	hws[UART9_MUX] = ma35d1_clk_mux(dev, "uart9_mux", clk_base + REG_CLK_CLKSEL3,
840 					2, 2, uart_sel_clks, ARRAY_SIZE(uart_sel_clks));
841 	hws[UART9_DIV] = ma35d1_clk_divider(dev, "uart9_div", "uart9_mux",
842 					    clk_base + REG_CLK_CLKDIV2,
843 					    20, 4);
844 	hws[UART9_GATE] = ma35d1_clk_gate(dev, "uart9_gate", "uart9_div",
845 					  clk_base + REG_CLK_APBCLK0, 21);
846 	hws[UART10_MUX] = ma35d1_clk_mux(dev, "uart10_mux", clk_base + REG_CLK_CLKSEL3,
847 					 4, 2, uart_sel_clks, ARRAY_SIZE(uart_sel_clks));
848 	hws[UART10_DIV] = ma35d1_clk_divider(dev, "uart10_div", "uart10_mux",
849 					     clk_base + REG_CLK_CLKDIV2,
850 					     24, 4);
851 	hws[UART10_GATE] = ma35d1_clk_gate(dev, "uart10_gate", "uart10_div",
852 					   clk_base + REG_CLK_APBCLK0, 22);
853 	hws[UART11_MUX] = ma35d1_clk_mux(dev, "uart11_mux", clk_base + REG_CLK_CLKSEL3,
854 					 6, 2, uart_sel_clks, ARRAY_SIZE(uart_sel_clks));
855 	hws[UART11_DIV] = ma35d1_clk_divider(dev, "uart11_div", "uart11_mux",
856 					     clk_base + REG_CLK_CLKDIV2,
857 					     28, 4);
858 	hws[UART11_GATE] = ma35d1_clk_gate(dev, "uart11_gate", "uart11_div",
859 					   clk_base + REG_CLK_APBCLK0, 23);
860 	hws[UART12_MUX] = ma35d1_clk_mux(dev, "uart12_mux", clk_base + REG_CLK_CLKSEL3,
861 					 8, 2, uart_sel_clks, ARRAY_SIZE(uart_sel_clks));
862 	hws[UART12_DIV] = ma35d1_clk_divider(dev, "uart12_div", "uart12_mux",
863 					     clk_base + REG_CLK_CLKDIV3,
864 					     0, 4);
865 	hws[UART12_GATE] = ma35d1_clk_gate(dev, "uart12_gate", "uart12_div",
866 					   clk_base + REG_CLK_APBCLK0, 24);
867 	hws[UART13_MUX] = ma35d1_clk_mux(dev, "uart13_mux", clk_base + REG_CLK_CLKSEL3,
868 					 10, 2, uart_sel_clks, ARRAY_SIZE(uart_sel_clks));
869 	hws[UART13_DIV] = ma35d1_clk_divider(dev, "uart13_div", "uart13_mux",
870 					     clk_base + REG_CLK_CLKDIV3,
871 					     4, 4);
872 	hws[UART13_GATE] = ma35d1_clk_gate(dev, "uart13_gate", "uart13_div",
873 					   clk_base + REG_CLK_APBCLK0, 25);
874 	hws[UART14_MUX] = ma35d1_clk_mux(dev, "uart14_mux", clk_base + REG_CLK_CLKSEL3,
875 					 12, 2, uart_sel_clks, ARRAY_SIZE(uart_sel_clks));
876 	hws[UART14_DIV] = ma35d1_clk_divider(dev, "uart14_div", "uart14_mux",
877 					     clk_base + REG_CLK_CLKDIV3,
878 					     8, 4);
879 	hws[UART14_GATE] = ma35d1_clk_gate(dev, "uart14_gate", "uart14_div",
880 					   clk_base + REG_CLK_APBCLK0, 26);
881 	hws[UART15_MUX] = ma35d1_clk_mux(dev, "uart15_mux", clk_base + REG_CLK_CLKSEL3,
882 					 14, 2, uart_sel_clks, ARRAY_SIZE(uart_sel_clks));
883 	hws[UART15_DIV] = ma35d1_clk_divider(dev, "uart15_div", "uart15_mux",
884 					     clk_base + REG_CLK_CLKDIV3,
885 					     12, 4);
886 	hws[UART15_GATE] = ma35d1_clk_gate(dev, "uart15_gate", "uart15_div",
887 					   clk_base + REG_CLK_APBCLK0, 27);
888 	hws[UART16_MUX] = ma35d1_clk_mux(dev, "uart16_mux", clk_base + REG_CLK_CLKSEL3,
889 					 16, 2, uart_sel_clks, ARRAY_SIZE(uart_sel_clks));
890 	hws[UART16_DIV] = ma35d1_clk_divider(dev, "uart16_div", "uart16_mux",
891 					     clk_base + REG_CLK_CLKDIV3,
892 					     16, 4);
893 	hws[UART16_GATE] = ma35d1_clk_gate(dev, "uart16_gate", "uart16_div",
894 					   clk_base + REG_CLK_APBCLK0, 28);
895 
896 	hws[RTC_GATE] = ma35d1_clk_gate(dev, "rtc_gate", "lxt",
897 					clk_base + REG_CLK_APBCLK0, 29);
898 	hws[DDR_GATE] = ma35d1_clk_gate(dev, "ddr_gate", "ddrpll",
899 					clk_base + REG_CLK_APBCLK0, 30);
900 
901 	hws[KPI_MUX] = ma35d1_clk_mux(dev, "kpi_mux", clk_base + REG_CLK_CLKSEL4,
902 				      30, 1, kpi_sel_clks, ARRAY_SIZE(kpi_sel_clks));
903 	hws[KPI_DIV] = ma35d1_clk_divider(dev, "kpi_div", "kpi_mux",
904 					  clk_base + REG_CLK_CLKDIV4,
905 					  24, 8);
906 	hws[KPI_GATE] = ma35d1_clk_gate(dev, "kpi_gate", "kpi_div",
907 					clk_base + REG_CLK_APBCLK0, 31);
908 
909 	hws[I2C0_GATE] = ma35d1_clk_gate(dev, "i2c0_gate", "pclk0",
910 					 clk_base + REG_CLK_APBCLK1, 0);
911 	hws[I2C1_GATE] = ma35d1_clk_gate(dev, "i2c1_gate", "pclk1",
912 					 clk_base + REG_CLK_APBCLK1, 1);
913 	hws[I2C2_GATE] = ma35d1_clk_gate(dev, "i2c2_gate", "pclk2",
914 					 clk_base + REG_CLK_APBCLK1, 2);
915 	hws[I2C3_GATE] = ma35d1_clk_gate(dev, "i2c3_gate", "pclk0",
916 					 clk_base + REG_CLK_APBCLK1, 3);
917 	hws[I2C4_GATE] = ma35d1_clk_gate(dev, "i2c4_gate", "pclk1",
918 					 clk_base + REG_CLK_APBCLK1, 4);
919 	hws[I2C5_GATE] = ma35d1_clk_gate(dev, "i2c5_gate", "pclk2",
920 					 clk_base + REG_CLK_APBCLK1, 5);
921 
922 	hws[QSPI0_MUX] = ma35d1_clk_mux(dev, "qspi0_mux", clk_base + REG_CLK_CLKSEL4,
923 					8, 2, qspi0_sel_clks, ARRAY_SIZE(qspi0_sel_clks));
924 	hws[QSPI0_GATE] = ma35d1_clk_gate(dev, "qspi0_gate", "qspi0_mux",
925 					  clk_base + REG_CLK_APBCLK1, 6);
926 	hws[QSPI1_MUX] = ma35d1_clk_mux(dev, "qspi1_mux", clk_base + REG_CLK_CLKSEL4,
927 					10, 2, qspi1_sel_clks, ARRAY_SIZE(qspi1_sel_clks));
928 	hws[QSPI1_GATE] = ma35d1_clk_gate(dev, "qspi1_gate", "qspi1_mux",
929 					  clk_base + REG_CLK_APBCLK1, 7);
930 
931 	hws[SMC0_MUX] = ma35d1_clk_mux(dev, "smc0_mux", clk_base + REG_CLK_CLKSEL4,
932 					28, 1, smc_sel_clks, ARRAY_SIZE(smc_sel_clks));
933 	hws[SMC0_DIV] = ma35d1_clk_divider(dev, "smc0_div", "smc0_mux",
934 					   clk_base + REG_CLK_CLKDIV1,
935 					   0, 4);
936 	hws[SMC0_GATE] = ma35d1_clk_gate(dev, "smc0_gate", "smc0_div",
937 					 clk_base + REG_CLK_APBCLK1, 12);
938 	hws[SMC1_MUX] = ma35d1_clk_mux(dev, "smc1_mux", clk_base + REG_CLK_CLKSEL4,
939 					 29, 1, smc_sel_clks, ARRAY_SIZE(smc_sel_clks));
940 	hws[SMC1_DIV] = ma35d1_clk_divider(dev, "smc1_div", "smc1_mux",
941 					   clk_base + REG_CLK_CLKDIV1,
942 					   4, 4);
943 	hws[SMC1_GATE] = ma35d1_clk_gate(dev, "smc1_gate", "smc1_div",
944 					 clk_base + REG_CLK_APBCLK1, 13);
945 
946 	hws[WDT0_MUX] = ma35d1_clk_mux(dev, "wdt0_mux", clk_base + REG_CLK_CLKSEL3,
947 				       20, 2, wdt0_sel_clks, ARRAY_SIZE(wdt0_sel_clks));
948 	hws[WDT0_GATE] = ma35d1_clk_gate(dev, "wdt0_gate", "wdt0_mux",
949 					 clk_base + REG_CLK_APBCLK1, 16);
950 	hws[WDT1_MUX] = ma35d1_clk_mux(dev, "wdt1_mux", clk_base + REG_CLK_CLKSEL3,
951 				       24, 2, wdt1_sel_clks, ARRAY_SIZE(wdt1_sel_clks));
952 	hws[WDT1_GATE] = ma35d1_clk_gate(dev, "wdt1_gate", "wdt1_mux",
953 					 clk_base + REG_CLK_APBCLK1, 17);
954 	hws[WDT2_MUX] = ma35d1_clk_mux(dev, "wdt2_mux", clk_base + REG_CLK_CLKSEL3,
955 				       28, 2, wdt2_sel_clks, ARRAY_SIZE(wdt2_sel_clks));
956 	hws[WDT2_GATE] = ma35d1_clk_gate(dev, "wdt2_gate", "wdt2_mux",
957 				       clk_base + REG_CLK_APBCLK1, 18);
958 
959 	hws[WWDT0_MUX] = ma35d1_clk_mux(dev, "wwdt0_mux", clk_base + REG_CLK_CLKSEL3,
960 					22, 2, wwdt0_sel_clks, ARRAY_SIZE(wwdt0_sel_clks));
961 	hws[WWDT1_MUX] = ma35d1_clk_mux(dev, "wwdt1_mux", clk_base + REG_CLK_CLKSEL3,
962 					26, 2, wwdt1_sel_clks, ARRAY_SIZE(wwdt1_sel_clks));
963 	hws[WWDT2_MUX] = ma35d1_clk_mux(dev, "wwdt2_mux", clk_base + REG_CLK_CLKSEL3,
964 					30, 2, wwdt2_sel_clks, ARRAY_SIZE(wwdt2_sel_clks));
965 
966 	hws[EPWM0_GATE] = ma35d1_clk_gate(dev, "epwm0_gate", "pclk1",
967 					  clk_base + REG_CLK_APBCLK1, 24);
968 	hws[EPWM1_GATE] = ma35d1_clk_gate(dev, "epwm1_gate", "pclk2",
969 					  clk_base + REG_CLK_APBCLK1, 25);
970 	hws[EPWM2_GATE] = ma35d1_clk_gate(dev, "epwm2_gate", "pclk1",
971 					  clk_base + REG_CLK_APBCLK1, 26);
972 
973 	hws[I2S0_MUX] = ma35d1_clk_mux(dev, "i2s0_mux", clk_base + REG_CLK_CLKSEL4,
974 				       12, 2, i2s0_sel_clks, ARRAY_SIZE(i2s0_sel_clks));
975 	hws[I2S0_GATE] = ma35d1_clk_gate(dev, "i2s0_gate", "i2s0_mux",
976 					 clk_base + REG_CLK_APBCLK2, 0);
977 	hws[I2S1_MUX] = ma35d1_clk_mux(dev, "i2s1_mux", clk_base + REG_CLK_CLKSEL4,
978 				       14, 2, i2s1_sel_clks, ARRAY_SIZE(i2s1_sel_clks));
979 	hws[I2S1_GATE] = ma35d1_clk_gate(dev, "i2s1_gate", "i2s1_mux",
980 					 clk_base + REG_CLK_APBCLK2, 1);
981 
982 	hws[SSMCC_GATE] = ma35d1_clk_gate(dev, "ssmcc_gate", "pclk3",
983 					  clk_base + REG_CLK_APBCLK2, 2);
984 	hws[SSPCC_GATE] = ma35d1_clk_gate(dev, "sspcc_gate", "pclk3",
985 					  clk_base + REG_CLK_APBCLK2, 3);
986 
987 	hws[SPI0_MUX] = ma35d1_clk_mux(dev, "spi0_mux", clk_base + REG_CLK_CLKSEL4,
988 				       0, 2, spi0_sel_clks, ARRAY_SIZE(spi0_sel_clks));
989 	hws[SPI0_GATE] = ma35d1_clk_gate(dev, "spi0_gate", "spi0_mux",
990 					 clk_base + REG_CLK_APBCLK2, 4);
991 	hws[SPI1_MUX] = ma35d1_clk_mux(dev, "spi1_mux", clk_base + REG_CLK_CLKSEL4,
992 				       2, 2, spi1_sel_clks, ARRAY_SIZE(spi1_sel_clks));
993 	hws[SPI1_GATE] = ma35d1_clk_gate(dev, "spi1_gate", "spi1_mux",
994 					 clk_base + REG_CLK_APBCLK2, 5);
995 	hws[SPI2_MUX] = ma35d1_clk_mux(dev, "spi2_mux", clk_base + REG_CLK_CLKSEL4,
996 				       4, 2, spi2_sel_clks, ARRAY_SIZE(spi2_sel_clks));
997 	hws[SPI2_GATE] = ma35d1_clk_gate(dev, "spi2_gate", "spi2_mux",
998 					 clk_base + REG_CLK_APBCLK2, 6);
999 	hws[SPI3_MUX] = ma35d1_clk_mux(dev, "spi3_mux", clk_base + REG_CLK_CLKSEL4,
1000 				       6, 2, spi3_sel_clks, ARRAY_SIZE(spi3_sel_clks));
1001 	hws[SPI3_GATE] = ma35d1_clk_gate(dev, "spi3_gate", "spi3_mux",
1002 					 clk_base + REG_CLK_APBCLK2, 7);
1003 
1004 	hws[ECAP0_GATE] = ma35d1_clk_gate(dev, "ecap0_gate", "pclk1",
1005 					  clk_base + REG_CLK_APBCLK2, 8);
1006 	hws[ECAP1_GATE] = ma35d1_clk_gate(dev, "ecap1_gate", "pclk2",
1007 					  clk_base + REG_CLK_APBCLK2, 9);
1008 	hws[ECAP2_GATE] = ma35d1_clk_gate(dev, "ecap2_gate", "pclk1",
1009 					  clk_base + REG_CLK_APBCLK2, 10);
1010 
1011 	hws[QEI0_GATE] = ma35d1_clk_gate(dev, "qei0_gate", "pclk1",
1012 					 clk_base + REG_CLK_APBCLK2, 12);
1013 	hws[QEI1_GATE] = ma35d1_clk_gate(dev, "qei1_gate", "pclk2",
1014 					 clk_base + REG_CLK_APBCLK2, 13);
1015 	hws[QEI2_GATE] = ma35d1_clk_gate(dev, "qei2_gate", "pclk1",
1016 					 clk_base + REG_CLK_APBCLK2, 14);
1017 
1018 	hws[ADC_DIV] = ma35d1_reg_adc_clkdiv(dev, "adc_div", hws[PCLK0],
1019 					     &ma35d1_lock, 0,
1020 					     clk_base + REG_CLK_CLKDIV4,
1021 					     4, 17, 0x1ffff);
1022 	hws[ADC_GATE] = ma35d1_clk_gate(dev, "adc_gate", "adc_div",
1023 					clk_base + REG_CLK_APBCLK2, 24);
1024 
1025 	hws[EADC_DIV] = ma35d1_clk_divider_table(dev, "eadc_div", "pclk2",
1026 						 clk_base + REG_CLK_CLKDIV4,
1027 						 0, 4, eadc_div_table);
1028 	hws[EADC_GATE] = ma35d1_clk_gate(dev, "eadc_gate", "eadc_div",
1029 					 clk_base + REG_CLK_APBCLK2, 25);
1030 
1031 	return devm_of_clk_add_hw_provider(dev,
1032 					   of_clk_hw_onecell_get,
1033 					   ma35d1_hw_data);
1034 }
1035 
1036 static const struct of_device_id ma35d1_clk_of_match[] = {
1037 	{ .compatible = "nuvoton,ma35d1-clk" },
1038 	{ }
1039 };
1040 MODULE_DEVICE_TABLE(of, ma35d1_clk_of_match);
1041 
1042 static struct platform_driver ma35d1_clk_driver = {
1043 	.probe = ma35d1_clocks_probe,
1044 	.driver = {
1045 		.name = "ma35d1-clk",
1046 		.of_match_table = ma35d1_clk_of_match,
1047 	},
1048 };
1049 
1050 static int __init ma35d1_clocks_init(void)
1051 {
1052 	return platform_driver_register(&ma35d1_clk_driver);
1053 }
1054 
1055 postcore_initcall(ma35d1_clocks_init);
1056 
1057 MODULE_AUTHOR("Chi-Fang Li <cfli0@nuvoton.com>");
1058 MODULE_DESCRIPTION("NUVOTON MA35D1 Clock Driver");
1059 MODULE_LICENSE("GPL");
1060