GNU Linux-libre 6.8.9-gnu
[releases.git] / drivers / clk / clk-sp7021.c
1 // SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
2 /*
3  * Copyright (C) Sunplus Technology Co., Ltd.
4  *       All rights reserved.
5  */
6 #include <linux/module.h>
7 #include <linux/clk-provider.h>
8 #include <linux/of.h>
9 #include <linux/bitfield.h>
10 #include <linux/slab.h>
11 #include <linux/io.h>
12 #include <linux/err.h>
13 #include <linux/platform_device.h>
14
15 #include <dt-bindings/clock/sunplus,sp7021-clkc.h>
16
17 /* speical div_width values for PLLTV/PLLA */
18 #define DIV_TV          33
19 #define DIV_A           34
20
21 /* PLLTV parameters */
22 enum {
23         SEL_FRA,
24         SDM_MOD,
25         PH_SEL,
26         NFRA,
27         DIVR,
28         DIVN,
29         DIVM,
30         P_MAX
31 };
32
33 #define MASK_SEL_FRA    GENMASK(1, 1)
34 #define MASK_SDM_MOD    GENMASK(2, 2)
35 #define MASK_PH_SEL     GENMASK(4, 4)
36 #define MASK_NFRA       GENMASK(12, 6)
37 #define MASK_DIVR       GENMASK(8, 7)
38 #define MASK_DIVN       GENMASK(7, 0)
39 #define MASK_DIVM       GENMASK(14, 8)
40
41 /* HIWORD_MASK FIELD_PREP */
42 #define HWM_FIELD_PREP(mask, value)             \
43 ({                                              \
44         u64 _m = mask;                          \
45         (_m << 16) | FIELD_PREP(_m, value);     \
46 })
47
48 struct sp_pll {
49         struct clk_hw hw;
50         void __iomem *reg;
51         spinlock_t lock;        /* lock for reg */
52         int div_shift;
53         int div_width;
54         int pd_bit;             /* power down bit idx */
55         int bp_bit;             /* bypass bit idx */
56         unsigned long brate;    /* base rate, TODO: replace brate with muldiv */
57         u32 p[P_MAX];           /* for hold PLLTV/PLLA parameters */
58 };
59
60 #define to_sp_pll(_hw)  container_of(_hw, struct sp_pll, hw)
61
62 struct sp_clk_gate_info {
63         u16     reg;            /* reg_index_shift */
64         u16     ext_parent;     /* parent is extclk */
65 };
66
67 static const struct sp_clk_gate_info sp_clk_gates[] = {
68         { 0x02 },
69         { 0x05 },
70         { 0x06 },
71         { 0x07 },
72         { 0x09 },
73         { 0x0b, 1 },
74         { 0x0f, 1 },
75         { 0x14 },
76         { 0x15 },
77         { 0x16 },
78         { 0x17 },
79         { 0x18, 1 },
80         { 0x19, 1 },
81         { 0x1a, 1 },
82         { 0x1b, 1 },
83         { 0x1c, 1 },
84         { 0x1d, 1 },
85         { 0x1e },
86         { 0x1f, 1 },
87         { 0x20 },
88         { 0x21 },
89         { 0x22 },
90         { 0x23 },
91         { 0x24 },
92         { 0x25 },
93         { 0x26 },
94         { 0x2a },
95         { 0x2b },
96         { 0x2d },
97         { 0x2e },
98         { 0x30 },
99         { 0x31 },
100         { 0x32 },
101         { 0x33 },
102         { 0x3d },
103         { 0x3e },
104         { 0x3f },
105         { 0x42 },
106         { 0x44 },
107         { 0x4b },
108         { 0x4c },
109         { 0x4d },
110         { 0x4e },
111         { 0x4f },
112         { 0x50 },
113         { 0x55 },
114         { 0x60 },
115         { 0x61 },
116         { 0x6a },
117         { 0x73 },
118         { 0x86 },
119         { 0x8a },
120         { 0x8b },
121         { 0x8d },
122         { 0x8e },
123         { 0x8f },
124         { 0x90 },
125         { 0x92 },
126         { 0x93 },
127         { 0x95 },
128         { 0x96 },
129         { 0x97 },
130         { 0x98 },
131         { 0x99 },
132 };
133
134 #define _M              1000000UL
135 #define F_27M           (27 * _M)
136
137 /*********************************** PLL_TV **********************************/
138
139 /* TODO: set proper FVCO range */
140 #define FVCO_MIN        (100 * _M)
141 #define FVCO_MAX        (200 * _M)
142
143 #define F_MIN           (FVCO_MIN / 8)
144 #define F_MAX           (FVCO_MAX)
145
146 static long plltv_integer_div(struct sp_pll *clk, unsigned long freq)
147 {
148         /* valid m values: 27M must be divisible by m */
149         static const u32 m_table[] = {
150                 1, 2, 3, 4, 5, 6, 8, 9, 10, 12, 15, 16, 18, 20, 24, 25, 27, 30, 32
151         };
152         u32 m, n, r;
153         unsigned long fvco, nf;
154         long ret;
155
156         freq = clamp(freq, F_MIN, F_MAX);
157
158         /* DIVR 0~3 */
159         for (r = 0; r <= 3; r++) {
160                 fvco = freq << r;
161                 if (fvco <= FVCO_MAX)
162                         break;
163         }
164
165         /* DIVM */
166         for (m = 0; m < ARRAY_SIZE(m_table); m++) {
167                 nf = fvco * m_table[m];
168                 n = nf / F_27M;
169                 if ((n * F_27M) == nf)
170                         break;
171         }
172         if (m >= ARRAY_SIZE(m_table)) {
173                 ret = -EINVAL;
174                 goto err_not_found;
175         }
176
177         /* save parameters */
178         clk->p[SEL_FRA] = 0;
179         clk->p[DIVR]    = r;
180         clk->p[DIVN]    = n;
181         clk->p[DIVM]    = m_table[m];
182
183         return freq;
184
185 err_not_found:
186         pr_err("%s: %s freq:%lu not found a valid setting\n",
187                __func__, clk_hw_get_name(&clk->hw), freq);
188
189         return ret;
190 }
191
192 /* parameters for PLLTV fractional divider */
193 static const u32 pt[][5] = {
194         /* conventional fractional */
195         {
196                 1,                      /* factor */
197                 5,                      /* 5 * p0 (nint) */
198                 1,                      /* 1 * p0 */
199                 F_27M,                  /* F_27M / p0 */
200                 1,                      /* p0 / p2 */
201         },
202         /* phase rotation */
203         {
204                 10,                     /* factor */
205                 54,                     /* 5.4 * p0 (nint) */
206                 2,                      /* 0.2 * p0 */
207                 F_27M / 10,             /* F_27M / p0 */
208                 5,                      /* p0 / p2 */
209         },
210 };
211
212 static const u32 sdm_mod_vals[] = { 91, 55 };
213
214 static long plltv_fractional_div(struct sp_pll *clk, unsigned long freq)
215 {
216         u32 m, r;
217         u32 nint, nfra;
218         u32 df_quotient_min = 210000000;
219         u32 df_remainder_min = 0;
220         unsigned long fvco, nf, f, fout = 0;
221         int sdm, ph;
222
223         freq = clamp(freq, F_MIN, F_MAX);
224
225         /* DIVR 0~3 */
226         for (r = 0; r <= 3; r++) {
227                 fvco = freq << r;
228                 if (fvco <= FVCO_MAX)
229                         break;
230         }
231         f = F_27M >> r;
232
233         /* PH_SEL */
234         for (ph = ARRAY_SIZE(pt) - 1; ph >= 0; ph--) {
235                 const u32 *pp = pt[ph];
236
237                 /* SDM_MOD */
238                 for (sdm = 0; sdm < ARRAY_SIZE(sdm_mod_vals); sdm++) {
239                         u32 mod = sdm_mod_vals[sdm];
240
241                         /* DIVM 1~32 */
242                         for (m = 1; m <= 32; m++) {
243                                 u32 df; /* diff freq */
244                                 u32 df_quotient, df_remainder;
245
246                                 nf = fvco * m;
247                                 nint = nf / pp[3];
248
249                                 if (nint < pp[1])
250                                         continue;
251                                 if (nint > pp[1])
252                                         break;
253
254                                 nfra = (((nf % pp[3]) * mod * pp[4]) + (F_27M / 2)) / F_27M;
255                                 if (nfra) {
256                                         u32 df0 = f * (nint + pp[2]) / pp[0];
257                                         u32 df1 = f * (mod - nfra) / mod / pp[4];
258
259                                         df = df0 - df1;
260                                 } else {
261                                         df = f * (nint) / pp[0];
262                                 }
263
264                                 df_quotient  = df / m;
265                                 df_remainder = ((df % m) * 1000) / m;
266
267                                 if (freq > df_quotient) {
268                                         df_quotient  = freq - df_quotient - 1;
269                                         df_remainder = 1000 - df_remainder;
270                                 } else {
271                                         df_quotient = df_quotient - freq;
272                                 }
273
274                                 if (df_quotient_min > df_quotient ||
275                                     (df_quotient_min == df_quotient &&
276                                     df_remainder_min > df_remainder)) {
277                                         /* found a closer freq, save parameters */
278                                         clk->p[SEL_FRA] = 1;
279                                         clk->p[SDM_MOD] = sdm;
280                                         clk->p[PH_SEL]  = ph;
281                                         clk->p[NFRA]    = nfra;
282                                         clk->p[DIVR]    = r;
283                                         clk->p[DIVM]    = m;
284
285                                         fout = df / m;
286                                         df_quotient_min = df_quotient;
287                                         df_remainder_min = df_remainder;
288                                 }
289                         }
290                 }
291         }
292
293         if (!fout) {
294                 pr_err("%s: %s freq:%lu not found a valid setting\n",
295                        __func__, clk_hw_get_name(&clk->hw), freq);
296                 return -EINVAL;
297         }
298
299         return fout;
300 }
301
302 static long plltv_div(struct sp_pll *clk, unsigned long freq)
303 {
304         if (freq % 100)
305                 return plltv_fractional_div(clk, freq);
306
307         return plltv_integer_div(clk, freq);
308 }
309
310 static int plltv_set_rate(struct sp_pll *clk)
311 {
312         unsigned long flags;
313         u32 r0, r1, r2;
314
315         r0  = BIT(clk->bp_bit + 16);
316         r0 |= HWM_FIELD_PREP(MASK_SEL_FRA, clk->p[SEL_FRA]);
317         r0 |= HWM_FIELD_PREP(MASK_SDM_MOD, clk->p[SDM_MOD]);
318         r0 |= HWM_FIELD_PREP(MASK_PH_SEL, clk->p[PH_SEL]);
319         r0 |= HWM_FIELD_PREP(MASK_NFRA, clk->p[NFRA]);
320
321         r1  = HWM_FIELD_PREP(MASK_DIVR, clk->p[DIVR]);
322
323         r2  = HWM_FIELD_PREP(MASK_DIVN, clk->p[DIVN] - 1);
324         r2 |= HWM_FIELD_PREP(MASK_DIVM, clk->p[DIVM] - 1);
325
326         spin_lock_irqsave(&clk->lock, flags);
327         writel(r0, clk->reg);
328         writel(r1, clk->reg + 4);
329         writel(r2, clk->reg + 8);
330         spin_unlock_irqrestore(&clk->lock, flags);
331
332         return 0;
333 }
334
335 /*********************************** PLL_A ***********************************/
336
337 /* from Q628_PLLs_REG_setting.xlsx */
338 static const struct {
339         u32 rate;
340         u32 regs[5];
341 } pa[] = {
342         {
343                 .rate = 135475200,
344                 .regs = {
345                         0x4801,
346                         0x02df,
347                         0x248f,
348                         0x0211,
349                         0x33e9
350                 }
351         },
352         {
353                 .rate = 147456000,
354                 .regs = {
355                         0x4801,
356                         0x1adf,
357                         0x2490,
358                         0x0349,
359                         0x33e9
360                 }
361         },
362         {
363                 .rate = 196608000,
364                 .regs = {
365                         0x4801,
366                         0x42ef,
367                         0x2495,
368                         0x01c6,
369                         0x33e9
370                 }
371         },
372 };
373
374 static int plla_set_rate(struct sp_pll *clk)
375 {
376         const u32 *pp = pa[clk->p[0]].regs;
377         unsigned long flags;
378         int i;
379
380         spin_lock_irqsave(&clk->lock, flags);
381         for (i = 0; i < ARRAY_SIZE(pa->regs); i++)
382                 writel(0xffff0000 | pp[i], clk->reg + (i * 4));
383         spin_unlock_irqrestore(&clk->lock, flags);
384
385         return 0;
386 }
387
388 static long plla_round_rate(struct sp_pll *clk, unsigned long rate)
389 {
390         int i = ARRAY_SIZE(pa);
391
392         while (--i) {
393                 if (rate >= pa[i].rate)
394                         break;
395         }
396         clk->p[0] = i;
397
398         return pa[i].rate;
399 }
400
401 /********************************** SP_PLL ***********************************/
402
403 static long sp_pll_calc_div(struct sp_pll *clk, unsigned long rate)
404 {
405         u32 fbdiv;
406         u32 max = 1 << clk->div_width;
407
408         fbdiv = DIV_ROUND_CLOSEST(rate, clk->brate);
409         if (fbdiv > max)
410                 fbdiv = max;
411
412         return fbdiv;
413 }
414
415 static long sp_pll_round_rate(struct clk_hw *hw, unsigned long rate,
416                               unsigned long *prate)
417 {
418         struct sp_pll *clk = to_sp_pll(hw);
419         long ret;
420
421         if (rate == *prate) {
422                 ret = *prate; /* bypass */
423         } else if (clk->div_width == DIV_A) {
424                 ret = plla_round_rate(clk, rate);
425         } else if (clk->div_width == DIV_TV) {
426                 ret = plltv_div(clk, rate);
427                 if (ret < 0)
428                         ret = *prate;
429         } else {
430                 ret = sp_pll_calc_div(clk, rate) * clk->brate;
431         }
432
433         return ret;
434 }
435
436 static unsigned long sp_pll_recalc_rate(struct clk_hw *hw,
437                                         unsigned long prate)
438 {
439         struct sp_pll *clk = to_sp_pll(hw);
440         u32 reg = readl(clk->reg);
441         unsigned long ret;
442
443         if (reg & BIT(clk->bp_bit)) {
444                 ret = prate; /* bypass */
445         } else if (clk->div_width == DIV_A) {
446                 ret = pa[clk->p[0]].rate;
447         } else if (clk->div_width == DIV_TV) {
448                 u32 m, r, reg2;
449
450                 r = FIELD_GET(MASK_DIVR, readl(clk->reg + 4));
451                 reg2 = readl(clk->reg + 8);
452                 m = FIELD_GET(MASK_DIVM, reg2) + 1;
453
454                 if (reg & MASK_SEL_FRA) {
455                         /* fractional divider */
456                         u32 sdm  = FIELD_GET(MASK_SDM_MOD, reg);
457                         u32 ph   = FIELD_GET(MASK_PH_SEL, reg);
458                         u32 nfra = FIELD_GET(MASK_NFRA, reg);
459                         const u32 *pp = pt[ph];
460                         unsigned long r0, r1;
461
462                         ret = prate >> r;
463                         r0  = ret * (pp[1] + pp[2]) / pp[0];
464                         r1  = ret * (sdm_mod_vals[sdm] - nfra) / sdm_mod_vals[sdm] / pp[4];
465                         ret = (r0 - r1) / m;
466                 } else {
467                         /* integer divider */
468                         u32 n = FIELD_GET(MASK_DIVN, reg2) + 1;
469
470                         ret = (prate / m * n) >> r;
471                 }
472         } else {
473                 u32 fbdiv = ((reg >> clk->div_shift) & ((1 << clk->div_width) - 1)) + 1;
474
475                 ret = clk->brate * fbdiv;
476         }
477
478         return ret;
479 }
480
481 static int sp_pll_set_rate(struct clk_hw *hw, unsigned long rate,
482                            unsigned long prate)
483 {
484         struct sp_pll *clk = to_sp_pll(hw);
485         unsigned long flags;
486         u32 reg;
487
488         reg = BIT(clk->bp_bit + 16); /* HIWORD_MASK */
489
490         if (rate == prate) {
491                 reg |= BIT(clk->bp_bit); /* bypass */
492         } else if (clk->div_width == DIV_A) {
493                 return plla_set_rate(clk);
494         } else if (clk->div_width == DIV_TV) {
495                 return plltv_set_rate(clk);
496         } else if (clk->div_width) {
497                 u32 fbdiv = sp_pll_calc_div(clk, rate);
498                 u32 mask = GENMASK(clk->div_shift + clk->div_width - 1, clk->div_shift);
499
500                 reg |= mask << 16;
501                 reg |= ((fbdiv - 1) << clk->div_shift) & mask;
502         }
503
504         spin_lock_irqsave(&clk->lock, flags);
505         writel(reg, clk->reg);
506         spin_unlock_irqrestore(&clk->lock, flags);
507
508         return 0;
509 }
510
511 static int sp_pll_enable(struct clk_hw *hw)
512 {
513         struct sp_pll *clk = to_sp_pll(hw);
514
515         writel(BIT(clk->pd_bit + 16) | BIT(clk->pd_bit), clk->reg);
516
517         return 0;
518 }
519
520 static void sp_pll_disable(struct clk_hw *hw)
521 {
522         struct sp_pll *clk = to_sp_pll(hw);
523
524         writel(BIT(clk->pd_bit + 16), clk->reg);
525 }
526
527 static int sp_pll_is_enabled(struct clk_hw *hw)
528 {
529         struct sp_pll *clk = to_sp_pll(hw);
530
531         return readl(clk->reg) & BIT(clk->pd_bit);
532 }
533
534 static const struct clk_ops sp_pll_ops = {
535         .enable = sp_pll_enable,
536         .disable = sp_pll_disable,
537         .is_enabled = sp_pll_is_enabled,
538         .round_rate = sp_pll_round_rate,
539         .recalc_rate = sp_pll_recalc_rate,
540         .set_rate = sp_pll_set_rate
541 };
542
543 static const struct clk_ops sp_pll_sub_ops = {
544         .enable = sp_pll_enable,
545         .disable = sp_pll_disable,
546         .is_enabled = sp_pll_is_enabled,
547         .recalc_rate = sp_pll_recalc_rate,
548 };
549
550 static struct clk_hw *sp_pll_register(struct device *dev, const char *name,
551                                       const struct clk_parent_data *parent_data,
552                                       void __iomem *reg, int pd_bit, int bp_bit,
553                                       unsigned long brate, int shift, int width,
554                                       unsigned long flags)
555 {
556         struct sp_pll *pll;
557         struct clk_hw *hw;
558         struct clk_init_data initd = {
559                 .name = name,
560                 .parent_data = parent_data,
561                 .ops = (bp_bit >= 0) ? &sp_pll_ops : &sp_pll_sub_ops,
562                 .num_parents = 1,
563                 .flags = flags,
564         };
565         int ret;
566
567         pll = devm_kzalloc(dev, sizeof(*pll), GFP_KERNEL);
568         if (!pll)
569                 return ERR_PTR(-ENOMEM);
570
571         pll->hw.init = &initd;
572         pll->reg = reg;
573         pll->pd_bit = pd_bit;
574         pll->bp_bit = bp_bit;
575         pll->brate = brate;
576         pll->div_shift = shift;
577         pll->div_width = width;
578         spin_lock_init(&pll->lock);
579
580         hw = &pll->hw;
581         ret = devm_clk_hw_register(dev, hw);
582         if (ret)
583                 return ERR_PTR(ret);
584
585         return hw;
586 }
587
588 #define PLLA_CTL        (pll_base + 0x1c)
589 #define PLLE_CTL        (pll_base + 0x30)
590 #define PLLF_CTL        (pll_base + 0x34)
591 #define PLLTV_CTL       (pll_base + 0x38)
592
593 static int sp7021_clk_probe(struct platform_device *pdev)
594 {
595         static const u32 sp_clken[] = {
596                 0x67ef, 0x03ff, 0xff03, 0xfff0, 0x0004, /* G0.1~5  */
597                 0x0000, 0x8000, 0xffff, 0x0040, 0x0000, /* G0.6~10 */
598         };
599         static struct clk_parent_data pd_ext, pd_sys, pd_e;
600         struct device *dev = &pdev->dev;
601         void __iomem *clk_base, *pll_base, *sys_base;
602         struct clk_hw_onecell_data *clk_data;
603         struct clk_hw **hws;
604         int i;
605
606         clk_base = devm_platform_ioremap_resource(pdev, 0);
607         if (IS_ERR(clk_base))
608                 return PTR_ERR(clk_base);
609         pll_base = devm_platform_ioremap_resource(pdev, 1);
610         if (IS_ERR(pll_base))
611                 return PTR_ERR(pll_base);
612         sys_base = devm_platform_ioremap_resource(pdev, 2);
613         if (IS_ERR(sys_base))
614                 return PTR_ERR(sys_base);
615
616         /* enable default clks */
617         for (i = 0; i < ARRAY_SIZE(sp_clken); i++)
618                 writel((sp_clken[i] << 16) | sp_clken[i], clk_base + i * 4);
619
620         clk_data = devm_kzalloc(dev, struct_size(clk_data, hws, CLK_MAX),
621                                 GFP_KERNEL);
622         if (!clk_data)
623                 return -ENOMEM;
624         clk_data->num = CLK_MAX;
625
626         hws = clk_data->hws;
627         pd_ext.index = 0;
628
629         /* PLLs */
630         hws[PLL_A] = sp_pll_register(dev, "plla", &pd_ext, PLLA_CTL,
631                                      11, 12, 27000000, 0, DIV_A, 0);
632         if (IS_ERR(hws[PLL_A]))
633                 return PTR_ERR(hws[PLL_A]);
634
635         hws[PLL_E] = sp_pll_register(dev, "plle", &pd_ext, PLLE_CTL,
636                                      6, 2, 50000000, 0, 0, 0);
637         if (IS_ERR(hws[PLL_E]))
638                 return PTR_ERR(hws[PLL_E]);
639         pd_e.hw = hws[PLL_E];
640         hws[PLL_E_2P5] = sp_pll_register(dev, "plle_2p5", &pd_e, PLLE_CTL,
641                                          13, -1, 2500000, 0, 0, 0);
642         if (IS_ERR(hws[PLL_E_2P5]))
643                 return PTR_ERR(hws[PLL_E_2P5]);
644         hws[PLL_E_25] = sp_pll_register(dev, "plle_25", &pd_e, PLLE_CTL,
645                                         12, -1, 25000000, 0, 0, 0);
646         if (IS_ERR(hws[PLL_E_25]))
647                 return PTR_ERR(hws[PLL_E_25]);
648         hws[PLL_E_112P5] = sp_pll_register(dev, "plle_112p5", &pd_e, PLLE_CTL,
649                                            11, -1, 112500000, 0, 0, 0);
650         if (IS_ERR(hws[PLL_E_112P5]))
651                 return PTR_ERR(hws[PLL_E_112P5]);
652
653         hws[PLL_F] = sp_pll_register(dev, "pllf", &pd_ext, PLLF_CTL,
654                                      0, 10, 13500000, 1, 4, 0);
655         if (IS_ERR(hws[PLL_F]))
656                 return PTR_ERR(hws[PLL_F]);
657
658         hws[PLL_TV] = sp_pll_register(dev, "plltv", &pd_ext, PLLTV_CTL,
659                                       0, 15, 27000000, 0, DIV_TV, 0);
660         if (IS_ERR(hws[PLL_TV]))
661                 return PTR_ERR(hws[PLL_TV]);
662         hws[PLL_TV_A] = devm_clk_hw_register_divider(dev, "plltv_a", "plltv", 0,
663                                                      PLLTV_CTL + 4, 5, 1,
664                                                      CLK_DIVIDER_POWER_OF_TWO,
665                                                      &to_sp_pll(hws[PLL_TV])->lock);
666         if (IS_ERR(hws[PLL_TV_A]))
667                 return PTR_ERR(hws[PLL_TV_A]);
668
669         /* system clock, should not be disabled */
670         hws[PLL_SYS] = sp_pll_register(dev, "pllsys", &pd_ext, sys_base,
671                                        10, 9, 13500000, 0, 4, CLK_IS_CRITICAL);
672         if (IS_ERR(hws[PLL_SYS]))
673                 return PTR_ERR(hws[PLL_SYS]);
674         pd_sys.hw = hws[PLL_SYS];
675
676         /* gates */
677         for (i = 0; i < ARRAY_SIZE(sp_clk_gates); i++) {
678                 char name[10];
679                 u32 j = sp_clk_gates[i].reg;
680                 struct clk_parent_data *pd = sp_clk_gates[i].ext_parent ? &pd_ext : &pd_sys;
681
682                 sprintf(name, "%02d_0x%02x", i, j);
683                 hws[i] = devm_clk_hw_register_gate_parent_data(dev, name, pd, 0,
684                                                                clk_base + (j >> 4) * 4,
685                                                                j & 0x0f,
686                                                                CLK_GATE_HIWORD_MASK,
687                                                                NULL);
688                 if (IS_ERR(hws[i]))
689                         return PTR_ERR(hws[i]);
690         }
691
692         return devm_of_clk_add_hw_provider(dev, of_clk_hw_onecell_get, clk_data);
693 }
694
695 static const struct of_device_id sp7021_clk_dt_ids[] = {
696         { .compatible = "sunplus,sp7021-clkc" },
697         { }
698 };
699 MODULE_DEVICE_TABLE(of, sp7021_clk_dt_ids);
700
701 static struct platform_driver sp7021_clk_driver = {
702         .probe  = sp7021_clk_probe,
703         .driver = {
704                 .name = "sp7021-clk",
705                 .of_match_table = sp7021_clk_dt_ids,
706         },
707 };
708 module_platform_driver(sp7021_clk_driver);
709
710 MODULE_AUTHOR("Sunplus Technology");
711 MODULE_LICENSE("GPL");
712 MODULE_DESCRIPTION("Clock driver for Sunplus SP7021 SoC");