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
17static 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
65static const struct clk_parent_data ca35clk_sel_clks[] = {
66 { .fw_name = "hxt", },
67 { .fw_name = "capll", },
68 { .fw_name = "ddrpll", },
69};
70
71static const struct clk_parent_data sysclk0_sel_clks[] = {
72 { .fw_name = "epll_div2", },
73 { .fw_name = "syspll", },
74};
75
76static const struct clk_parent_data sysclk1_sel_clks[] = {
77 { .fw_name = "hxt", },
78 { .fw_name = "syspll", },
79};
80
81static const struct clk_parent_data axiclk_sel_clks[] = {
82 { .fw_name = "capll_div2", },
83 { .fw_name = "capll_div4", },
84};
85
86static 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
93static const struct clk_parent_data sdh_sel_clks[] = {
94 { .fw_name = "syspll", },
95 { .fw_name = "apll", },
96};
97
98static const struct clk_parent_data dcu_sel_clks[] = {
99 { .fw_name = "epll_div2", },
100 { .fw_name = "syspll", },
101};
102
103static const struct clk_parent_data gfx_sel_clks[] = {
104 { .fw_name = "epll", },
105 { .fw_name = "syspll", },
106};
107
108static const struct clk_parent_data dbg_sel_clks[] = {
109 { .fw_name = "hirc", },
110 { .fw_name = "syspll", },
111};
112
113static 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
124static 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
135static 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
146static 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
157static 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
168static 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
179static 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
190static 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
201static 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
212static 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
223static 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
234static 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
245static const struct clk_parent_data uart_sel_clks[] = {
246 { .fw_name = "hxt", },
247 { .fw_name = "sysclk1_div2", },
248};
249
250static 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
257static 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
264static 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
271static 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
278static 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
285static 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
292static const struct clk_parent_data spi0_sel_clks[] = {
293 { .fw_name = "pclk1", },
294 { .fw_name = "apll", },
295};
296
297static const struct clk_parent_data spi1_sel_clks[] = {
298 { .fw_name = "pclk2", },
299 { .fw_name = "apll", },
300};
301
302static const struct clk_parent_data spi2_sel_clks[] = {
303 { .fw_name = "pclk1", },
304 { .fw_name = "apll", },
305};
306
307static const struct clk_parent_data spi3_sel_clks[] = {
308 { .fw_name = "pclk2", },
309 { .fw_name = "apll", },
310};
311
312static const struct clk_parent_data qspi0_sel_clks[] = {
313 { .fw_name = "pclk0", },
314 { .fw_name = "apll", },
315};
316
317static const struct clk_parent_data qspi1_sel_clks[] = {
318 { .fw_name = "pclk0", },
319 { .fw_name = "apll", },
320};
321
322static const struct clk_parent_data i2s0_sel_clks[] = {
323 { .fw_name = "apll", },
324 { .fw_name = "sysclk1_div2", },
325};
326
327static const struct clk_parent_data i2s1_sel_clks[] = {
328 { .fw_name = "apll", },
329 { .fw_name = "sysclk1_div2", },
330};
331
332static const struct clk_parent_data can_sel_clks[] = {
333 { .fw_name = "apll", },
334 { .fw_name = "vpll", },
335};
336
337static 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
350static const struct clk_parent_data smc_sel_clks[] = {
351 { .fw_name = "hxt", },
352 { .fw_name = "pclk4", },
353};
354
355static const struct clk_parent_data kpi_sel_clks[] = {
356 { .fw_name = "hxt", },
357 { .fw_name = "lxt", },
358};
359
360static 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
365static 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
372static 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
377static 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
387static 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
397static 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
405static 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
414static 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
424static 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_name: parent,
429 CLK_SET_RATE_PARENT, mult, div);
430}
431
432static 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
439static 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(np: clk_node, propname: "nuvoton,pll-mode", index: i, output: &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
459static 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 void __iomem *clk_base;
464 static struct clk_hw **hws;
465 static struct clk_hw_onecell_data *ma35d1_hw_data;
466 u32 pllmode[PLL_MAX_NUM];
467 int ret;
468
469 ma35d1_hw_data = devm_kzalloc(dev,
470 struct_size(ma35d1_hw_data, hws, CLK_MAX_IDX),
471 GFP_KERNEL);
472 if (!ma35d1_hw_data)
473 return -ENOMEM;
474
475 ma35d1_hw_data->num = CLK_MAX_IDX;
476 hws = ma35d1_hw_data->hws;
477
478 clk_base = devm_platform_ioremap_resource(pdev, index: 0);
479 if (IS_ERR(ptr: clk_base))
480 return PTR_ERR(ptr: clk_base);
481
482 ret = ma35d1_get_pll_setting(clk_node, pllmode);
483 if (ret < 0) {
484 dev_err(dev, "Invalid PLL setting!\n");
485 return -EINVAL;
486 }
487
488 hws[HXT] = ma35d1_clk_fixed(name: "hxt", rate: 24000000);
489 hws[HXT_GATE] = ma35d1_clk_gate(dev, name: "hxt_gate", parent: "hxt",
490 reg: clk_base + REG_CLK_PWRCTL, shift: 0);
491 hws[LXT] = ma35d1_clk_fixed(name: "lxt", rate: 32768);
492 hws[LXT_GATE] = ma35d1_clk_gate(dev, name: "lxt_gate", parent: "lxt",
493 reg: clk_base + REG_CLK_PWRCTL, shift: 1);
494 hws[HIRC] = ma35d1_clk_fixed(name: "hirc", rate: 12000000);
495 hws[HIRC_GATE] = ma35d1_clk_gate(dev, name: "hirc_gate", parent: "hirc",
496 reg: clk_base + REG_CLK_PWRCTL, shift: 2);
497 hws[LIRC] = ma35d1_clk_fixed(name: "lirc", rate: 32000);
498 hws[LIRC_GATE] = ma35d1_clk_gate(dev, name: "lirc_gate", parent: "lirc",
499 reg: clk_base + REG_CLK_PWRCTL, shift: 3);
500
501 hws[CAPLL] = ma35d1_reg_clk_pll(dev, CAPLL, u8mode: pllmode[0], name: "capll",
502 parent_hw: hws[HXT], base: clk_base + REG_CLK_PLL0CTL0);
503 hws[SYSPLL] = ma35d1_clk_fixed(name: "syspll", rate: 180000000);
504 hws[DDRPLL] = ma35d1_reg_clk_pll(dev, DDRPLL, u8mode: pllmode[1], name: "ddrpll",
505 parent_hw: hws[HXT], base: clk_base + REG_CLK_PLL2CTL0);
506 hws[APLL] = ma35d1_reg_clk_pll(dev, APLL, u8mode: pllmode[2], name: "apll",
507 parent_hw: hws[HXT], base: clk_base + REG_CLK_PLL3CTL0);
508 hws[EPLL] = ma35d1_reg_clk_pll(dev, EPLL, u8mode: pllmode[3], name: "epll",
509 parent_hw: hws[HXT], base: clk_base + REG_CLK_PLL4CTL0);
510 hws[VPLL] = ma35d1_reg_clk_pll(dev, VPLL, u8mode: pllmode[4], name: "vpll",
511 parent_hw: hws[HXT], base: clk_base + REG_CLK_PLL5CTL0);
512
513 hws[EPLL_DIV2] = ma35d1_clk_fixed_factor(dev, name: "epll_div2", parent: "epll", mult: 1, div: 2);
514 hws[EPLL_DIV4] = ma35d1_clk_fixed_factor(dev, name: "epll_div4", parent: "epll", mult: 1, div: 4);
515 hws[EPLL_DIV8] = ma35d1_clk_fixed_factor(dev, name: "epll_div8", parent: "epll", mult: 1, div: 8);
516
517 hws[CA35CLK_MUX] = ma35d1_clk_mux_parent(dev, name: "ca35clk_mux",
518 reg: clk_base + REG_CLK_CLKSEL0, shift: 0, width: 2,
519 pdata: ca35clk_sel_clks,
520 ARRAY_SIZE(ca35clk_sel_clks));
521 hws[AXICLK_DIV2] = ma35d1_clk_fixed_factor(dev, name: "capll_div2", parent: "ca35clk_mux", mult: 1, div: 2);
522 hws[AXICLK_DIV4] = ma35d1_clk_fixed_factor(dev, name: "capll_div4", parent: "ca35clk_mux", mult: 1, div: 4);
523
524 hws[AXICLK_MUX] = ma35d1_clk_mux(dev, name: "axiclk_mux", reg: clk_base + REG_CLK_CLKDIV0,
525 shift: 26, width: 1, pdata: axiclk_sel_clks,
526 ARRAY_SIZE(axiclk_sel_clks));
527 hws[SYSCLK0_MUX] = ma35d1_clk_mux(dev, name: "sysclk0_mux", reg: clk_base + REG_CLK_CLKSEL0,
528 shift: 2, width: 1, pdata: sysclk0_sel_clks,
529 ARRAY_SIZE(sysclk0_sel_clks));
530 hws[SYSCLK1_MUX] = ma35d1_clk_mux(dev, name: "sysclk1_mux", reg: clk_base + REG_CLK_CLKSEL0,
531 shift: 4, width: 1, pdata: sysclk1_sel_clks,
532 ARRAY_SIZE(sysclk1_sel_clks));
533 hws[SYSCLK1_DIV2] = ma35d1_clk_fixed_factor(dev, name: "sysclk1_div2", parent: "sysclk1_mux", mult: 1, div: 2);
534
535 /* HCLK0~3 & PCLK0~4 */
536 hws[HCLK0] = ma35d1_clk_fixed_factor(dev, name: "hclk0", parent: "sysclk1_mux", mult: 1, div: 1);
537 hws[HCLK1] = ma35d1_clk_fixed_factor(dev, name: "hclk1", parent: "sysclk1_mux", mult: 1, div: 1);
538 hws[HCLK2] = ma35d1_clk_fixed_factor(dev, name: "hclk2", parent: "sysclk1_mux", mult: 1, div: 1);
539 hws[PCLK0] = ma35d1_clk_fixed_factor(dev, name: "pclk0", parent: "sysclk1_mux", mult: 1, div: 1);
540 hws[PCLK1] = ma35d1_clk_fixed_factor(dev, name: "pclk1", parent: "sysclk1_mux", mult: 1, div: 1);
541 hws[PCLK2] = ma35d1_clk_fixed_factor(dev, name: "pclk2", parent: "sysclk1_mux", mult: 1, div: 1);
542
543 hws[HCLK3] = ma35d1_clk_fixed_factor(dev, name: "hclk3", parent: "sysclk1_mux", mult: 1, div: 2);
544 hws[PCLK3] = ma35d1_clk_fixed_factor(dev, name: "pclk3", parent: "sysclk1_mux", mult: 1, div: 2);
545 hws[PCLK4] = ma35d1_clk_fixed_factor(dev, name: "pclk4", parent: "sysclk1_mux", mult: 1, div: 2);
546
547 hws[USBPHY0] = ma35d1_clk_fixed(name: "usbphy0", rate: 480000000);
548 hws[USBPHY1] = ma35d1_clk_fixed(name: "usbphy1", rate: 480000000);
549
550 /* DDR */
551 hws[DDR0_GATE] = ma35d1_clk_gate(dev, name: "ddr0_gate", parent: "ddrpll",
552 reg: clk_base + REG_CLK_SYSCLK0, shift: 4);
553 hws[DDR6_GATE] = ma35d1_clk_gate(dev, name: "ddr6_gate", parent: "ddrpll",
554 reg: clk_base + REG_CLK_SYSCLK0, shift: 5);
555
556 hws[CAN0_MUX] = ma35d1_clk_mux(dev, name: "can0_mux", reg: clk_base + REG_CLK_CLKSEL4,
557 shift: 16, width: 1, pdata: can_sel_clks, ARRAY_SIZE(can_sel_clks));
558 hws[CAN0_DIV] = ma35d1_clk_divider_table(dev, name: "can0_div", parent: "can0_mux",
559 reg: clk_base + REG_CLK_CLKDIV0,
560 shift: 0, width: 3, table: ip_div_table);
561 hws[CAN0_GATE] = ma35d1_clk_gate(dev, name: "can0_gate", parent: "can0_div",
562 reg: clk_base + REG_CLK_SYSCLK0, shift: 8);
563 hws[CAN1_MUX] = ma35d1_clk_mux(dev, name: "can1_mux", reg: clk_base + REG_CLK_CLKSEL4,
564 shift: 17, width: 1, pdata: can_sel_clks, ARRAY_SIZE(can_sel_clks));
565 hws[CAN1_DIV] = ma35d1_clk_divider_table(dev, name: "can1_div", parent: "can1_mux",
566 reg: clk_base + REG_CLK_CLKDIV0,
567 shift: 4, width: 3, table: ip_div_table);
568 hws[CAN1_GATE] = ma35d1_clk_gate(dev, name: "can1_gate", parent: "can1_div",
569 reg: clk_base + REG_CLK_SYSCLK0, shift: 9);
570 hws[CAN2_MUX] = ma35d1_clk_mux(dev, name: "can2_mux", reg: clk_base + REG_CLK_CLKSEL4,
571 shift: 18, width: 1, pdata: can_sel_clks, ARRAY_SIZE(can_sel_clks));
572 hws[CAN2_DIV] = ma35d1_clk_divider_table(dev, name: "can2_div", parent: "can2_mux",
573 reg: clk_base + REG_CLK_CLKDIV0,
574 shift: 8, width: 3, table: ip_div_table);
575 hws[CAN2_GATE] = ma35d1_clk_gate(dev, name: "can2_gate", parent: "can2_div",
576 reg: clk_base + REG_CLK_SYSCLK0, shift: 10);
577 hws[CAN3_MUX] = ma35d1_clk_mux(dev, name: "can3_mux", reg: clk_base + REG_CLK_CLKSEL4,
578 shift: 19, width: 1, pdata: can_sel_clks, ARRAY_SIZE(can_sel_clks));
579 hws[CAN3_DIV] = ma35d1_clk_divider_table(dev, name: "can3_div", parent: "can3_mux",
580 reg: clk_base + REG_CLK_CLKDIV0,
581 shift: 12, width: 3, table: ip_div_table);
582 hws[CAN3_GATE] = ma35d1_clk_gate(dev, name: "can3_gate", parent: "can3_div",
583 reg: clk_base + REG_CLK_SYSCLK0, shift: 11);
584
585 hws[SDH0_MUX] = ma35d1_clk_mux(dev, name: "sdh0_mux", reg: clk_base + REG_CLK_CLKSEL0,
586 shift: 16, width: 2, pdata: sdh_sel_clks, ARRAY_SIZE(sdh_sel_clks));
587 hws[SDH0_GATE] = ma35d1_clk_gate(dev, name: "sdh0_gate", parent: "sdh0_mux",
588 reg: clk_base + REG_CLK_SYSCLK0, shift: 16);
589 hws[SDH1_MUX] = ma35d1_clk_mux(dev, name: "sdh1_mux", reg: clk_base + REG_CLK_CLKSEL0,
590 shift: 18, width: 2, pdata: sdh_sel_clks, ARRAY_SIZE(sdh_sel_clks));
591 hws[SDH1_GATE] = ma35d1_clk_gate(dev, name: "sdh1_gate", parent: "sdh1_mux",
592 reg: clk_base + REG_CLK_SYSCLK0, shift: 17);
593
594 hws[NAND_GATE] = ma35d1_clk_gate(dev, name: "nand_gate", parent: "hclk1",
595 reg: clk_base + REG_CLK_SYSCLK0, shift: 18);
596
597 hws[USBD_GATE] = ma35d1_clk_gate(dev, name: "usbd_gate", parent: "usbphy0",
598 reg: clk_base + REG_CLK_SYSCLK0, shift: 19);
599 hws[USBH_GATE] = ma35d1_clk_gate(dev, name: "usbh_gate", parent: "usbphy0",
600 reg: clk_base + REG_CLK_SYSCLK0, shift: 20);
601 hws[HUSBH0_GATE] = ma35d1_clk_gate(dev, name: "husbh0_gate", parent: "usbphy0",
602 reg: clk_base + REG_CLK_SYSCLK0, shift: 21);
603 hws[HUSBH1_GATE] = ma35d1_clk_gate(dev, name: "husbh1_gate", parent: "usbphy0",
604 reg: clk_base + REG_CLK_SYSCLK0, shift: 22);
605
606 hws[GFX_MUX] = ma35d1_clk_mux(dev, name: "gfx_mux", reg: clk_base + REG_CLK_CLKSEL0,
607 shift: 26, width: 1, pdata: gfx_sel_clks, ARRAY_SIZE(gfx_sel_clks));
608 hws[GFX_GATE] = ma35d1_clk_gate(dev, name: "gfx_gate", parent: "gfx_mux",
609 reg: clk_base + REG_CLK_SYSCLK0, shift: 24);
610 hws[VC8K_GATE] = ma35d1_clk_gate(dev, name: "vc8k_gate", parent: "sysclk0_mux",
611 reg: clk_base + REG_CLK_SYSCLK0, shift: 25);
612 hws[DCU_MUX] = ma35d1_clk_mux(dev, name: "dcu_mux", reg: clk_base + REG_CLK_CLKSEL0,
613 shift: 24, width: 1, pdata: dcu_sel_clks, ARRAY_SIZE(dcu_sel_clks));
614 hws[DCU_GATE] = ma35d1_clk_gate(dev, name: "dcu_gate", parent: "dcu_mux",
615 reg: clk_base + REG_CLK_SYSCLK0, shift: 26);
616 hws[DCUP_DIV] = ma35d1_clk_divider_table(dev, name: "dcup_div", parent: "vpll",
617 reg: clk_base + REG_CLK_CLKDIV0,
618 shift: 16, width: 3, table: ip_div_table);
619
620 hws[EMAC0_GATE] = ma35d1_clk_gate(dev, name: "emac0_gate", parent: "epll_div2",
621 reg: clk_base + REG_CLK_SYSCLK0, shift: 27);
622 hws[EMAC1_GATE] = ma35d1_clk_gate(dev, name: "emac1_gate", parent: "epll_div2",
623 reg: clk_base + REG_CLK_SYSCLK0, shift: 28);
624
625 hws[CCAP0_MUX] = ma35d1_clk_mux(dev, name: "ccap0_mux", reg: clk_base + REG_CLK_CLKSEL0,
626 shift: 12, width: 1, pdata: ccap_sel_clks, ARRAY_SIZE(ccap_sel_clks));
627 hws[CCAP0_DIV] = ma35d1_clk_divider(dev, name: "ccap0_div", parent: "ccap0_mux",
628 reg: clk_base + REG_CLK_CLKDIV1, shift: 8, width: 4);
629 hws[CCAP0_GATE] = ma35d1_clk_gate(dev, name: "ccap0_gate", parent: "ccap0_div",
630 reg: clk_base + REG_CLK_SYSCLK0, shift: 29);
631 hws[CCAP1_MUX] = ma35d1_clk_mux(dev, name: "ccap1_mux", reg: clk_base + REG_CLK_CLKSEL0,
632 shift: 14, width: 1, pdata: ccap_sel_clks, ARRAY_SIZE(ccap_sel_clks));
633 hws[CCAP1_DIV] = ma35d1_clk_divider(dev, name: "ccap1_div", parent: "ccap1_mux",
634 reg: clk_base + REG_CLK_CLKDIV1,
635 shift: 12, width: 4);
636 hws[CCAP1_GATE] = ma35d1_clk_gate(dev, name: "ccap1_gate", parent: "ccap1_div",
637 reg: clk_base + REG_CLK_SYSCLK0, shift: 30);
638
639 hws[PDMA0_GATE] = ma35d1_clk_gate(dev, name: "pdma0_gate", parent: "hclk0",
640 reg: clk_base + REG_CLK_SYSCLK1, shift: 0);
641 hws[PDMA1_GATE] = ma35d1_clk_gate(dev, name: "pdma1_gate", parent: "hclk0",
642 reg: clk_base + REG_CLK_SYSCLK1, shift: 1);
643 hws[PDMA2_GATE] = ma35d1_clk_gate(dev, name: "pdma2_gate", parent: "hclk0",
644 reg: clk_base + REG_CLK_SYSCLK1, shift: 2);
645 hws[PDMA3_GATE] = ma35d1_clk_gate(dev, name: "pdma3_gate", parent: "hclk0",
646 reg: clk_base + REG_CLK_SYSCLK1, shift: 3);
647
648 hws[WH0_GATE] = ma35d1_clk_gate(dev, name: "wh0_gate", parent: "hclk0",
649 reg: clk_base + REG_CLK_SYSCLK1, shift: 4);
650 hws[WH1_GATE] = ma35d1_clk_gate(dev, name: "wh1_gate", parent: "hclk0",
651 reg: clk_base + REG_CLK_SYSCLK1, shift: 5);
652
653 hws[HWS_GATE] = ma35d1_clk_gate(dev, name: "hws_gate", parent: "hclk0",
654 reg: clk_base + REG_CLK_SYSCLK1, shift: 6);
655
656 hws[EBI_GATE] = ma35d1_clk_gate(dev, name: "ebi_gate", parent: "hclk0",
657 reg: clk_base + REG_CLK_SYSCLK1, shift: 7);
658
659 hws[SRAM0_GATE] = ma35d1_clk_gate(dev, name: "sram0_gate", parent: "hclk0",
660 reg: clk_base + REG_CLK_SYSCLK1, shift: 8);
661 hws[SRAM1_GATE] = ma35d1_clk_gate(dev, name: "sram1_gate", parent: "hclk0",
662 reg: clk_base + REG_CLK_SYSCLK1, shift: 9);
663
664 hws[ROM_GATE] = ma35d1_clk_gate(dev, name: "rom_gate", parent: "hclk0",
665 reg: clk_base + REG_CLK_SYSCLK1, shift: 10);
666
667 hws[TRA_GATE] = ma35d1_clk_gate(dev, name: "tra_gate", parent: "hclk0",
668 reg: clk_base + REG_CLK_SYSCLK1, shift: 11);
669
670 hws[DBG_MUX] = ma35d1_clk_mux(dev, name: "dbg_mux", reg: clk_base + REG_CLK_CLKSEL0,
671 shift: 27, width: 1, pdata: dbg_sel_clks, ARRAY_SIZE(dbg_sel_clks));
672 hws[DBG_GATE] = ma35d1_clk_gate(dev, name: "dbg_gate", parent: "hclk0",
673 reg: clk_base + REG_CLK_SYSCLK1, shift: 12);
674
675 hws[CKO_MUX] = ma35d1_clk_mux(dev, name: "cko_mux", reg: clk_base + REG_CLK_CLKSEL4,
676 shift: 24, width: 4, pdata: cko_sel_clks, ARRAY_SIZE(cko_sel_clks));
677 hws[CKO_DIV] = ma35d1_clk_divider_pow2(dev, name: "cko_div", parent: "cko_mux",
678 reg: clk_base + REG_CLK_CLKOCTL, shift: 0, width: 4);
679 hws[CKO_GATE] = ma35d1_clk_gate(dev, name: "cko_gate", parent: "cko_div",
680 reg: clk_base + REG_CLK_SYSCLK1, shift: 13);
681
682 hws[GTMR_GATE] = ma35d1_clk_gate(dev, name: "gtmr_gate", parent: "hirc",
683 reg: clk_base + REG_CLK_SYSCLK1, shift: 14);
684
685 hws[GPA_GATE] = ma35d1_clk_gate(dev, name: "gpa_gate", parent: "hclk0",
686 reg: clk_base + REG_CLK_SYSCLK1, shift: 16);
687 hws[GPB_GATE] = ma35d1_clk_gate(dev, name: "gpb_gate", parent: "hclk0",
688 reg: clk_base + REG_CLK_SYSCLK1, shift: 17);
689 hws[GPC_GATE] = ma35d1_clk_gate(dev, name: "gpc_gate", parent: "hclk0",
690 reg: clk_base + REG_CLK_SYSCLK1, shift: 18);
691 hws[GPD_GATE] = ma35d1_clk_gate(dev, name: "gpd_gate", parent: "hclk0",
692 reg: clk_base + REG_CLK_SYSCLK1, shift: 19);
693 hws[GPE_GATE] = ma35d1_clk_gate(dev, name: "gpe_gate", parent: "hclk0",
694 reg: clk_base + REG_CLK_SYSCLK1, shift: 20);
695 hws[GPF_GATE] = ma35d1_clk_gate(dev, name: "gpf_gate", parent: "hclk0",
696 reg: clk_base + REG_CLK_SYSCLK1, shift: 21);
697 hws[GPG_GATE] = ma35d1_clk_gate(dev, name: "gpg_gate", parent: "hclk0",
698 reg: clk_base + REG_CLK_SYSCLK1, shift: 22);
699 hws[GPH_GATE] = ma35d1_clk_gate(dev, name: "gph_gate", parent: "hclk0",
700 reg: clk_base + REG_CLK_SYSCLK1, shift: 23);
701 hws[GPI_GATE] = ma35d1_clk_gate(dev, name: "gpi_gate", parent: "hclk0",
702 reg: clk_base + REG_CLK_SYSCLK1, shift: 24);
703 hws[GPJ_GATE] = ma35d1_clk_gate(dev, name: "gpj_gate", parent: "hclk0",
704 reg: clk_base + REG_CLK_SYSCLK1, shift: 25);
705 hws[GPK_GATE] = ma35d1_clk_gate(dev, name: "gpk_gate", parent: "hclk0",
706 reg: clk_base + REG_CLK_SYSCLK1, shift: 26);
707 hws[GPL_GATE] = ma35d1_clk_gate(dev, name: "gpl_gate", parent: "hclk0",
708 reg: clk_base + REG_CLK_SYSCLK1, shift: 27);
709 hws[GPM_GATE] = ma35d1_clk_gate(dev, name: "gpm_gate", parent: "hclk0",
710 reg: clk_base + REG_CLK_SYSCLK1, shift: 28);
711 hws[GPN_GATE] = ma35d1_clk_gate(dev, name: "gpn_gate", parent: "hclk0",
712 reg: clk_base + REG_CLK_SYSCLK1, shift: 29);
713
714 hws[TMR0_MUX] = ma35d1_clk_mux(dev, name: "tmr0_mux", reg: clk_base + REG_CLK_CLKSEL1,
715 shift: 0, width: 3, pdata: timer0_sel_clks,
716 ARRAY_SIZE(timer0_sel_clks));
717 hws[TMR0_GATE] = ma35d1_clk_gate(dev, name: "tmr0_gate", parent: "tmr0_mux",
718 reg: clk_base + REG_CLK_APBCLK0, shift: 0);
719 hws[TMR1_MUX] = ma35d1_clk_mux(dev, name: "tmr1_mux", reg: clk_base + REG_CLK_CLKSEL1,
720 shift: 4, width: 3, pdata: timer1_sel_clks,
721 ARRAY_SIZE(timer1_sel_clks));
722 hws[TMR1_GATE] = ma35d1_clk_gate(dev, name: "tmr1_gate", parent: "tmr1_mux",
723 reg: clk_base + REG_CLK_APBCLK0, shift: 1);
724 hws[TMR2_MUX] = ma35d1_clk_mux(dev, name: "tmr2_mux", reg: clk_base + REG_CLK_CLKSEL1,
725 shift: 8, width: 3, pdata: timer2_sel_clks,
726 ARRAY_SIZE(timer2_sel_clks));
727 hws[TMR2_GATE] = ma35d1_clk_gate(dev, name: "tmr2_gate", parent: "tmr2_mux",
728 reg: clk_base + REG_CLK_APBCLK0, shift: 2);
729 hws[TMR3_MUX] = ma35d1_clk_mux(dev, name: "tmr3_mux", reg: clk_base + REG_CLK_CLKSEL1,
730 shift: 12, width: 3, pdata: timer3_sel_clks,
731 ARRAY_SIZE(timer3_sel_clks));
732 hws[TMR3_GATE] = ma35d1_clk_gate(dev, name: "tmr3_gate", parent: "tmr3_mux",
733 reg: clk_base + REG_CLK_APBCLK0, shift: 3);
734 hws[TMR4_MUX] = ma35d1_clk_mux(dev, name: "tmr4_mux", reg: clk_base + REG_CLK_CLKSEL1,
735 shift: 16, width: 3, pdata: timer4_sel_clks,
736 ARRAY_SIZE(timer4_sel_clks));
737 hws[TMR4_GATE] = ma35d1_clk_gate(dev, name: "tmr4_gate", parent: "tmr4_mux",
738 reg: clk_base + REG_CLK_APBCLK0, shift: 4);
739 hws[TMR5_MUX] = ma35d1_clk_mux(dev, name: "tmr5_mux", reg: clk_base + REG_CLK_CLKSEL1,
740 shift: 20, width: 3, pdata: timer5_sel_clks,
741 ARRAY_SIZE(timer5_sel_clks));
742 hws[TMR5_GATE] = ma35d1_clk_gate(dev, name: "tmr5_gate", parent: "tmr5_mux",
743 reg: clk_base + REG_CLK_APBCLK0, shift: 5);
744 hws[TMR6_MUX] = ma35d1_clk_mux(dev, name: "tmr6_mux", reg: clk_base + REG_CLK_CLKSEL1,
745 shift: 24, width: 3, pdata: timer6_sel_clks,
746 ARRAY_SIZE(timer6_sel_clks));
747 hws[TMR6_GATE] = ma35d1_clk_gate(dev, name: "tmr6_gate", parent: "tmr6_mux",
748 reg: clk_base + REG_CLK_APBCLK0, shift: 6);
749 hws[TMR7_MUX] = ma35d1_clk_mux(dev, name: "tmr7_mux", reg: clk_base + REG_CLK_CLKSEL1,
750 shift: 28, width: 3, pdata: timer7_sel_clks,
751 ARRAY_SIZE(timer7_sel_clks));
752 hws[TMR7_GATE] = ma35d1_clk_gate(dev, name: "tmr7_gate", parent: "tmr7_mux",
753 reg: clk_base + REG_CLK_APBCLK0, shift: 7);
754 hws[TMR8_MUX] = ma35d1_clk_mux(dev, name: "tmr8_mux", reg: clk_base + REG_CLK_CLKSEL2,
755 shift: 0, width: 3, pdata: timer8_sel_clks,
756 ARRAY_SIZE(timer8_sel_clks));
757 hws[TMR8_GATE] = ma35d1_clk_gate(dev, name: "tmr8_gate", parent: "tmr8_mux",
758 reg: clk_base + REG_CLK_APBCLK0, shift: 8);
759 hws[TMR9_MUX] = ma35d1_clk_mux(dev, name: "tmr9_mux", reg: clk_base + REG_CLK_CLKSEL2,
760 shift: 4, width: 3, pdata: timer9_sel_clks,
761 ARRAY_SIZE(timer9_sel_clks));
762 hws[TMR9_GATE] = ma35d1_clk_gate(dev, name: "tmr9_gate", parent: "tmr9_mux",
763 reg: clk_base + REG_CLK_APBCLK0, shift: 9);
764 hws[TMR10_MUX] = ma35d1_clk_mux(dev, name: "tmr10_mux", reg: clk_base + REG_CLK_CLKSEL2,
765 shift: 8, width: 3, pdata: timer10_sel_clks,
766 ARRAY_SIZE(timer10_sel_clks));
767 hws[TMR10_GATE] = ma35d1_clk_gate(dev, name: "tmr10_gate", parent: "tmr10_mux",
768 reg: clk_base + REG_CLK_APBCLK0, shift: 10);
769 hws[TMR11_MUX] = ma35d1_clk_mux(dev, name: "tmr11_mux", reg: clk_base + REG_CLK_CLKSEL2,
770 shift: 12, width: 3, pdata: timer11_sel_clks,
771 ARRAY_SIZE(timer11_sel_clks));
772 hws[TMR11_GATE] = ma35d1_clk_gate(dev, name: "tmr11_gate", parent: "tmr11_mux",
773 reg: clk_base + REG_CLK_APBCLK0, shift: 11);
774
775 hws[UART0_MUX] = ma35d1_clk_mux(dev, name: "uart0_mux", reg: clk_base + REG_CLK_CLKSEL2,
776 shift: 16, width: 2, pdata: uart_sel_clks, ARRAY_SIZE(uart_sel_clks));
777 hws[UART0_DIV] = ma35d1_clk_divider(dev, name: "uart0_div", parent: "uart0_mux",
778 reg: clk_base + REG_CLK_CLKDIV1,
779 shift: 16, width: 4);
780 hws[UART0_GATE] = ma35d1_clk_gate(dev, name: "uart0_gate", parent: "uart0_div",
781 reg: clk_base + REG_CLK_APBCLK0, shift: 12);
782 hws[UART1_MUX] = ma35d1_clk_mux(dev, name: "uart1_mux", reg: clk_base + REG_CLK_CLKSEL2,
783 shift: 18, width: 2, pdata: uart_sel_clks, ARRAY_SIZE(uart_sel_clks));
784 hws[UART1_DIV] = ma35d1_clk_divider(dev, name: "uart1_div", parent: "uart1_mux",
785 reg: clk_base + REG_CLK_CLKDIV1,
786 shift: 20, width: 4);
787 hws[UART1_GATE] = ma35d1_clk_gate(dev, name: "uart1_gate", parent: "uart1_div",
788 reg: clk_base + REG_CLK_APBCLK0, shift: 13);
789 hws[UART2_MUX] = ma35d1_clk_mux(dev, name: "uart2_mux", reg: clk_base + REG_CLK_CLKSEL2,
790 shift: 20, width: 2, pdata: uart_sel_clks, ARRAY_SIZE(uart_sel_clks));
791 hws[UART2_DIV] = ma35d1_clk_divider(dev, name: "uart2_div", parent: "uart2_mux",
792 reg: clk_base + REG_CLK_CLKDIV1,
793 shift: 24, width: 4);
794 hws[UART2_GATE] = ma35d1_clk_gate(dev, name: "uart2_gate", parent: "uart2_div",
795 reg: clk_base + REG_CLK_APBCLK0, shift: 14);
796 hws[UART3_MUX] = ma35d1_clk_mux(dev, name: "uart3_mux", reg: clk_base + REG_CLK_CLKSEL2,
797 shift: 22, width: 2, pdata: uart_sel_clks, ARRAY_SIZE(uart_sel_clks));
798 hws[UART3_DIV] = ma35d1_clk_divider(dev, name: "uart3_div", parent: "uart3_mux",
799 reg: clk_base + REG_CLK_CLKDIV1,
800 shift: 28, width: 4);
801 hws[UART3_GATE] = ma35d1_clk_gate(dev, name: "uart3_gate", parent: "uart3_div",
802 reg: clk_base + REG_CLK_APBCLK0, shift: 15);
803 hws[UART4_MUX] = ma35d1_clk_mux(dev, name: "uart4_mux", reg: clk_base + REG_CLK_CLKSEL2,
804 shift: 24, width: 2, pdata: uart_sel_clks, ARRAY_SIZE(uart_sel_clks));
805 hws[UART4_DIV] = ma35d1_clk_divider(dev, name: "uart4_div", parent: "uart4_mux",
806 reg: clk_base + REG_CLK_CLKDIV2,
807 shift: 0, width: 4);
808 hws[UART4_GATE] = ma35d1_clk_gate(dev, name: "uart4_gate", parent: "uart4_div",
809 reg: clk_base + REG_CLK_APBCLK0, shift: 16);
810 hws[UART5_MUX] = ma35d1_clk_mux(dev, name: "uart5_mux", reg: clk_base + REG_CLK_CLKSEL2,
811 shift: 26, width: 2, pdata: uart_sel_clks, ARRAY_SIZE(uart_sel_clks));
812 hws[UART5_DIV] = ma35d1_clk_divider(dev, name: "uart5_div", parent: "uart5_mux",
813 reg: clk_base + REG_CLK_CLKDIV2,
814 shift: 4, width: 4);
815 hws[UART5_GATE] = ma35d1_clk_gate(dev, name: "uart5_gate", parent: "uart5_div",
816 reg: clk_base + REG_CLK_APBCLK0, shift: 17);
817 hws[UART6_MUX] = ma35d1_clk_mux(dev, name: "uart6_mux", reg: clk_base + REG_CLK_CLKSEL2,
818 shift: 28, width: 2, pdata: uart_sel_clks, ARRAY_SIZE(uart_sel_clks));
819 hws[UART6_DIV] = ma35d1_clk_divider(dev, name: "uart6_div", parent: "uart6_mux",
820 reg: clk_base + REG_CLK_CLKDIV2,
821 shift: 8, width: 4);
822 hws[UART6_GATE] = ma35d1_clk_gate(dev, name: "uart6_gate", parent: "uart6_div",
823 reg: clk_base + REG_CLK_APBCLK0, shift: 18);
824 hws[UART7_MUX] = ma35d1_clk_mux(dev, name: "uart7_mux", reg: clk_base + REG_CLK_CLKSEL2,
825 shift: 30, width: 2, pdata: uart_sel_clks, ARRAY_SIZE(uart_sel_clks));
826 hws[UART7_DIV] = ma35d1_clk_divider(dev, name: "uart7_div", parent: "uart7_mux",
827 reg: clk_base + REG_CLK_CLKDIV2,
828 shift: 12, width: 4);
829 hws[UART7_GATE] = ma35d1_clk_gate(dev, name: "uart7_gate", parent: "uart7_div",
830 reg: clk_base + REG_CLK_APBCLK0, shift: 19);
831 hws[UART8_MUX] = ma35d1_clk_mux(dev, name: "uart8_mux", reg: clk_base + REG_CLK_CLKSEL3,
832 shift: 0, width: 2, pdata: uart_sel_clks, ARRAY_SIZE(uart_sel_clks));
833 hws[UART8_DIV] = ma35d1_clk_divider(dev, name: "uart8_div", parent: "uart8_mux",
834 reg: clk_base + REG_CLK_CLKDIV2,
835 shift: 16, width: 4);
836 hws[UART8_GATE] = ma35d1_clk_gate(dev, name: "uart8_gate", parent: "uart8_div",
837 reg: clk_base + REG_CLK_APBCLK0, shift: 20);
838 hws[UART9_MUX] = ma35d1_clk_mux(dev, name: "uart9_mux", reg: clk_base + REG_CLK_CLKSEL3,
839 shift: 2, width: 2, pdata: uart_sel_clks, ARRAY_SIZE(uart_sel_clks));
840 hws[UART9_DIV] = ma35d1_clk_divider(dev, name: "uart9_div", parent: "uart9_mux",
841 reg: clk_base + REG_CLK_CLKDIV2,
842 shift: 20, width: 4);
843 hws[UART9_GATE] = ma35d1_clk_gate(dev, name: "uart9_gate", parent: "uart9_div",
844 reg: clk_base + REG_CLK_APBCLK0, shift: 21);
845 hws[UART10_MUX] = ma35d1_clk_mux(dev, name: "uart10_mux", reg: clk_base + REG_CLK_CLKSEL3,
846 shift: 4, width: 2, pdata: uart_sel_clks, ARRAY_SIZE(uart_sel_clks));
847 hws[UART10_DIV] = ma35d1_clk_divider(dev, name: "uart10_div", parent: "uart10_mux",
848 reg: clk_base + REG_CLK_CLKDIV2,
849 shift: 24, width: 4);
850 hws[UART10_GATE] = ma35d1_clk_gate(dev, name: "uart10_gate", parent: "uart10_div",
851 reg: clk_base + REG_CLK_APBCLK0, shift: 22);
852 hws[UART11_MUX] = ma35d1_clk_mux(dev, name: "uart11_mux", reg: clk_base + REG_CLK_CLKSEL3,
853 shift: 6, width: 2, pdata: uart_sel_clks, ARRAY_SIZE(uart_sel_clks));
854 hws[UART11_DIV] = ma35d1_clk_divider(dev, name: "uart11_div", parent: "uart11_mux",
855 reg: clk_base + REG_CLK_CLKDIV2,
856 shift: 28, width: 4);
857 hws[UART11_GATE] = ma35d1_clk_gate(dev, name: "uart11_gate", parent: "uart11_div",
858 reg: clk_base + REG_CLK_APBCLK0, shift: 23);
859 hws[UART12_MUX] = ma35d1_clk_mux(dev, name: "uart12_mux", reg: clk_base + REG_CLK_CLKSEL3,
860 shift: 8, width: 2, pdata: uart_sel_clks, ARRAY_SIZE(uart_sel_clks));
861 hws[UART12_DIV] = ma35d1_clk_divider(dev, name: "uart12_div", parent: "uart12_mux",
862 reg: clk_base + REG_CLK_CLKDIV3,
863 shift: 0, width: 4);
864 hws[UART12_GATE] = ma35d1_clk_gate(dev, name: "uart12_gate", parent: "uart12_div",
865 reg: clk_base + REG_CLK_APBCLK0, shift: 24);
866 hws[UART13_MUX] = ma35d1_clk_mux(dev, name: "uart13_mux", reg: clk_base + REG_CLK_CLKSEL3,
867 shift: 10, width: 2, pdata: uart_sel_clks, ARRAY_SIZE(uart_sel_clks));
868 hws[UART13_DIV] = ma35d1_clk_divider(dev, name: "uart13_div", parent: "uart13_mux",
869 reg: clk_base + REG_CLK_CLKDIV3,
870 shift: 4, width: 4);
871 hws[UART13_GATE] = ma35d1_clk_gate(dev, name: "uart13_gate", parent: "uart13_div",
872 reg: clk_base + REG_CLK_APBCLK0, shift: 25);
873 hws[UART14_MUX] = ma35d1_clk_mux(dev, name: "uart14_mux", reg: clk_base + REG_CLK_CLKSEL3,
874 shift: 12, width: 2, pdata: uart_sel_clks, ARRAY_SIZE(uart_sel_clks));
875 hws[UART14_DIV] = ma35d1_clk_divider(dev, name: "uart14_div", parent: "uart14_mux",
876 reg: clk_base + REG_CLK_CLKDIV3,
877 shift: 8, width: 4);
878 hws[UART14_GATE] = ma35d1_clk_gate(dev, name: "uart14_gate", parent: "uart14_div",
879 reg: clk_base + REG_CLK_APBCLK0, shift: 26);
880 hws[UART15_MUX] = ma35d1_clk_mux(dev, name: "uart15_mux", reg: clk_base + REG_CLK_CLKSEL3,
881 shift: 14, width: 2, pdata: uart_sel_clks, ARRAY_SIZE(uart_sel_clks));
882 hws[UART15_DIV] = ma35d1_clk_divider(dev, name: "uart15_div", parent: "uart15_mux",
883 reg: clk_base + REG_CLK_CLKDIV3,
884 shift: 12, width: 4);
885 hws[UART15_GATE] = ma35d1_clk_gate(dev, name: "uart15_gate", parent: "uart15_div",
886 reg: clk_base + REG_CLK_APBCLK0, shift: 27);
887 hws[UART16_MUX] = ma35d1_clk_mux(dev, name: "uart16_mux", reg: clk_base + REG_CLK_CLKSEL3,
888 shift: 16, width: 2, pdata: uart_sel_clks, ARRAY_SIZE(uart_sel_clks));
889 hws[UART16_DIV] = ma35d1_clk_divider(dev, name: "uart16_div", parent: "uart16_mux",
890 reg: clk_base + REG_CLK_CLKDIV3,
891 shift: 16, width: 4);
892 hws[UART16_GATE] = ma35d1_clk_gate(dev, name: "uart16_gate", parent: "uart16_div",
893 reg: clk_base + REG_CLK_APBCLK0, shift: 28);
894
895 hws[RTC_GATE] = ma35d1_clk_gate(dev, name: "rtc_gate", parent: "lxt",
896 reg: clk_base + REG_CLK_APBCLK0, shift: 29);
897 hws[DDR_GATE] = ma35d1_clk_gate(dev, name: "ddr_gate", parent: "ddrpll",
898 reg: clk_base + REG_CLK_APBCLK0, shift: 30);
899
900 hws[KPI_MUX] = ma35d1_clk_mux(dev, name: "kpi_mux", reg: clk_base + REG_CLK_CLKSEL4,
901 shift: 30, width: 1, pdata: kpi_sel_clks, ARRAY_SIZE(kpi_sel_clks));
902 hws[KPI_DIV] = ma35d1_clk_divider(dev, name: "kpi_div", parent: "kpi_mux",
903 reg: clk_base + REG_CLK_CLKDIV4,
904 shift: 24, width: 8);
905 hws[KPI_GATE] = ma35d1_clk_gate(dev, name: "kpi_gate", parent: "kpi_div",
906 reg: clk_base + REG_CLK_APBCLK0, shift: 31);
907
908 hws[I2C0_GATE] = ma35d1_clk_gate(dev, name: "i2c0_gate", parent: "pclk0",
909 reg: clk_base + REG_CLK_APBCLK1, shift: 0);
910 hws[I2C1_GATE] = ma35d1_clk_gate(dev, name: "i2c1_gate", parent: "pclk1",
911 reg: clk_base + REG_CLK_APBCLK1, shift: 1);
912 hws[I2C2_GATE] = ma35d1_clk_gate(dev, name: "i2c2_gate", parent: "pclk2",
913 reg: clk_base + REG_CLK_APBCLK1, shift: 2);
914 hws[I2C3_GATE] = ma35d1_clk_gate(dev, name: "i2c3_gate", parent: "pclk0",
915 reg: clk_base + REG_CLK_APBCLK1, shift: 3);
916 hws[I2C4_GATE] = ma35d1_clk_gate(dev, name: "i2c4_gate", parent: "pclk1",
917 reg: clk_base + REG_CLK_APBCLK1, shift: 4);
918 hws[I2C5_GATE] = ma35d1_clk_gate(dev, name: "i2c5_gate", parent: "pclk2",
919 reg: clk_base + REG_CLK_APBCLK1, shift: 5);
920
921 hws[QSPI0_MUX] = ma35d1_clk_mux(dev, name: "qspi0_mux", reg: clk_base + REG_CLK_CLKSEL4,
922 shift: 8, width: 2, pdata: qspi0_sel_clks, ARRAY_SIZE(qspi0_sel_clks));
923 hws[QSPI0_GATE] = ma35d1_clk_gate(dev, name: "qspi0_gate", parent: "qspi0_mux",
924 reg: clk_base + REG_CLK_APBCLK1, shift: 6);
925 hws[QSPI1_MUX] = ma35d1_clk_mux(dev, name: "qspi1_mux", reg: clk_base + REG_CLK_CLKSEL4,
926 shift: 10, width: 2, pdata: qspi1_sel_clks, ARRAY_SIZE(qspi1_sel_clks));
927 hws[QSPI1_GATE] = ma35d1_clk_gate(dev, name: "qspi1_gate", parent: "qspi1_mux",
928 reg: clk_base + REG_CLK_APBCLK1, shift: 7);
929
930 hws[SMC0_MUX] = ma35d1_clk_mux(dev, name: "smc0_mux", reg: clk_base + REG_CLK_CLKSEL4,
931 shift: 28, width: 1, pdata: smc_sel_clks, ARRAY_SIZE(smc_sel_clks));
932 hws[SMC0_DIV] = ma35d1_clk_divider(dev, name: "smc0_div", parent: "smc0_mux",
933 reg: clk_base + REG_CLK_CLKDIV1,
934 shift: 0, width: 4);
935 hws[SMC0_GATE] = ma35d1_clk_gate(dev, name: "smc0_gate", parent: "smc0_div",
936 reg: clk_base + REG_CLK_APBCLK1, shift: 12);
937 hws[SMC1_MUX] = ma35d1_clk_mux(dev, name: "smc1_mux", reg: clk_base + REG_CLK_CLKSEL4,
938 shift: 29, width: 1, pdata: smc_sel_clks, ARRAY_SIZE(smc_sel_clks));
939 hws[SMC1_DIV] = ma35d1_clk_divider(dev, name: "smc1_div", parent: "smc1_mux",
940 reg: clk_base + REG_CLK_CLKDIV1,
941 shift: 4, width: 4);
942 hws[SMC1_GATE] = ma35d1_clk_gate(dev, name: "smc1_gate", parent: "smc1_div",
943 reg: clk_base + REG_CLK_APBCLK1, shift: 13);
944
945 hws[WDT0_MUX] = ma35d1_clk_mux(dev, name: "wdt0_mux", reg: clk_base + REG_CLK_CLKSEL3,
946 shift: 20, width: 2, pdata: wdt0_sel_clks, ARRAY_SIZE(wdt0_sel_clks));
947 hws[WDT0_GATE] = ma35d1_clk_gate(dev, name: "wdt0_gate", parent: "wdt0_mux",
948 reg: clk_base + REG_CLK_APBCLK1, shift: 16);
949 hws[WDT1_MUX] = ma35d1_clk_mux(dev, name: "wdt1_mux", reg: clk_base + REG_CLK_CLKSEL3,
950 shift: 24, width: 2, pdata: wdt1_sel_clks, ARRAY_SIZE(wdt1_sel_clks));
951 hws[WDT1_GATE] = ma35d1_clk_gate(dev, name: "wdt1_gate", parent: "wdt1_mux",
952 reg: clk_base + REG_CLK_APBCLK1, shift: 17);
953 hws[WDT2_MUX] = ma35d1_clk_mux(dev, name: "wdt2_mux", reg: clk_base + REG_CLK_CLKSEL3,
954 shift: 28, width: 2, pdata: wdt2_sel_clks, ARRAY_SIZE(wdt2_sel_clks));
955 hws[WDT2_GATE] = ma35d1_clk_gate(dev, name: "wdt2_gate", parent: "wdt2_mux",
956 reg: clk_base + REG_CLK_APBCLK1, shift: 18);
957
958 hws[WWDT0_MUX] = ma35d1_clk_mux(dev, name: "wwdt0_mux", reg: clk_base + REG_CLK_CLKSEL3,
959 shift: 22, width: 2, pdata: wwdt0_sel_clks, ARRAY_SIZE(wwdt0_sel_clks));
960 hws[WWDT1_MUX] = ma35d1_clk_mux(dev, name: "wwdt1_mux", reg: clk_base + REG_CLK_CLKSEL3,
961 shift: 26, width: 2, pdata: wwdt1_sel_clks, ARRAY_SIZE(wwdt1_sel_clks));
962 hws[WWDT2_MUX] = ma35d1_clk_mux(dev, name: "wwdt2_mux", reg: clk_base + REG_CLK_CLKSEL3,
963 shift: 30, width: 2, pdata: wwdt2_sel_clks, ARRAY_SIZE(wwdt2_sel_clks));
964
965 hws[EPWM0_GATE] = ma35d1_clk_gate(dev, name: "epwm0_gate", parent: "pclk1",
966 reg: clk_base + REG_CLK_APBCLK1, shift: 24);
967 hws[EPWM1_GATE] = ma35d1_clk_gate(dev, name: "epwm1_gate", parent: "pclk2",
968 reg: clk_base + REG_CLK_APBCLK1, shift: 25);
969 hws[EPWM2_GATE] = ma35d1_clk_gate(dev, name: "epwm2_gate", parent: "pclk1",
970 reg: clk_base + REG_CLK_APBCLK1, shift: 26);
971
972 hws[I2S0_MUX] = ma35d1_clk_mux(dev, name: "i2s0_mux", reg: clk_base + REG_CLK_CLKSEL4,
973 shift: 12, width: 2, pdata: i2s0_sel_clks, ARRAY_SIZE(i2s0_sel_clks));
974 hws[I2S0_GATE] = ma35d1_clk_gate(dev, name: "i2s0_gate", parent: "i2s0_mux",
975 reg: clk_base + REG_CLK_APBCLK2, shift: 0);
976 hws[I2S1_MUX] = ma35d1_clk_mux(dev, name: "i2s1_mux", reg: clk_base + REG_CLK_CLKSEL4,
977 shift: 14, width: 2, pdata: i2s1_sel_clks, ARRAY_SIZE(i2s1_sel_clks));
978 hws[I2S1_GATE] = ma35d1_clk_gate(dev, name: "i2s1_gate", parent: "i2s1_mux",
979 reg: clk_base + REG_CLK_APBCLK2, shift: 1);
980
981 hws[SSMCC_GATE] = ma35d1_clk_gate(dev, name: "ssmcc_gate", parent: "pclk3",
982 reg: clk_base + REG_CLK_APBCLK2, shift: 2);
983 hws[SSPCC_GATE] = ma35d1_clk_gate(dev, name: "sspcc_gate", parent: "pclk3",
984 reg: clk_base + REG_CLK_APBCLK2, shift: 3);
985
986 hws[SPI0_MUX] = ma35d1_clk_mux(dev, name: "spi0_mux", reg: clk_base + REG_CLK_CLKSEL4,
987 shift: 0, width: 2, pdata: spi0_sel_clks, ARRAY_SIZE(spi0_sel_clks));
988 hws[SPI0_GATE] = ma35d1_clk_gate(dev, name: "spi0_gate", parent: "spi0_mux",
989 reg: clk_base + REG_CLK_APBCLK2, shift: 4);
990 hws[SPI1_MUX] = ma35d1_clk_mux(dev, name: "spi1_mux", reg: clk_base + REG_CLK_CLKSEL4,
991 shift: 2, width: 2, pdata: spi1_sel_clks, ARRAY_SIZE(spi1_sel_clks));
992 hws[SPI1_GATE] = ma35d1_clk_gate(dev, name: "spi1_gate", parent: "spi1_mux",
993 reg: clk_base + REG_CLK_APBCLK2, shift: 5);
994 hws[SPI2_MUX] = ma35d1_clk_mux(dev, name: "spi2_mux", reg: clk_base + REG_CLK_CLKSEL4,
995 shift: 4, width: 2, pdata: spi2_sel_clks, ARRAY_SIZE(spi2_sel_clks));
996 hws[SPI2_GATE] = ma35d1_clk_gate(dev, name: "spi2_gate", parent: "spi2_mux",
997 reg: clk_base + REG_CLK_APBCLK2, shift: 6);
998 hws[SPI3_MUX] = ma35d1_clk_mux(dev, name: "spi3_mux", reg: clk_base + REG_CLK_CLKSEL4,
999 shift: 6, width: 2, pdata: spi3_sel_clks, ARRAY_SIZE(spi3_sel_clks));
1000 hws[SPI3_GATE] = ma35d1_clk_gate(dev, name: "spi3_gate", parent: "spi3_mux",
1001 reg: clk_base + REG_CLK_APBCLK2, shift: 7);
1002
1003 hws[ECAP0_GATE] = ma35d1_clk_gate(dev, name: "ecap0_gate", parent: "pclk1",
1004 reg: clk_base + REG_CLK_APBCLK2, shift: 8);
1005 hws[ECAP1_GATE] = ma35d1_clk_gate(dev, name: "ecap1_gate", parent: "pclk2",
1006 reg: clk_base + REG_CLK_APBCLK2, shift: 9);
1007 hws[ECAP2_GATE] = ma35d1_clk_gate(dev, name: "ecap2_gate", parent: "pclk1",
1008 reg: clk_base + REG_CLK_APBCLK2, shift: 10);
1009
1010 hws[QEI0_GATE] = ma35d1_clk_gate(dev, name: "qei0_gate", parent: "pclk1",
1011 reg: clk_base + REG_CLK_APBCLK2, shift: 12);
1012 hws[QEI1_GATE] = ma35d1_clk_gate(dev, name: "qei1_gate", parent: "pclk2",
1013 reg: clk_base + REG_CLK_APBCLK2, shift: 13);
1014 hws[QEI2_GATE] = ma35d1_clk_gate(dev, name: "qei2_gate", parent: "pclk1",
1015 reg: clk_base + REG_CLK_APBCLK2, shift: 14);
1016
1017 hws[ADC_DIV] = ma35d1_reg_adc_clkdiv(dev, name: "adc_div", parent_hw: hws[PCLK0],
1018 lock: &ma35d1_lock, flags: 0,
1019 reg: clk_base + REG_CLK_CLKDIV4,
1020 shift: 4, width: 17, mask_bit: 0x1ffff);
1021 hws[ADC_GATE] = ma35d1_clk_gate(dev, name: "adc_gate", parent: "adc_div",
1022 reg: clk_base + REG_CLK_APBCLK2, shift: 24);
1023
1024 hws[EADC_DIV] = ma35d1_clk_divider_table(dev, name: "eadc_div", parent: "pclk2",
1025 reg: clk_base + REG_CLK_CLKDIV4,
1026 shift: 0, width: 4, table: eadc_div_table);
1027 hws[EADC_GATE] = ma35d1_clk_gate(dev, name: "eadc_gate", parent: "eadc_div",
1028 reg: clk_base + REG_CLK_APBCLK2, shift: 25);
1029
1030 return devm_of_clk_add_hw_provider(dev,
1031 get: of_clk_hw_onecell_get,
1032 data: ma35d1_hw_data);
1033}
1034
1035static const struct of_device_id ma35d1_clk_of_match[] = {
1036 { .compatible = "nuvoton,ma35d1-clk" },
1037 { }
1038};
1039MODULE_DEVICE_TABLE(of, ma35d1_clk_of_match);
1040
1041static struct platform_driver ma35d1_clk_driver = {
1042 .probe = ma35d1_clocks_probe,
1043 .driver = {
1044 .name = "ma35d1-clk",
1045 .of_match_table = ma35d1_clk_of_match,
1046 },
1047};
1048
1049static int __init ma35d1_clocks_init(void)
1050{
1051 return platform_driver_register(&ma35d1_clk_driver);
1052}
1053
1054postcore_initcall(ma35d1_clocks_init);
1055
1056MODULE_AUTHOR("Chi-Fang Li <cfli0@nuvoton.com>");
1057MODULE_DESCRIPTION("NUVOTON MA35D1 Clock Driver");
1058MODULE_LICENSE("GPL");
1059

source code of linux/drivers/clk/nuvoton/clk-ma35d1.c