]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sys/arm/allwinner/clk/aw_pll.c
Import the skein hashing algorithm, based on the threefish block cipher
[FreeBSD/FreeBSD.git] / sys / arm / allwinner / clk / aw_pll.c
1 /*-
2  * Copyright (c) 2016 Jared McNeill <jmcneill@invisible.ca>
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  *    notice, this list of conditions and the following disclaimer in the
12  *    documentation and/or other materials provided with the distribution.
13  *
14  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
15  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
16  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
17  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
18  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
19  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
20  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
21  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
22  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24  * SUCH DAMAGE.
25  *
26  * $FreeBSD$
27  */
28
29 /*
30  * Allwinner PLL clock
31  */
32
33 #include <sys/cdefs.h>
34 __FBSDID("$FreeBSD$");
35
36 #include <sys/param.h>
37 #include <sys/systm.h>
38 #include <sys/bus.h>
39 #include <sys/rman.h>
40 #include <sys/kernel.h>
41 #include <sys/module.h>
42 #include <machine/bus.h>
43
44 #include <dev/ofw/ofw_bus.h>
45 #include <dev/ofw/ofw_bus_subr.h>
46 #include <dev/ofw/ofw_subr.h>
47
48 #include <dev/extres/clk/clk.h>
49
50 #include <dt-bindings/clock/sun4i-a10-pll2.h>
51
52 #include "clkdev_if.h"
53
54 #define AW_PLL_ENABLE                   (1 << 31)
55
56 #define A10_PLL1_OUT_EXT_DIVP           (0x3 << 16)
57 #define A10_PLL1_OUT_EXT_DIVP_SHIFT     16
58 #define A10_PLL1_FACTOR_N               (0x1f << 8)
59 #define A10_PLL1_FACTOR_N_SHIFT         8
60 #define A10_PLL1_FACTOR_K               (0x3 << 4)
61 #define A10_PLL1_FACTOR_K_SHIFT         4
62 #define A10_PLL1_FACTOR_M               (0x3 << 0)
63 #define A10_PLL1_FACTOR_M_SHIFT         0
64
65 #define A10_PLL2_POST_DIV               (0xf << 26)
66 #define A10_PLL2_POST_DIV_SHIFT         26
67 #define A10_PLL2_FACTOR_N               (0x7f << 8)
68 #define A10_PLL2_FACTOR_N_SHIFT         8
69 #define A10_PLL2_PRE_DIV                (0x1f << 0)
70 #define A10_PLL2_PRE_DIV_SHIFT          0
71
72 #define A10_PLL3_MODE_SEL               (0x1 << 15)
73 #define A10_PLL3_MODE_SEL_FRACT         (0 << 15)
74 #define A10_PLL3_MODE_SEL_INT           (1 << 15)
75 #define A10_PLL3_FUNC_SET               (0x1 << 14)
76 #define A10_PLL3_FUNC_SET_270MHZ        (0 << 14)
77 #define A10_PLL3_FUNC_SET_297MHZ        (1 << 14)
78 #define A10_PLL3_FACTOR_M               (0x7f << 0)
79 #define A10_PLL3_FACTOR_M_SHIFT         0
80 #define A10_PLL3_REF_FREQ               3000000
81
82 #define A10_PLL5_OUT_EXT_DIVP           (0x3 << 16)
83 #define A10_PLL5_OUT_EXT_DIVP_SHIFT     16
84 #define A10_PLL5_FACTOR_N               (0x1f << 8)
85 #define A10_PLL5_FACTOR_N_SHIFT         8
86 #define A10_PLL5_FACTOR_K               (0x3 << 4)
87 #define A10_PLL5_FACTOR_K_SHIFT         4
88 #define A10_PLL5_FACTOR_M1              (0x3 << 2)
89 #define A10_PLL5_FACTOR_M1_SHIFT        2
90 #define A10_PLL5_FACTOR_M               (0x3 << 0)
91 #define A10_PLL5_FACTOR_M_SHIFT         0
92
93 #define A10_PLL6_BYPASS_EN              (1 << 30)
94 #define A10_PLL6_SATA_CLK_EN            (1 << 14)
95 #define A10_PLL6_FACTOR_N               (0x1f << 8)
96 #define A10_PLL6_FACTOR_N_SHIFT         8
97 #define A10_PLL6_FACTOR_K               (0x3 << 4)
98 #define A10_PLL6_FACTOR_K_SHIFT         4
99 #define A10_PLL6_FACTOR_M               (0x3 << 0)
100 #define A10_PLL6_FACTOR_M_SHIFT         0
101
102 #define A10_PLL2_POST_DIV               (0xf << 26)
103
104 #define A23_PLL1_FACTOR_N               (0x1f << 8)
105 #define A23_PLL1_FACTOR_N_SHIFT         8
106 #define A23_PLL1_FACTOR_K               (0x3 << 4)
107 #define A23_PLL1_FACTOR_K_SHIFT         4
108 #define A23_PLL1_FACTOR_M               (0x3 << 0)
109 #define A23_PLL1_FACTOR_M_SHIFT         0
110 #define A23_PLL1_FACTOR_P               (0x3 << 16)
111 #define A23_PLL1_FACTOR_P_SHIFT         16
112
113 #define A31_PLL1_LOCK                   (1 << 28)
114 #define A31_PLL1_CPU_SIGMA_DELTA_EN     (1 << 24)
115 #define A31_PLL1_FACTOR_N               (0x1f << 8)
116 #define A31_PLL1_FACTOR_N_SHIFT         8
117 #define A31_PLL1_FACTOR_K               (0x3 << 4)
118 #define A31_PLL1_FACTOR_K_SHIFT         4
119 #define A31_PLL1_FACTOR_M               (0x3 << 0)
120 #define A31_PLL1_FACTOR_M_SHIFT         0
121
122 #define A31_PLL6_LOCK                   (1 << 28)
123 #define A31_PLL6_BYPASS_EN              (1 << 25)
124 #define A31_PLL6_CLK_OUT_EN             (1 << 24)
125 #define A31_PLL6_24M_OUT_EN             (1 << 18)
126 #define A31_PLL6_24M_POST_DIV           (0x3 << 16)
127 #define A31_PLL6_24M_POST_DIV_SHIFT     16
128 #define A31_PLL6_FACTOR_N               (0x1f << 8)
129 #define A31_PLL6_FACTOR_N_SHIFT         8
130 #define A31_PLL6_FACTOR_K               (0x3 << 4)
131 #define A31_PLL6_FACTOR_K_SHIFT         4
132 #define A31_PLL6_DEFAULT_N              0x18
133 #define A31_PLL6_DEFAULT_K              0x1
134 #define A31_PLL6_TIMEOUT                10
135
136 #define A80_PLL4_CLK_OUT_EN             (1 << 20)
137 #define A80_PLL4_PLL_DIV2               (1 << 18)
138 #define A80_PLL4_PLL_DIV1               (1 << 16)
139 #define A80_PLL4_FACTOR_N               (0xff << 8)
140 #define A80_PLL4_FACTOR_N_SHIFT         8
141
142 #define CLKID_A10_PLL3_1X               0
143 #define CLKID_A10_PLL3_2X               1
144
145 #define CLKID_A10_PLL5_DDR              0
146 #define CLKID_A10_PLL5_OTHER            1
147
148 #define CLKID_A10_PLL6_SATA             0
149 #define CLKID_A10_PLL6_OTHER            1
150 #define CLKID_A10_PLL6                  2
151 #define CLKID_A10_PLL6_DIV_4            3
152
153 #define CLKID_A31_PLL6                  0
154 #define CLKID_A31_PLL6_X2               1
155
156 enum aw_pll_type {
157         AWPLL_A10_PLL1 = 1,
158         AWPLL_A10_PLL2,
159         AWPLL_A10_PLL3,
160         AWPLL_A10_PLL5,
161         AWPLL_A10_PLL6,
162         AWPLL_A23_PLL1,
163         AWPLL_A31_PLL1,
164         AWPLL_A31_PLL6,
165         AWPLL_A80_PLL4,
166 };
167
168 struct aw_pll_sc {
169         enum aw_pll_type        type;
170         device_t                clkdev;
171         bus_addr_t              reg;
172         int                     id;
173 };
174
175 struct aw_pll_funcs {
176         int     (*recalc)(struct aw_pll_sc *, uint64_t *);
177         int     (*set_freq)(struct aw_pll_sc *, uint64_t, uint64_t *, int);
178         int     (*init)(device_t, bus_addr_t, struct clknode_init_def *);
179 };
180
181 #define PLL_READ(sc, val)       CLKDEV_READ_4((sc)->clkdev, (sc)->reg, (val))
182 #define PLL_WRITE(sc, val)      CLKDEV_WRITE_4((sc)->clkdev, (sc)->reg, (val))
183 #define DEVICE_LOCK(sc)         CLKDEV_DEVICE_LOCK((sc)->clkdev)
184 #define DEVICE_UNLOCK(sc)       CLKDEV_DEVICE_UNLOCK((sc)->clkdev)
185
186 static int
187 a10_pll1_recalc(struct aw_pll_sc *sc, uint64_t *freq)
188 {
189         uint32_t val, m, n, k, p;
190
191         DEVICE_LOCK(sc);
192         PLL_READ(sc, &val);
193         DEVICE_UNLOCK(sc);
194
195         p = 1 << ((val & A10_PLL1_OUT_EXT_DIVP) >> A10_PLL1_OUT_EXT_DIVP_SHIFT);
196         m = ((val & A10_PLL1_FACTOR_M) >> A10_PLL1_FACTOR_M_SHIFT) + 1;
197         k = ((val & A10_PLL1_FACTOR_K) >> A10_PLL1_FACTOR_K_SHIFT) + 1;
198         n = (val & A10_PLL1_FACTOR_N) >> A10_PLL1_FACTOR_N_SHIFT;
199         if (n == 0)
200                 n = 1;
201
202         *freq = (*freq * n * k) / (m * p);
203
204         return (0);
205 }
206
207 static int
208 a10_pll2_recalc(struct aw_pll_sc *sc, uint64_t *freq)
209 {
210         uint32_t val, post_div, n, pre_div;
211
212         DEVICE_LOCK(sc);
213         PLL_READ(sc, &val);
214         DEVICE_UNLOCK(sc);
215
216         post_div = (val & A10_PLL2_POST_DIV) >> A10_PLL2_POST_DIV_SHIFT;
217         if (post_div == 0)
218                 post_div = 1;
219         n = (val & A10_PLL2_FACTOR_N) >> A10_PLL2_FACTOR_N_SHIFT;
220         if (n == 0)
221                 n = 1;
222         pre_div = (val & A10_PLL2_PRE_DIV) >> A10_PLL2_PRE_DIV_SHIFT;
223         if (pre_div == 0)
224                 pre_div = 1;
225
226         switch (sc->id) {
227         case SUN4I_A10_PLL2_1X:
228                 *freq = (*freq * 2 * n) / pre_div / post_div / 2;
229                 break;
230         case SUN4I_A10_PLL2_2X:
231                 *freq = (*freq * 2 * n) / pre_div / 4;
232                 break;
233         case SUN4I_A10_PLL2_4X:
234                 *freq = (*freq * 2 * n) / pre_div / 2;
235                 break;
236         case SUN4I_A10_PLL2_8X:
237                 *freq = (*freq * 2 * n) / pre_div;
238                 break;
239         default:
240                 return (EINVAL);
241         }
242
243         return (0);
244 }
245
246 static int
247 a10_pll2_set_freq(struct aw_pll_sc *sc, uint64_t fin, uint64_t *fout,
248     int flags)
249 {
250         uint32_t val, post_div, n, pre_div;
251
252         if (sc->id != SUN4I_A10_PLL2_1X)
253                 return (ENXIO);
254
255         /*
256          * Audio Codec needs PLL2-1X to be either 24576000 or 22579200.
257          *
258          * PLL2-1X output frequency is (48MHz * n) / pre_div / post_div / 2.
259          * To get as close as possible to the desired rate, we use a
260          * pre-divider of 21 and a post-divider of 4. With these values,
261          * a multiplier of 86 or 79 gets us close to the target rates.
262          */
263         if (*fout != 24576000 && *fout != 22579200)
264                 return (EINVAL);
265
266         pre_div = 21;
267         post_div = 4;
268         n = (*fout * pre_div * post_div * 2) / (2 * fin);
269
270         DEVICE_LOCK(sc);
271         PLL_READ(sc, &val);
272         val &= ~(A10_PLL2_POST_DIV | A10_PLL2_FACTOR_N | A10_PLL2_PRE_DIV);
273         val |= (post_div << A10_PLL2_POST_DIV_SHIFT);
274         val |= (n << A10_PLL2_FACTOR_N_SHIFT);
275         val |= (pre_div << A10_PLL2_PRE_DIV_SHIFT);
276         PLL_WRITE(sc, val);
277         DEVICE_UNLOCK(sc);
278
279         return (0);
280 }
281
282 static int
283 a10_pll3_recalc(struct aw_pll_sc *sc, uint64_t *freq)
284 {
285         uint32_t val, m;
286
287         DEVICE_LOCK(sc);
288         PLL_READ(sc, &val);
289         DEVICE_UNLOCK(sc);
290
291         if ((val & A10_PLL3_MODE_SEL) == A10_PLL3_MODE_SEL_INT) {
292                 /* In integer mode, output is 3MHz * m */
293                 m = (val & A10_PLL3_FACTOR_M) >> A10_PLL3_FACTOR_M_SHIFT;
294                 *freq = A10_PLL3_REF_FREQ * m;
295         } else {
296                 /* In fractional mode, output is either 270MHz or 297MHz */
297                 if ((val & A10_PLL3_FUNC_SET) == A10_PLL3_FUNC_SET_270MHZ)
298                         *freq = 270000000;
299                 else
300                         *freq = 297000000;
301         }
302
303         if (sc->id == CLKID_A10_PLL3_2X)
304                 *freq *= 2;
305
306         return (0);
307 }
308
309 static int
310 a10_pll3_set_freq(struct aw_pll_sc *sc, uint64_t fin, uint64_t *fout,
311     int flags)
312 {
313         uint32_t val, m, mode, func;
314
315         m = *fout / A10_PLL3_REF_FREQ;
316         if (sc->id == CLKID_A10_PLL3_2X)
317                 m /= 2;
318
319         mode = A10_PLL3_MODE_SEL_INT;
320         func = 0;
321         *fout = m * A10_PLL3_REF_FREQ;
322         if (sc->id == CLKID_A10_PLL3_2X)
323                 *fout *= 2;
324
325         DEVICE_LOCK(sc);
326         PLL_READ(sc, &val);
327         val &= ~(A10_PLL3_MODE_SEL | A10_PLL3_FUNC_SET | A10_PLL3_FACTOR_M);
328         val |= mode;
329         val |= func;
330         val |= (m << A10_PLL3_FACTOR_M_SHIFT);
331         PLL_WRITE(sc, val);
332         DEVICE_UNLOCK(sc);
333
334         return (0);
335 }
336
337 static int
338 a10_pll3_init(device_t dev, bus_addr_t reg, struct clknode_init_def *def)
339 {
340         uint32_t val;
341
342         /* Allow changing PLL frequency while enabled */
343         def->flags = CLK_NODE_GLITCH_FREE;
344
345         /* Set PLL to 297MHz */
346         CLKDEV_DEVICE_LOCK(dev);
347         CLKDEV_READ_4(dev, reg, &val);
348         val &= ~(A10_PLL3_MODE_SEL | A10_PLL3_FUNC_SET | A10_PLL3_FACTOR_M);
349         val |= A10_PLL3_MODE_SEL_FRACT;
350         val |= A10_PLL3_FUNC_SET_297MHZ;
351         CLKDEV_WRITE_4(dev, reg, val);
352         CLKDEV_DEVICE_UNLOCK(dev);
353
354         return (0);
355 }
356
357 static int
358 a10_pll5_recalc(struct aw_pll_sc *sc, uint64_t *freq)
359 {
360         uint32_t val, m, n, k, p;
361
362         DEVICE_LOCK(sc);
363         PLL_READ(sc, &val);
364         DEVICE_UNLOCK(sc);
365
366         p = 1 << ((val & A10_PLL5_OUT_EXT_DIVP) >> A10_PLL5_OUT_EXT_DIVP_SHIFT);
367         m = ((val & A10_PLL5_FACTOR_M) >> A10_PLL5_FACTOR_M_SHIFT) + 1;
368         k = ((val & A10_PLL5_FACTOR_K) >> A10_PLL5_FACTOR_K_SHIFT) + 1;
369         n = (val & A10_PLL5_FACTOR_N) >> A10_PLL5_FACTOR_N_SHIFT;
370         if (n == 0)
371                 return (ENXIO);
372
373         switch (sc->id) {
374         case CLKID_A10_PLL5_DDR:
375                 *freq = (*freq * n * k) / m;
376                 break;
377         case CLKID_A10_PLL5_OTHER:
378                 *freq = (*freq * n * k) / p;
379                 break;
380         default:
381                 return (ENXIO);
382         }
383
384         return (0);
385 }
386
387 static int
388 a10_pll6_init(device_t dev, bus_addr_t reg, struct clknode_init_def *def)
389 {
390         uint32_t val, m, n, k;
391
392         /*
393          * SATA needs PLL6 to be a 100MHz clock.
394          *
395          * The SATA output frequency is (24MHz * n * k) / m / 6.
396          * To get to 100MHz, k & m must be equal and n must be 25.
397          */
398         m = k = 0;
399         n = 25;
400
401         CLKDEV_DEVICE_LOCK(dev);
402         CLKDEV_READ_4(dev, reg, &val);
403         val &= ~(A10_PLL6_FACTOR_N | A10_PLL6_FACTOR_K | A10_PLL6_FACTOR_M);
404         val &= ~A10_PLL6_BYPASS_EN;
405         val |= A10_PLL6_SATA_CLK_EN;
406         val |= (n << A10_PLL6_FACTOR_N_SHIFT);
407         val |= (k << A10_PLL6_FACTOR_K_SHIFT);
408         val |= (m << A10_PLL6_FACTOR_M_SHIFT);
409         CLKDEV_WRITE_4(dev, reg, val);
410         CLKDEV_DEVICE_UNLOCK(dev);
411
412         return (0);
413 }
414
415 static int
416 a10_pll6_recalc(struct aw_pll_sc *sc, uint64_t *freq)
417 {
418         uint32_t val, m, k, n;
419
420         DEVICE_LOCK(sc);
421         PLL_READ(sc, &val);
422         DEVICE_UNLOCK(sc);
423
424         m = ((val & A10_PLL6_FACTOR_M) >> A10_PLL6_FACTOR_M_SHIFT) + 1;
425         k = ((val & A10_PLL6_FACTOR_K) >> A10_PLL6_FACTOR_K_SHIFT) + 1;
426         n = (val & A10_PLL6_FACTOR_N) >> A10_PLL6_FACTOR_N_SHIFT;
427         if (n == 0)
428                 return (ENXIO);
429
430         switch (sc->id) {
431         case CLKID_A10_PLL6_SATA:
432                 *freq = (*freq * n * k) / m / 6;
433                 break;
434         case CLKID_A10_PLL6_OTHER:
435                 *freq = (*freq * n * k) / 2;
436                 break;
437         case CLKID_A10_PLL6:
438                 *freq = (*freq * n * k);
439                 break;
440         case CLKID_A10_PLL6_DIV_4:
441                 *freq = (*freq * n * k) / 4;
442                 break;
443         default:
444                 return (ENXIO);
445         }
446
447         return (0);
448 }
449
450 static int
451 a10_pll6_set_freq(struct aw_pll_sc *sc, uint64_t fin, uint64_t *fout,
452     int flags)
453 {
454         if (sc->id != CLKID_A10_PLL6_SATA)
455                 return (ENXIO);
456
457         /* PLL6 SATA output has been set to 100MHz in a10_pll6_init */
458         if (*fout != 100000000)
459                 return (ERANGE);
460
461         return (0);
462 }
463
464 static int
465 a23_pll1_recalc(struct aw_pll_sc *sc, uint64_t *freq)
466 {
467         uint32_t val, m, n, k, p;
468
469         DEVICE_LOCK(sc);
470         PLL_READ(sc, &val);
471         DEVICE_UNLOCK(sc);
472
473         m = ((val & A23_PLL1_FACTOR_M) >> A23_PLL1_FACTOR_M_SHIFT) + 1;
474         k = ((val & A23_PLL1_FACTOR_K) >> A23_PLL1_FACTOR_K_SHIFT) + 1;
475         n = ((val & A23_PLL1_FACTOR_N) >> A23_PLL1_FACTOR_N_SHIFT) + 1;
476         p = ((val & A23_PLL1_FACTOR_P) >> A23_PLL1_FACTOR_P_SHIFT) + 1;
477
478         *freq = (*freq * n * k) / (m * p);
479
480         return (0);
481 }
482
483 static int
484 a31_pll1_recalc(struct aw_pll_sc *sc, uint64_t *freq)
485 {
486         uint32_t val, m, n, k;
487
488         DEVICE_LOCK(sc);
489         PLL_READ(sc, &val);
490         DEVICE_UNLOCK(sc);
491
492         m = ((val & A31_PLL1_FACTOR_M) >> A31_PLL1_FACTOR_M_SHIFT) + 1;
493         k = ((val & A31_PLL1_FACTOR_K) >> A31_PLL1_FACTOR_K_SHIFT) + 1;
494         n = ((val & A31_PLL1_FACTOR_N) >> A31_PLL1_FACTOR_N_SHIFT) + 1;
495
496         *freq = (*freq * n * k) / m;
497
498         return (0);
499 }
500
501 static int
502 a31_pll6_init(device_t dev, bus_addr_t reg, struct clknode_init_def *def)
503 {
504         uint32_t val;
505         int retry;
506
507         if (def->id != CLKID_A31_PLL6)
508                 return (0);
509
510         /*
511          * The datasheet recommends that PLL6 output should be fixed to
512          * 600MHz.
513          */
514         CLKDEV_DEVICE_LOCK(dev);
515         CLKDEV_READ_4(dev, reg, &val);
516         val &= ~(A31_PLL6_FACTOR_N | A31_PLL6_FACTOR_K | A31_PLL6_BYPASS_EN);
517         val |= (A31_PLL6_DEFAULT_N << A31_PLL6_FACTOR_N_SHIFT);
518         val |= (A31_PLL6_DEFAULT_K << A31_PLL6_FACTOR_K_SHIFT);
519         CLKDEV_WRITE_4(dev, reg, val);
520
521         /* Wait for PLL to become stable */
522         for (retry = A31_PLL6_TIMEOUT; retry > 0; retry--) {
523                 CLKDEV_READ_4(dev, reg, &val);
524                 if ((val & A31_PLL6_LOCK) == A31_PLL6_LOCK)
525                         break;
526                 DELAY(1);
527         }
528
529         CLKDEV_DEVICE_UNLOCK(dev);
530
531         if (retry == 0)
532                 return (ETIMEDOUT);
533
534         return (0);
535 }
536
537 static int
538 a31_pll6_recalc(struct aw_pll_sc *sc, uint64_t *freq)
539 {
540         uint32_t val, k, n;
541
542         DEVICE_LOCK(sc);
543         PLL_READ(sc, &val);
544         DEVICE_UNLOCK(sc);
545
546         k = ((val & A10_PLL6_FACTOR_K) >> A10_PLL6_FACTOR_K_SHIFT) + 1;
547         n = ((val & A10_PLL6_FACTOR_N) >> A10_PLL6_FACTOR_N_SHIFT) + 1;
548
549         switch (sc->id) {
550         case CLKID_A31_PLL6:
551                 *freq = (*freq * n * k) / 2;
552                 break;
553         case CLKID_A31_PLL6_X2:
554                 *freq = *freq * n * k;
555                 break;
556         default:
557                 return (ENXIO);
558         }
559
560         return (0);
561 }
562
563 static int
564 a80_pll4_recalc(struct aw_pll_sc *sc, uint64_t *freq)
565 {
566         uint32_t val, n, div1, div2;
567
568         DEVICE_LOCK(sc);
569         PLL_READ(sc, &val);
570         DEVICE_UNLOCK(sc);
571
572         n = (val & A80_PLL4_FACTOR_N) >> A80_PLL4_FACTOR_N_SHIFT;
573         div1 = (val & A80_PLL4_PLL_DIV1) == 0 ? 1 : 2;
574         div2 = (val & A80_PLL4_PLL_DIV2) == 0 ? 1 : 2;
575
576         *freq = (*freq * n) / div1 / div2;
577
578         return (0);
579 }
580
581 #define PLL(_type, _recalc, _set_freq, _init)   \
582         [(_type)] = {                           \
583                 .recalc = (_recalc),            \
584                 .set_freq = (_set_freq),        \
585                 .init = (_init)                 \
586         }
587
588 static struct aw_pll_funcs aw_pll_func[] = {
589         PLL(AWPLL_A10_PLL1, a10_pll1_recalc, NULL, NULL),
590         PLL(AWPLL_A10_PLL2, a10_pll2_recalc, a10_pll2_set_freq, NULL),
591         PLL(AWPLL_A10_PLL3, a10_pll3_recalc, a10_pll3_set_freq, a10_pll3_init),
592         PLL(AWPLL_A10_PLL5, a10_pll5_recalc, NULL, NULL),
593         PLL(AWPLL_A10_PLL6, a10_pll6_recalc, a10_pll6_set_freq, a10_pll6_init),
594         PLL(AWPLL_A23_PLL1, a23_pll1_recalc, NULL, NULL),
595         PLL(AWPLL_A31_PLL1, a31_pll1_recalc, NULL, NULL),
596         PLL(AWPLL_A31_PLL6, a31_pll6_recalc, NULL, a31_pll6_init),
597         PLL(AWPLL_A80_PLL4, a80_pll4_recalc, NULL, NULL),
598 };
599
600 static struct ofw_compat_data compat_data[] = {
601         { "allwinner,sun4i-a10-pll1-clk",       AWPLL_A10_PLL1 },
602         { "allwinner,sun4i-a10-pll2-clk",       AWPLL_A10_PLL2 },
603         { "allwinner,sun4i-a10-pll3-clk",       AWPLL_A10_PLL3 },
604         { "allwinner,sun4i-a10-pll5-clk",       AWPLL_A10_PLL5 },
605         { "allwinner,sun4i-a10-pll6-clk",       AWPLL_A10_PLL6 },
606         { "allwinner,sun6i-a31-pll1-clk",       AWPLL_A31_PLL1 },
607         { "allwinner,sun6i-a31-pll6-clk",       AWPLL_A31_PLL6 },
608         { "allwinner,sun8i-a23-pll1-clk",       AWPLL_A23_PLL1 },
609         { "allwinner,sun9i-a80-pll4-clk",       AWPLL_A80_PLL4 },
610         { NULL, 0 }
611 };
612
613 static int
614 aw_pll_init(struct clknode *clk, device_t dev)
615 {
616         clknode_init_parent_idx(clk, 0);
617         return (0);
618 }
619
620 static int
621 aw_pll_set_gate(struct clknode *clk, bool enable)
622 {
623         struct aw_pll_sc *sc;
624         uint32_t val;
625
626         sc = clknode_get_softc(clk);
627
628         DEVICE_LOCK(sc);
629         PLL_READ(sc, &val);
630         if (enable)
631                 val |= AW_PLL_ENABLE;
632         else
633                 val &= ~AW_PLL_ENABLE;
634         PLL_WRITE(sc, val);
635         DEVICE_UNLOCK(sc);
636
637         return (0);
638 }
639
640 static int
641 aw_pll_recalc(struct clknode *clk, uint64_t *freq)
642 {
643         struct aw_pll_sc *sc;
644
645         sc = clknode_get_softc(clk);
646
647         if (aw_pll_func[sc->type].recalc == NULL)
648                 return (ENXIO);
649
650         return (aw_pll_func[sc->type].recalc(sc, freq));
651 }
652
653 static int
654 aw_pll_set_freq(struct clknode *clk, uint64_t fin, uint64_t *fout,
655     int flags, int *stop)
656 {
657         struct aw_pll_sc *sc;
658
659         sc = clknode_get_softc(clk);
660
661         *stop = 1;
662
663         if (aw_pll_func[sc->type].set_freq == NULL)
664                 return (ENXIO);
665
666         return (aw_pll_func[sc->type].set_freq(sc, fin, fout, flags));
667 }
668
669 static clknode_method_t aw_pll_clknode_methods[] = {
670         /* Device interface */
671         CLKNODEMETHOD(clknode_init,             aw_pll_init),
672         CLKNODEMETHOD(clknode_set_gate,         aw_pll_set_gate),
673         CLKNODEMETHOD(clknode_recalc_freq,      aw_pll_recalc),
674         CLKNODEMETHOD(clknode_set_freq,         aw_pll_set_freq),
675         CLKNODEMETHOD_END
676 };
677
678 DEFINE_CLASS_1(aw_pll_clknode, aw_pll_clknode_class, aw_pll_clknode_methods,
679     sizeof(struct aw_pll_sc), clknode_class);
680
681 static int
682 aw_pll_create(device_t dev, bus_addr_t paddr, struct clkdom *clkdom,
683     const char *pclkname, const char *clkname, int index)
684 {
685         enum aw_pll_type type;
686         struct clknode_init_def clkdef;
687         struct aw_pll_sc *sc;
688         struct clknode *clk;
689         int error;
690
691         type = ofw_bus_search_compatible(dev, compat_data)->ocd_data;
692
693         memset(&clkdef, 0, sizeof(clkdef));
694         clkdef.id = index;
695         clkdef.name = clkname;
696         if (pclkname != NULL) {
697                 clkdef.parent_names = malloc(sizeof(char *), M_OFWPROP,
698                     M_WAITOK);
699                 clkdef.parent_names[0] = pclkname;
700                 clkdef.parent_cnt = 1;
701         } else
702                 clkdef.parent_cnt = 0;
703
704         if (aw_pll_func[type].init != NULL) {
705                 error = aw_pll_func[type].init(device_get_parent(dev),
706                     paddr, &clkdef);
707                 if (error != 0) {
708                         device_printf(dev, "clock %s init failed\n", clkname);
709                         return (error);
710                 }
711         }
712
713         clk = clknode_create(clkdom, &aw_pll_clknode_class, &clkdef);
714         if (clk == NULL) {
715                 device_printf(dev, "cannot create clock node\n");
716                 return (ENXIO);
717         }
718         sc = clknode_get_softc(clk);
719         sc->clkdev = device_get_parent(dev);
720         sc->reg = paddr;
721         sc->type = type;
722         sc->id = clkdef.id;
723
724         clknode_register(clkdom, clk);
725
726         OF_prop_free(__DECONST(char *, clkdef.parent_names));
727
728         return (0);
729 }
730
731 static int
732 aw_pll_probe(device_t dev)
733 {
734         if (!ofw_bus_status_okay(dev))
735                 return (ENXIO);
736
737         if (ofw_bus_search_compatible(dev, compat_data)->ocd_data == 0)
738                 return (ENXIO);
739
740         device_set_desc(dev, "Allwinner PLL Clock");
741         return (BUS_PROBE_DEFAULT);
742 }
743
744 static int
745 aw_pll_attach(device_t dev)
746 {
747         struct clkdom *clkdom;
748         const char **names;
749         int index, nout, error;
750         clk_t clk_parent;
751         uint32_t *indices;
752         bus_addr_t paddr;
753         bus_size_t psize;
754         phandle_t node;
755
756         node = ofw_bus_get_node(dev);
757
758         if (ofw_reg_to_paddr(node, 0, &paddr, &psize, NULL) != 0) {
759                 device_printf(dev, "couldn't parse 'reg' property\n");
760                 return (ENXIO);
761         }
762
763         clkdom = clkdom_create(dev);
764
765         nout = clk_parse_ofw_out_names(dev, node, &names, &indices);
766         if (nout == 0) {
767                 device_printf(dev, "no clock outputs found\n");
768                 error = ENOENT;
769                 goto fail;
770         }
771
772         if (clk_get_by_ofw_index(dev, 0, &clk_parent) != 0)
773                 clk_parent = NULL;
774
775         for (index = 0; index < nout; index++) {
776                 error = aw_pll_create(dev, paddr, clkdom,
777                     clk_parent ? clk_get_name(clk_parent) : NULL,
778                     names[index], nout == 1 ? 1 : index);
779                 if (error)
780                         goto fail;
781         }
782
783         if (clkdom_finit(clkdom) != 0) {
784                 device_printf(dev, "cannot finalize clkdom initialization\n");
785                 error = ENXIO;
786                 goto fail;
787         }
788
789         if (bootverbose)
790                 clkdom_dump(clkdom);
791
792         return (0);
793
794 fail:
795         return (error);
796 }
797
798 static device_method_t aw_pll_methods[] = {
799         /* Device interface */
800         DEVMETHOD(device_probe,         aw_pll_probe),
801         DEVMETHOD(device_attach,        aw_pll_attach),
802
803         DEVMETHOD_END
804 };
805
806 static driver_t aw_pll_driver = {
807         "aw_pll",
808         aw_pll_methods,
809         0,
810 };
811
812 static devclass_t aw_pll_devclass;
813
814 EARLY_DRIVER_MODULE(aw_pll, simplebus, aw_pll_driver,
815     aw_pll_devclass, 0, 0, BUS_PASS_BUS + BUS_PASS_ORDER_MIDDLE);