]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sys/arm64/rockchip/clk/rk_clk_pll.c
Import tzdata 2020b
[FreeBSD/FreeBSD.git] / sys / arm64 / rockchip / clk / rk_clk_pll.c
1 /*-
2  * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
3  *
4  * Copyright (c) 2018 Emmanuel Vadot <manu@freebsd.org>
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  * 1. Redistributions of source code must retain the above copyright
10  *    notice, this list of conditions and the following disclaimer.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  *    notice, this list of conditions and the following disclaimer in the
13  *    documentation and/or other materials provided with the distribution.
14  *
15  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
16  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
17  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
18  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
19  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
20  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
21  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
22  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
23  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25  * SUCH DAMAGE.
26  *
27  * $FreeBSD$
28  */
29
30 #include <sys/cdefs.h>
31 __FBSDID("$FreeBSD$");
32
33 #include <sys/param.h>
34 #include <sys/systm.h>
35 #include <sys/bus.h>
36
37 #include <dev/extres/clk/clk.h>
38
39 #include <arm64/rockchip/clk/rk_clk_pll.h>
40
41 #include "clkdev_if.h"
42
43 struct rk_clk_pll_sc {
44         uint32_t        base_offset;
45
46         uint32_t        gate_offset;
47         uint32_t        gate_shift;
48
49         uint32_t        mode_reg;
50         uint32_t        mode_shift;
51
52         uint32_t        flags;
53
54         struct rk_clk_pll_rate  *rates;
55         struct rk_clk_pll_rate  *frac_rates;
56 };
57
58 #define WRITE4(_clk, off, val)                                          \
59         CLKDEV_WRITE_4(clknode_get_device(_clk), off, val)
60 #define READ4(_clk, off, val)                                           \
61         CLKDEV_READ_4(clknode_get_device(_clk), off, val)
62 #define DEVICE_LOCK(_clk)                                               \
63         CLKDEV_DEVICE_LOCK(clknode_get_device(_clk))
64 #define DEVICE_UNLOCK(_clk)                                             \
65         CLKDEV_DEVICE_UNLOCK(clknode_get_device(_clk))
66
67 #define RK_CLK_PLL_MASK_SHIFT   16
68
69 #if 0
70 #define dprintf(format, arg...)                                         \
71         printf("%s:(%s)" format, __func__, clknode_get_name(clk), arg)
72 #else
73 #define dprintf(format, arg...)
74 #endif
75
76 static int
77 rk_clk_pll_set_gate(struct clknode *clk, bool enable)
78 {
79         struct rk_clk_pll_sc *sc;
80         uint32_t val = 0;
81
82         sc = clknode_get_softc(clk);
83
84         if ((sc->flags & RK_CLK_PLL_HAVE_GATE) == 0)
85                 return (0);
86
87         dprintf("%sabling gate\n", enable ? "En" : "Dis");
88         if (!enable)
89                 val |= 1 << sc->gate_shift;
90         dprintf("sc->gate_shift: %x\n", sc->gate_shift);
91         val |= (1 << sc->gate_shift) << RK_CLK_PLL_MASK_SHIFT;
92         dprintf("Write: gate_offset=%x, val=%x\n", sc->gate_offset, val);
93         DEVICE_LOCK(clk);
94         WRITE4(clk, sc->gate_offset, val);
95         DEVICE_UNLOCK(clk);
96
97         return (0);
98 }
99
100 #define RK3328_CLK_PLL_FBDIV_OFFSET     0
101 #define RK3328_CLK_PLL_FBDIV_SHIFT      0
102 #define RK3328_CLK_PLL_FBDIV_MASK       0xFFF
103
104 #define RK3328_CLK_PLL_POSTDIV1_OFFSET  0
105 #define RK3328_CLK_PLL_POSTDIV1_SHIFT   12
106 #define RK3328_CLK_PLL_POSTDIV1_MASK    0x7000
107
108 #define RK3328_CLK_PLL_DSMPD_OFFSET     4
109 #define RK3328_CLK_PLL_DSMPD_SHIFT      12
110 #define RK3328_CLK_PLL_DSMPD_MASK       0x1000
111
112 #define RK3328_CLK_PLL_REFDIV_OFFSET    4
113 #define RK3328_CLK_PLL_REFDIV_SHIFT     0
114 #define RK3328_CLK_PLL_REFDIV_MASK      0x3F
115
116 #define RK3328_CLK_PLL_POSTDIV2_OFFSET  4
117 #define RK3328_CLK_PLL_POSTDIV2_SHIFT   6
118 #define RK3328_CLK_PLL_POSTDIV2_MASK    0x1C0
119
120 #define RK3328_CLK_PLL_FRAC_OFFSET      8
121 #define RK3328_CLK_PLL_FRAC_SHIFT       0
122 #define RK3328_CLK_PLL_FRAC_MASK        0xFFFFFF
123
124 #define RK3328_CLK_PLL_LOCK_MASK        0x400
125
126 #define RK3328_CLK_PLL_MODE_SLOW        0
127 #define RK3328_CLK_PLL_MODE_NORMAL      1
128 #define RK3328_CLK_PLL_MODE_MASK        0x1
129
130 static int
131 rk3328_clk_pll_init(struct clknode *clk, device_t dev)
132 {
133         struct rk_clk_pll_sc *sc;
134
135         sc = clknode_get_softc(clk);
136
137         clknode_init_parent_idx(clk, 0);
138
139         return (0);
140 }
141
142 static int
143 rk3328_clk_pll_recalc(struct clknode *clk, uint64_t *freq)
144 {
145         struct rk_clk_pll_sc *sc;
146         uint64_t rate;
147         uint32_t dsmpd, refdiv, fbdiv;
148         uint32_t postdiv1, postdiv2, frac;
149         uint32_t raw1, raw2, raw3;
150
151         sc = clknode_get_softc(clk);
152
153         DEVICE_LOCK(clk);
154
155         READ4(clk, sc->base_offset, &raw1);
156         READ4(clk, sc->base_offset + 4, &raw2);
157         READ4(clk, sc->base_offset + 8, &raw3);
158
159         fbdiv = (raw1 & RK3328_CLK_PLL_FBDIV_MASK) >> RK3328_CLK_PLL_FBDIV_SHIFT;
160         postdiv1 = (raw1 & RK3328_CLK_PLL_POSTDIV1_MASK) >> RK3328_CLK_PLL_POSTDIV1_SHIFT;
161
162         dsmpd = (raw2 & RK3328_CLK_PLL_DSMPD_MASK) >> RK3328_CLK_PLL_DSMPD_SHIFT;
163         refdiv = (raw2 & RK3328_CLK_PLL_REFDIV_MASK) >> RK3328_CLK_PLL_REFDIV_SHIFT;
164         postdiv2 = (raw2 & RK3328_CLK_PLL_POSTDIV2_MASK) >> RK3328_CLK_PLL_POSTDIV2_SHIFT;
165
166         frac = (raw3 & RK3328_CLK_PLL_FRAC_MASK) >> RK3328_CLK_PLL_FRAC_SHIFT;
167
168         DEVICE_UNLOCK(clk);
169
170         rate = *freq * fbdiv / refdiv;
171         if (dsmpd == 0) {
172                 /* Fractional mode */
173                 uint64_t frac_rate;
174
175                 frac_rate = *freq * frac / refdiv;
176                 rate += frac_rate >> 24;
177         }
178
179         *freq = rate / postdiv1 / postdiv2;
180
181         if (*freq % 2)
182                 *freq = *freq + 1;
183
184         return (0);
185 }
186
187 static int
188 rk3328_clk_pll_set_freq(struct clknode *clk, uint64_t fparent, uint64_t *fout,
189     int flags, int *stop)
190 {
191         struct rk_clk_pll_rate *rates;
192         struct rk_clk_pll_sc *sc;
193         uint32_t reg;
194         int timeout;
195
196         sc = clknode_get_softc(clk);
197
198         if (sc->rates)
199                 rates = sc->rates;
200         else if (sc->frac_rates)
201                 rates = sc->frac_rates;
202         else
203                 return (EINVAL);
204
205         for (; rates->freq; rates++) {
206                 if (rates->freq == *fout)
207                         break;
208         }
209         if (rates->freq == 0) {
210                 *stop = 1;
211                 return (EINVAL);
212         }
213
214         DEVICE_LOCK(clk);
215
216         /* Setting to slow mode during frequency change */
217         reg = (RK3328_CLK_PLL_MODE_MASK << sc->mode_shift) <<
218                 RK_CLK_PLL_MASK_SHIFT;
219         dprintf("Set PLL_MODEREG to %x\n", reg);
220         WRITE4(clk, sc->mode_reg, reg);
221
222         /* Setting postdiv1 and fbdiv */
223         reg = (rates->postdiv1 << RK3328_CLK_PLL_POSTDIV1_SHIFT) |
224                 (rates->fbdiv << RK3328_CLK_PLL_FBDIV_SHIFT);
225         reg |= (RK3328_CLK_PLL_POSTDIV1_MASK | RK3328_CLK_PLL_FBDIV_MASK) << 16;
226         dprintf("Set PLL_CON0 to %x\n", reg);
227         WRITE4(clk, sc->base_offset, reg);
228
229         /* Setting dsmpd, postdiv2 and refdiv */
230         reg = (rates->dsmpd << RK3328_CLK_PLL_DSMPD_SHIFT) |
231                 (rates->postdiv2 << RK3328_CLK_PLL_POSTDIV2_SHIFT) |
232                 (rates->refdiv << RK3328_CLK_PLL_REFDIV_SHIFT);
233         reg |= (RK3328_CLK_PLL_DSMPD_MASK |
234             RK3328_CLK_PLL_POSTDIV2_MASK |
235             RK3328_CLK_PLL_REFDIV_MASK) << RK_CLK_PLL_MASK_SHIFT;
236         dprintf("Set PLL_CON1 to %x\n", reg);
237         WRITE4(clk, sc->base_offset + 0x4, reg);
238
239         /* Setting frac */
240         READ4(clk, sc->base_offset + 0x8, &reg);
241         reg &= ~RK3328_CLK_PLL_FRAC_MASK;
242         reg |= rates->frac << RK3328_CLK_PLL_FRAC_SHIFT;
243         dprintf("Set PLL_CON2 to %x\n", reg);
244         WRITE4(clk, sc->base_offset + 0x8, reg);
245
246         /* Reading lock */
247         for (timeout = 1000; timeout; timeout--) {
248                 READ4(clk, sc->base_offset + 0x4, &reg);
249                 if ((reg & RK3328_CLK_PLL_LOCK_MASK) == 0)
250                         break;
251                 DELAY(1);
252         }
253
254         /* Set back to normal mode */
255         reg = (RK3328_CLK_PLL_MODE_NORMAL << sc->mode_shift);
256         reg |= (RK3328_CLK_PLL_MODE_MASK << sc->mode_shift) <<
257                 RK_CLK_PLL_MASK_SHIFT;
258         dprintf("Set PLL_MODEREG to %x\n", reg);
259         WRITE4(clk, sc->mode_reg, reg);
260
261         DEVICE_UNLOCK(clk);
262
263         *stop = 1;
264         return (0);
265 }
266
267 static clknode_method_t rk3328_clk_pll_clknode_methods[] = {
268         /* Device interface */
269         CLKNODEMETHOD(clknode_init,             rk3328_clk_pll_init),
270         CLKNODEMETHOD(clknode_set_gate,         rk_clk_pll_set_gate),
271         CLKNODEMETHOD(clknode_recalc_freq,      rk3328_clk_pll_recalc),
272         CLKNODEMETHOD(clknode_set_freq,         rk3328_clk_pll_set_freq),
273         CLKNODEMETHOD_END
274 };
275
276 DEFINE_CLASS_1(rk3328_clk_pll_clknode, rk3328_clk_pll_clknode_class,
277     rk3328_clk_pll_clknode_methods, sizeof(struct rk_clk_pll_sc), clknode_class);
278
279 int
280 rk3328_clk_pll_register(struct clkdom *clkdom, struct rk_clk_pll_def *clkdef)
281 {
282         struct clknode *clk;
283         struct rk_clk_pll_sc *sc;
284
285         clk = clknode_create(clkdom, &rk3328_clk_pll_clknode_class,
286             &clkdef->clkdef);
287         if (clk == NULL)
288                 return (1);
289
290         sc = clknode_get_softc(clk);
291
292         sc->base_offset = clkdef->base_offset;
293         sc->gate_offset = clkdef->gate_offset;
294         sc->gate_shift = clkdef->gate_shift;
295         sc->mode_reg = clkdef->mode_reg;
296         sc->mode_shift = clkdef->mode_shift;
297         sc->flags = clkdef->flags;
298         sc->rates = clkdef->rates;
299         sc->frac_rates = clkdef->frac_rates;
300
301         clknode_register(clkdom, clk);
302
303         return (0);
304 }
305
306 #define RK3399_CLK_PLL_FBDIV_OFFSET             0
307 #define RK3399_CLK_PLL_FBDIV_SHIFT              0
308 #define RK3399_CLK_PLL_FBDIV_MASK               0xFFF
309
310 #define RK3399_CLK_PLL_POSTDIV2_OFFSET  4
311 #define RK3399_CLK_PLL_POSTDIV2_SHIFT   12
312 #define RK3399_CLK_PLL_POSTDIV2_MASK    0x7000
313
314 #define RK3399_CLK_PLL_POSTDIV1_OFFSET  4
315 #define RK3399_CLK_PLL_POSTDIV1_SHIFT   8
316 #define RK3399_CLK_PLL_POSTDIV1_MASK    0x700
317
318 #define RK3399_CLK_PLL_REFDIV_OFFSET    4
319 #define RK3399_CLK_PLL_REFDIV_SHIFT     0
320 #define RK3399_CLK_PLL_REFDIV_MASK      0x3F
321
322 #define RK3399_CLK_PLL_FRAC_OFFSET      8
323 #define RK3399_CLK_PLL_FRAC_SHIFT       0
324 #define RK3399_CLK_PLL_FRAC_MASK        0xFFFFFF
325
326 #define RK3399_CLK_PLL_DSMPD_OFFSET     0xC
327 #define RK3399_CLK_PLL_DSMPD_SHIFT      3
328 #define RK3399_CLK_PLL_DSMPD_MASK       0x8
329
330 #define RK3399_CLK_PLL_LOCK_OFFSET      8
331 #define RK3399_CLK_PLL_LOCK_MASK        0x400
332
333 #define RK3399_CLK_PLL_MODE_OFFSET      0xC
334 #define RK3399_CLK_PLL_MODE_MASK        0x300
335 #define RK3399_CLK_PLL_MODE_SLOW        0
336 #define RK3399_CLK_PLL_MODE_NORMAL      1
337 #define RK3399_CLK_PLL_MODE_DEEPSLOW    2
338 #define RK3399_CLK_PLL_MODE_SHIFT       8
339
340 #define RK3399_CLK_PLL_WRITE_MASK       0xFFFF0000
341
342 static int
343 rk3399_clk_pll_init(struct clknode *clk, device_t dev)
344 {
345         struct rk_clk_pll_sc *sc;
346
347         sc = clknode_get_softc(clk);
348         clknode_init_parent_idx(clk, 0);
349
350         return (0);
351 }
352
353 static int
354 rk3399_clk_pll_recalc(struct clknode *clk, uint64_t *freq)
355 {
356         struct rk_clk_pll_sc *sc;
357         uint32_t dsmpd, refdiv, fbdiv;
358         uint32_t postdiv1, postdiv2, fracdiv;
359         uint32_t con1, con2, con3, con4;
360         uint64_t foutvco;
361         uint32_t mode;
362         sc = clknode_get_softc(clk);
363
364         DEVICE_LOCK(clk);
365         READ4(clk, sc->base_offset, &con1);
366         READ4(clk, sc->base_offset + 4, &con2);
367         READ4(clk, sc->base_offset + 8, &con3);
368         READ4(clk, sc->base_offset + 0xC, &con4);
369         DEVICE_UNLOCK(clk);
370
371         /*
372          * if we are in slow mode the output freq
373          * is the parent one, the 24Mhz external oscillator
374          * if we are in deep mode the output freq is 32.768khz
375          */
376         mode = (con4 & RK3399_CLK_PLL_MODE_MASK) >> RK3399_CLK_PLL_MODE_SHIFT;
377         if (mode == RK3399_CLK_PLL_MODE_SLOW) {
378                 dprintf("pll in slow mode, con4=%x\n", con4);
379                 return (0);
380         } else if (mode == RK3399_CLK_PLL_MODE_DEEPSLOW) {
381                 dprintf("pll in deep slow, con4=%x\n", con4);
382                 *freq = 32768;
383                 return (0);
384         }
385
386         dprintf("con0: %x\n", con1);
387         dprintf("con1: %x\n", con2);
388         dprintf("con2: %x\n", con3);
389         dprintf("con3: %x\n", con4);
390
391         fbdiv = (con1 & RK3399_CLK_PLL_FBDIV_MASK)
392             >> RK3399_CLK_PLL_FBDIV_SHIFT;
393
394         postdiv1 = (con2 & RK3399_CLK_PLL_POSTDIV1_MASK)
395             >> RK3399_CLK_PLL_POSTDIV1_SHIFT;
396         postdiv2 = (con2 & RK3399_CLK_PLL_POSTDIV2_MASK)
397             >> RK3399_CLK_PLL_POSTDIV2_SHIFT;
398         refdiv = (con2 & RK3399_CLK_PLL_REFDIV_MASK)
399             >> RK3399_CLK_PLL_REFDIV_SHIFT;
400
401         fracdiv = (con3 & RK3399_CLK_PLL_FRAC_MASK)
402             >> RK3399_CLK_PLL_FRAC_SHIFT;
403         fracdiv >>= 24;
404
405         dsmpd = (con4 & RK3399_CLK_PLL_DSMPD_MASK) >> RK3399_CLK_PLL_DSMPD_SHIFT;
406
407         dprintf("fbdiv: %d\n", fbdiv);
408         dprintf("postdiv1: %d\n", postdiv1);
409         dprintf("postdiv2: %d\n", postdiv2);
410         dprintf("refdiv: %d\n", refdiv);
411         dprintf("fracdiv: %d\n", fracdiv);
412         dprintf("dsmpd: %d\n", dsmpd);
413
414         dprintf("parent freq=%ju\n", *freq);
415
416         if (dsmpd == 0) {
417                 /* Fractional mode */
418                 foutvco = *freq / refdiv * (fbdiv + fracdiv);
419         } else {
420                 /* Integer mode */
421                 foutvco = *freq / refdiv * fbdiv;
422         }
423         dprintf("foutvco: %ju\n", foutvco);
424
425         *freq = foutvco / postdiv1 / postdiv2;
426         dprintf("freq: %ju\n", *freq);
427
428         return (0);
429 }
430
431 static int
432 rk3399_clk_pll_set_freq(struct clknode *clk, uint64_t fparent, uint64_t *fout,
433     int flags, int *stop)
434 {
435         struct rk_clk_pll_rate *rates;
436         struct rk_clk_pll_sc *sc;
437         uint32_t reg;
438         int timeout;
439
440         sc = clknode_get_softc(clk);
441
442         if (sc->rates)
443                 rates = sc->rates;
444         else if (sc->frac_rates)
445                 rates = sc->frac_rates;
446         else
447                 return (EINVAL);
448
449         for (; rates->freq; rates++) {
450                 if (rates->freq == *fout)
451                         break;
452         }
453         if (rates->freq == 0) {
454                 *stop = 1;
455                 return (EINVAL);
456         }
457
458         DEVICE_LOCK(clk);
459
460         /* Set to slow mode during frequency change */
461         reg = RK3399_CLK_PLL_MODE_SLOW << RK3399_CLK_PLL_MODE_SHIFT;
462         reg |= RK3399_CLK_PLL_MODE_MASK << RK_CLK_PLL_MASK_SHIFT;
463         WRITE4(clk, sc->base_offset + 0xC, reg);
464
465         /* Setting fbdiv */
466         reg = rates->fbdiv << RK3399_CLK_PLL_FBDIV_SHIFT;
467         reg |= RK3399_CLK_PLL_FBDIV_MASK << RK_CLK_PLL_MASK_SHIFT;
468         WRITE4(clk, sc->base_offset, reg);
469
470         /* Setting postdiv1, postdiv2 and refdiv */
471         reg = rates->postdiv1 << RK3399_CLK_PLL_POSTDIV1_SHIFT;
472         reg |= rates->postdiv2 << RK3399_CLK_PLL_POSTDIV2_SHIFT;
473         reg |= rates->refdiv << RK3399_CLK_PLL_REFDIV_SHIFT;
474         reg |= (RK3399_CLK_PLL_POSTDIV1_MASK | RK3399_CLK_PLL_POSTDIV2_MASK |
475             RK3399_CLK_PLL_REFDIV_MASK) << RK_CLK_PLL_MASK_SHIFT;
476         WRITE4(clk, sc->base_offset + 0x4, reg);
477
478         /* Setting frac */
479         READ4(clk, sc->base_offset + 0x8, &reg);
480         reg &= ~RK3399_CLK_PLL_FRAC_MASK;
481         reg |= rates->frac << RK3399_CLK_PLL_FRAC_SHIFT;
482         WRITE4(clk, sc->base_offset + 0x8, reg | RK3399_CLK_PLL_WRITE_MASK);
483
484         /* Set dsmpd */
485         reg = rates->dsmpd << RK3399_CLK_PLL_DSMPD_SHIFT;
486         reg |= RK3399_CLK_PLL_DSMPD_MASK << RK_CLK_PLL_MASK_SHIFT;
487         WRITE4(clk, sc->base_offset + 0xC, reg);
488
489         /* Reading lock */
490         for (timeout = 1000; timeout; timeout--) {
491                 READ4(clk, sc->base_offset + RK3399_CLK_PLL_LOCK_OFFSET, &reg);
492                 if ((reg & RK3399_CLK_PLL_LOCK_MASK) == 0)
493                         break;
494                 DELAY(1);
495         }
496
497         /* Set back to normal mode */
498         reg = RK3399_CLK_PLL_MODE_NORMAL << RK3399_CLK_PLL_MODE_SHIFT;
499         reg |= RK3399_CLK_PLL_MODE_MASK << RK_CLK_PLL_MASK_SHIFT;
500         WRITE4(clk, sc->base_offset + 0xC, reg);
501
502         DEVICE_UNLOCK(clk);
503
504         *stop = 1;
505         return (0);
506 }
507
508 static clknode_method_t rk3399_clk_pll_clknode_methods[] = {
509         /* Device interface */
510         CLKNODEMETHOD(clknode_init,             rk3399_clk_pll_init),
511         CLKNODEMETHOD(clknode_set_gate,         rk_clk_pll_set_gate),
512         CLKNODEMETHOD(clknode_recalc_freq,      rk3399_clk_pll_recalc),
513         CLKNODEMETHOD(clknode_set_freq,         rk3399_clk_pll_set_freq),
514         CLKNODEMETHOD_END
515 };
516
517 DEFINE_CLASS_1(rk3399_clk_pll_clknode, rk3399_clk_pll_clknode_class,
518     rk3399_clk_pll_clknode_methods, sizeof(struct rk_clk_pll_sc), clknode_class);
519
520 int
521 rk3399_clk_pll_register(struct clkdom *clkdom, struct rk_clk_pll_def *clkdef)
522 {
523         struct clknode *clk;
524         struct rk_clk_pll_sc *sc;
525
526         clk = clknode_create(clkdom, &rk3399_clk_pll_clknode_class,
527             &clkdef->clkdef);
528         if (clk == NULL)
529                 return (1);
530
531         sc = clknode_get_softc(clk);
532
533         sc->base_offset = clkdef->base_offset;
534         sc->gate_offset = clkdef->gate_offset;
535         sc->gate_shift = clkdef->gate_shift;
536         sc->flags = clkdef->flags;
537         sc->rates = clkdef->rates;
538         sc->frac_rates = clkdef->frac_rates;
539
540         clknode_register(clkdom, clk);
541
542         return (0);
543 }