]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sys/arm/allwinner/clk/aw_pll.c
Merge ACPICA 20160422.
[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 A31_PLL1_LOCK                   (1 << 28)
105 #define A31_PLL1_CPU_SIGMA_DELTA_EN     (1 << 24)
106 #define A31_PLL1_FACTOR_N               (0x1f << 8)
107 #define A31_PLL1_FACTOR_N_SHIFT         8
108 #define A31_PLL1_FACTOR_K               (0x3 << 4)
109 #define A31_PLL1_FACTOR_K_SHIFT         4
110 #define A31_PLL1_FACTOR_M               (0x3 << 0)
111 #define A31_PLL1_FACTOR_M_SHIFT         0
112
113 #define A31_PLL6_LOCK                   (1 << 28)
114 #define A31_PLL6_BYPASS_EN              (1 << 25)
115 #define A31_PLL6_CLK_OUT_EN             (1 << 24)
116 #define A31_PLL6_24M_OUT_EN             (1 << 18)
117 #define A31_PLL6_24M_POST_DIV           (0x3 << 16)
118 #define A31_PLL6_24M_POST_DIV_SHIFT     16
119 #define A31_PLL6_FACTOR_N               (0x1f << 8)
120 #define A31_PLL6_FACTOR_N_SHIFT         8
121 #define A31_PLL6_FACTOR_K               (0x3 << 4)
122 #define A31_PLL6_FACTOR_K_SHIFT         4
123 #define A31_PLL6_DEFAULT_N              0x18
124 #define A31_PLL6_DEFAULT_K              0x1
125 #define A31_PLL6_TIMEOUT                10
126
127 #define CLKID_A10_PLL3_1X               0
128 #define CLKID_A10_PLL3_2X               1
129
130 #define CLKID_A10_PLL5_DDR              0
131 #define CLKID_A10_PLL5_OTHER            1
132
133 #define CLKID_A10_PLL6_SATA             0
134 #define CLKID_A10_PLL6_OTHER            1
135 #define CLKID_A10_PLL6                  2
136 #define CLKID_A10_PLL6_DIV_4            3
137
138 #define CLKID_A31_PLL6                  0
139 #define CLKID_A31_PLL6_X2               1
140
141 enum aw_pll_type {
142         AWPLL_A10_PLL1 = 1,
143         AWPLL_A10_PLL2,
144         AWPLL_A10_PLL3,
145         AWPLL_A10_PLL5,
146         AWPLL_A10_PLL6,
147         AWPLL_A31_PLL1,
148         AWPLL_A31_PLL6,
149 };
150
151 struct aw_pll_sc {
152         enum aw_pll_type        type;
153         device_t                clkdev;
154         bus_addr_t              reg;
155         int                     id;
156 };
157
158 struct aw_pll_funcs {
159         int     (*recalc)(struct aw_pll_sc *, uint64_t *);
160         int     (*set_freq)(struct aw_pll_sc *, uint64_t, uint64_t *, int);
161         int     (*init)(device_t, bus_addr_t, struct clknode_init_def *);
162 };
163
164 #define PLL_READ(sc, val)       CLKDEV_READ_4((sc)->clkdev, (sc)->reg, (val))
165 #define PLL_WRITE(sc, val)      CLKDEV_WRITE_4((sc)->clkdev, (sc)->reg, (val))
166 #define DEVICE_LOCK(sc)         CLKDEV_DEVICE_LOCK((sc)->clkdev)
167 #define DEVICE_UNLOCK(sc)       CLKDEV_DEVICE_UNLOCK((sc)->clkdev)
168
169 static int
170 a10_pll1_recalc(struct aw_pll_sc *sc, uint64_t *freq)
171 {
172         uint32_t val, m, n, k, p;
173
174         DEVICE_LOCK(sc);
175         PLL_READ(sc, &val);
176         DEVICE_UNLOCK(sc);
177
178         p = 1 << ((val & A10_PLL1_OUT_EXT_DIVP) >> A10_PLL1_OUT_EXT_DIVP_SHIFT);
179         m = ((val & A10_PLL1_FACTOR_M) >> A10_PLL1_FACTOR_M_SHIFT) + 1;
180         k = ((val & A10_PLL1_FACTOR_K) >> A10_PLL1_FACTOR_K_SHIFT) + 1;
181         n = (val & A10_PLL1_FACTOR_N) >> A10_PLL1_FACTOR_N_SHIFT;
182         if (n == 0)
183                 n = 1;
184
185         *freq = (*freq * n * k) / (m * p);
186
187         return (0);
188 }
189
190 static int
191 a10_pll2_recalc(struct aw_pll_sc *sc, uint64_t *freq)
192 {
193         uint32_t val, post_div, n, pre_div;
194
195         DEVICE_LOCK(sc);
196         PLL_READ(sc, &val);
197         DEVICE_UNLOCK(sc);
198
199         post_div = (val & A10_PLL2_POST_DIV) >> A10_PLL2_POST_DIV_SHIFT;
200         if (post_div == 0)
201                 post_div = 1;
202         n = (val & A10_PLL2_FACTOR_N) >> A10_PLL2_FACTOR_N_SHIFT;
203         if (n == 0)
204                 n = 1;
205         pre_div = (val & A10_PLL2_PRE_DIV) >> A10_PLL2_PRE_DIV_SHIFT;
206         if (pre_div == 0)
207                 pre_div = 1;
208
209         switch (sc->id) {
210         case SUN4I_A10_PLL2_1X:
211                 *freq = (*freq * 2 * n) / pre_div / post_div / 2;
212                 break;
213         case SUN4I_A10_PLL2_2X:
214                 *freq = (*freq * 2 * n) / pre_div / 4;
215                 break;
216         case SUN4I_A10_PLL2_4X:
217                 *freq = (*freq * 2 * n) / pre_div / 2;
218                 break;
219         case SUN4I_A10_PLL2_8X:
220                 *freq = (*freq * 2 * n) / pre_div;
221                 break;
222         default:
223                 return (EINVAL);
224         }
225
226         return (0);
227 }
228
229 static int
230 a10_pll2_set_freq(struct aw_pll_sc *sc, uint64_t fin, uint64_t *fout,
231     int flags)
232 {
233         uint32_t val, post_div, n, pre_div;
234
235         if (sc->id != SUN4I_A10_PLL2_1X)
236                 return (ENXIO);
237
238         /*
239          * Audio Codec needs PLL2-1X to be either 24576000 or 22579200.
240          *
241          * PLL2-1X output frequency is (48MHz * n) / pre_div / post_div / 2.
242          * To get as close as possible to the desired rate, we use a
243          * pre-divider of 21 and a post-divider of 4. With these values,
244          * a multiplier of 86 or 79 gets us close to the target rates.
245          */
246         if (*fout != 24576000 && *fout != 22579200)
247                 return (EINVAL);
248
249         pre_div = 21;
250         post_div = 4;
251         n = (*fout * pre_div * post_div * 2) / (2 * fin);
252
253         DEVICE_LOCK(sc);
254         PLL_READ(sc, &val);
255         val &= ~(A10_PLL2_POST_DIV | A10_PLL2_FACTOR_N | A10_PLL2_PRE_DIV);
256         val |= (post_div << A10_PLL2_POST_DIV_SHIFT);
257         val |= (n << A10_PLL2_FACTOR_N_SHIFT);
258         val |= (pre_div << A10_PLL2_PRE_DIV_SHIFT);
259         PLL_WRITE(sc, val);
260         DEVICE_UNLOCK(sc);
261
262         return (0);
263 }
264
265 static int
266 a10_pll3_recalc(struct aw_pll_sc *sc, uint64_t *freq)
267 {
268         uint32_t val, m;
269
270         DEVICE_LOCK(sc);
271         PLL_READ(sc, &val);
272         DEVICE_UNLOCK(sc);
273
274         if ((val & A10_PLL3_MODE_SEL) == A10_PLL3_MODE_SEL_INT) {
275                 /* In integer mode, output is 3MHz * m */
276                 m = (val & A10_PLL3_FACTOR_M) >> A10_PLL3_FACTOR_M_SHIFT;
277                 *freq = A10_PLL3_REF_FREQ * m;
278         } else {
279                 /* In fractional mode, output is either 270MHz or 297MHz */
280                 if ((val & A10_PLL3_FUNC_SET) == A10_PLL3_FUNC_SET_270MHZ)
281                         *freq = 270000000;
282                 else
283                         *freq = 297000000;
284         }
285
286         if (sc->id == CLKID_A10_PLL3_2X)
287                 *freq *= 2;
288
289         return (0);
290 }
291
292 static int
293 a10_pll3_set_freq(struct aw_pll_sc *sc, uint64_t fin, uint64_t *fout,
294     int flags)
295 {
296         uint32_t val, m, mode, func;
297
298         m = *fout / A10_PLL3_REF_FREQ;
299         if (sc->id == CLKID_A10_PLL3_2X)
300                 m /= 2;
301
302         mode = A10_PLL3_MODE_SEL_INT;
303         func = 0;
304         *fout = m * A10_PLL3_REF_FREQ;
305         if (sc->id == CLKID_A10_PLL3_2X)
306                 *fout *= 2;
307
308         DEVICE_LOCK(sc);
309         PLL_READ(sc, &val);
310         val &= ~(A10_PLL3_MODE_SEL | A10_PLL3_FUNC_SET | A10_PLL3_FACTOR_M);
311         val |= mode;
312         val |= func;
313         val |= (m << A10_PLL3_FACTOR_M_SHIFT);
314         PLL_WRITE(sc, val);
315         DEVICE_UNLOCK(sc);
316
317         return (0);
318 }
319
320 static int
321 a10_pll3_init(device_t dev, bus_addr_t reg, struct clknode_init_def *def)
322 {
323         uint32_t val;
324
325         /* Allow changing PLL frequency while enabled */
326         def->flags = CLK_NODE_GLITCH_FREE;
327
328         /* Set PLL to 297MHz */
329         CLKDEV_DEVICE_LOCK(dev);
330         CLKDEV_READ_4(dev, reg, &val);
331         val &= ~(A10_PLL3_MODE_SEL | A10_PLL3_FUNC_SET | A10_PLL3_FACTOR_M);
332         val |= A10_PLL3_MODE_SEL_FRACT;
333         val |= A10_PLL3_FUNC_SET_297MHZ;
334         CLKDEV_WRITE_4(dev, reg, val);
335         CLKDEV_DEVICE_UNLOCK(dev);
336
337         return (0);
338 }
339
340 static int
341 a10_pll5_recalc(struct aw_pll_sc *sc, uint64_t *freq)
342 {
343         uint32_t val, m, n, k, p;
344
345         DEVICE_LOCK(sc);
346         PLL_READ(sc, &val);
347         DEVICE_UNLOCK(sc);
348
349         p = 1 << ((val & A10_PLL5_OUT_EXT_DIVP) >> A10_PLL5_OUT_EXT_DIVP_SHIFT);
350         m = ((val & A10_PLL5_FACTOR_M) >> A10_PLL5_FACTOR_M_SHIFT) + 1;
351         k = ((val & A10_PLL5_FACTOR_K) >> A10_PLL5_FACTOR_K_SHIFT) + 1;
352         n = (val & A10_PLL5_FACTOR_N) >> A10_PLL5_FACTOR_N_SHIFT;
353         if (n == 0)
354                 return (ENXIO);
355
356         switch (sc->id) {
357         case CLKID_A10_PLL5_DDR:
358                 *freq = (*freq * n * k) / m;
359                 break;
360         case CLKID_A10_PLL5_OTHER:
361                 *freq = (*freq * n * k) / p;
362                 break;
363         default:
364                 return (ENXIO);
365         }
366
367         return (0);
368 }
369
370 static int
371 a10_pll6_init(device_t dev, bus_addr_t reg, struct clknode_init_def *def)
372 {
373         uint32_t val, m, n, k;
374
375         /*
376          * SATA needs PLL6 to be a 100MHz clock.
377          *
378          * The SATA output frequency is (24MHz * n * k) / m / 6.
379          * To get to 100MHz, k & m must be equal and n must be 25.
380          */
381         m = k = 0;
382         n = 25;
383
384         CLKDEV_DEVICE_LOCK(dev);
385         CLKDEV_READ_4(dev, reg, &val);
386         val &= ~(A10_PLL6_FACTOR_N | A10_PLL6_FACTOR_K | A10_PLL6_FACTOR_M);
387         val &= ~A10_PLL6_BYPASS_EN;
388         val |= A10_PLL6_SATA_CLK_EN;
389         val |= (n << A10_PLL6_FACTOR_N_SHIFT);
390         val |= (k << A10_PLL6_FACTOR_K_SHIFT);
391         val |= (m << A10_PLL6_FACTOR_M_SHIFT);
392         CLKDEV_WRITE_4(dev, reg, val);
393         CLKDEV_DEVICE_UNLOCK(dev);
394
395         return (0);
396 }
397
398 static int
399 a10_pll6_recalc(struct aw_pll_sc *sc, uint64_t *freq)
400 {
401         uint32_t val, m, k, n;
402
403         DEVICE_LOCK(sc);
404         PLL_READ(sc, &val);
405         DEVICE_UNLOCK(sc);
406
407         m = ((val & A10_PLL6_FACTOR_M) >> A10_PLL6_FACTOR_M_SHIFT) + 1;
408         k = ((val & A10_PLL6_FACTOR_K) >> A10_PLL6_FACTOR_K_SHIFT) + 1;
409         n = (val & A10_PLL6_FACTOR_N) >> A10_PLL6_FACTOR_N_SHIFT;
410         if (n == 0)
411                 return (ENXIO);
412
413         switch (sc->id) {
414         case CLKID_A10_PLL6_SATA:
415                 *freq = (*freq * n * k) / m / 6;
416                 break;
417         case CLKID_A10_PLL6_OTHER:
418                 *freq = (*freq * n * k) / 2;
419                 break;
420         case CLKID_A10_PLL6:
421                 *freq = (*freq * n * k);
422                 break;
423         case CLKID_A10_PLL6_DIV_4:
424                 *freq = (*freq * n * k) / 4;
425                 break;
426         default:
427                 return (ENXIO);
428         }
429
430         return (0);
431 }
432
433 static int
434 a10_pll6_set_freq(struct aw_pll_sc *sc, uint64_t fin, uint64_t *fout,
435     int flags)
436 {
437         if (sc->id != CLKID_A10_PLL6_SATA)
438                 return (ENXIO);
439
440         /* PLL6 SATA output has been set to 100MHz in a10_pll6_init */
441         if (*fout != 100000000)
442                 return (ERANGE);
443
444         return (0);
445 }
446
447 static int
448 a31_pll1_recalc(struct aw_pll_sc *sc, uint64_t *freq)
449 {
450         uint32_t val, m, n, k;
451
452         DEVICE_LOCK(sc);
453         PLL_READ(sc, &val);
454         DEVICE_UNLOCK(sc);
455
456         m = ((val & A31_PLL1_FACTOR_M) >> A31_PLL1_FACTOR_M_SHIFT) + 1;
457         k = ((val & A31_PLL1_FACTOR_K) >> A31_PLL1_FACTOR_K_SHIFT) + 1;
458         n = ((val & A31_PLL1_FACTOR_N) >> A31_PLL1_FACTOR_N_SHIFT) + 1;
459
460         *freq = (*freq * n * k) / m;
461
462         return (0);
463 }
464
465 static int
466 a31_pll6_init(device_t dev, bus_addr_t reg, struct clknode_init_def *def)
467 {
468         uint32_t val;
469         int retry;
470
471         if (def->id != CLKID_A31_PLL6)
472                 return (0);
473
474         /*
475          * The datasheet recommends that PLL6 output should be fixed to
476          * 600MHz.
477          */
478         CLKDEV_DEVICE_LOCK(dev);
479         CLKDEV_READ_4(dev, reg, &val);
480         val &= ~(A31_PLL6_FACTOR_N | A31_PLL6_FACTOR_K | A31_PLL6_BYPASS_EN);
481         val |= (A31_PLL6_DEFAULT_N << A31_PLL6_FACTOR_N_SHIFT);
482         val |= (A31_PLL6_DEFAULT_K << A31_PLL6_FACTOR_K_SHIFT);
483         CLKDEV_WRITE_4(dev, reg, val);
484
485         /* Wait for PLL to become stable */
486         for (retry = A31_PLL6_TIMEOUT; retry > 0; retry--) {
487                 CLKDEV_READ_4(dev, reg, &val);
488                 if ((val & A31_PLL6_LOCK) == A31_PLL6_LOCK)
489                         break;
490                 DELAY(1);
491         }
492
493         CLKDEV_DEVICE_UNLOCK(dev);
494
495         if (retry == 0)
496                 return (ETIMEDOUT);
497
498         return (0);
499 }
500
501 static int
502 a31_pll6_recalc(struct aw_pll_sc *sc, uint64_t *freq)
503 {
504         uint32_t val, k, n;
505
506         DEVICE_LOCK(sc);
507         PLL_READ(sc, &val);
508         DEVICE_UNLOCK(sc);
509
510         k = ((val & A10_PLL6_FACTOR_K) >> A10_PLL6_FACTOR_K_SHIFT) + 1;
511         n = ((val & A10_PLL6_FACTOR_N) >> A10_PLL6_FACTOR_N_SHIFT) + 1;
512
513         switch (sc->id) {
514         case CLKID_A31_PLL6:
515                 *freq = (*freq * n * k) / 2;
516                 break;
517         case CLKID_A31_PLL6_X2:
518                 *freq = *freq * n * k;
519                 break;
520         default:
521                 return (ENXIO);
522         }
523
524         return (0);
525 }
526
527 #define PLL(_type, _recalc, _set_freq, _init)   \
528         [(_type)] = {                           \
529                 .recalc = (_recalc),            \
530                 .set_freq = (_set_freq),        \
531                 .init = (_init)                 \
532         }
533
534 static struct aw_pll_funcs aw_pll_func[] = {
535         PLL(AWPLL_A10_PLL1, a10_pll1_recalc, NULL, NULL),
536         PLL(AWPLL_A10_PLL2, a10_pll2_recalc, a10_pll2_set_freq, NULL),
537         PLL(AWPLL_A10_PLL3, a10_pll3_recalc, a10_pll3_set_freq, a10_pll3_init),
538         PLL(AWPLL_A10_PLL5, a10_pll5_recalc, NULL, NULL),
539         PLL(AWPLL_A10_PLL6, a10_pll6_recalc, a10_pll6_set_freq, a10_pll6_init),
540         PLL(AWPLL_A31_PLL1, a31_pll1_recalc, NULL, NULL),
541         PLL(AWPLL_A31_PLL6, a31_pll6_recalc, NULL, a31_pll6_init),
542 };
543
544 static struct ofw_compat_data compat_data[] = {
545         { "allwinner,sun4i-a10-pll1-clk",       AWPLL_A10_PLL1 },
546         { "allwinner,sun4i-a10-pll2-clk",       AWPLL_A10_PLL2 },
547         { "allwinner,sun4i-a10-pll3-clk",       AWPLL_A10_PLL3 },
548         { "allwinner,sun4i-a10-pll5-clk",       AWPLL_A10_PLL5 },
549         { "allwinner,sun4i-a10-pll6-clk",       AWPLL_A10_PLL6 },
550         { "allwinner,sun6i-a31-pll1-clk",       AWPLL_A31_PLL1 },
551         { "allwinner,sun6i-a31-pll6-clk",       AWPLL_A31_PLL6 },
552         { NULL, 0 }
553 };
554
555 static int
556 aw_pll_init(struct clknode *clk, device_t dev)
557 {
558         clknode_init_parent_idx(clk, 0);
559         return (0);
560 }
561
562 static int
563 aw_pll_set_gate(struct clknode *clk, bool enable)
564 {
565         struct aw_pll_sc *sc;
566         uint32_t val;
567
568         sc = clknode_get_softc(clk);
569
570         DEVICE_LOCK(sc);
571         PLL_READ(sc, &val);
572         if (enable)
573                 val |= AW_PLL_ENABLE;
574         else
575                 val &= ~AW_PLL_ENABLE;
576         PLL_WRITE(sc, val);
577         DEVICE_UNLOCK(sc);
578
579         return (0);
580 }
581
582 static int
583 aw_pll_recalc(struct clknode *clk, uint64_t *freq)
584 {
585         struct aw_pll_sc *sc;
586
587         sc = clknode_get_softc(clk);
588
589         if (aw_pll_func[sc->type].recalc == NULL)
590                 return (ENXIO);
591
592         return (aw_pll_func[sc->type].recalc(sc, freq));
593 }
594
595 static int
596 aw_pll_set_freq(struct clknode *clk, uint64_t fin, uint64_t *fout,
597     int flags, int *stop)
598 {
599         struct aw_pll_sc *sc;
600
601         sc = clknode_get_softc(clk);
602
603         *stop = 1;
604
605         if (aw_pll_func[sc->type].set_freq == NULL)
606                 return (ENXIO);
607
608         return (aw_pll_func[sc->type].set_freq(sc, fin, fout, flags));
609 }
610
611 static clknode_method_t aw_pll_clknode_methods[] = {
612         /* Device interface */
613         CLKNODEMETHOD(clknode_init,             aw_pll_init),
614         CLKNODEMETHOD(clknode_set_gate,         aw_pll_set_gate),
615         CLKNODEMETHOD(clknode_recalc_freq,      aw_pll_recalc),
616         CLKNODEMETHOD(clknode_set_freq,         aw_pll_set_freq),
617         CLKNODEMETHOD_END
618 };
619
620 DEFINE_CLASS_1(aw_pll_clknode, aw_pll_clknode_class, aw_pll_clknode_methods,
621     sizeof(struct aw_pll_sc), clknode_class);
622
623 static int
624 aw_pll_create(device_t dev, bus_addr_t paddr, struct clkdom *clkdom,
625     const char *pclkname, const char *clkname, int index)
626 {
627         enum aw_pll_type type;
628         struct clknode_init_def clkdef;
629         struct aw_pll_sc *sc;
630         struct clknode *clk;
631         int error;
632
633         type = ofw_bus_search_compatible(dev, compat_data)->ocd_data;
634
635         memset(&clkdef, 0, sizeof(clkdef));
636         clkdef.id = index;
637         clkdef.name = clkname;
638         if (pclkname != NULL) {
639                 clkdef.parent_names = malloc(sizeof(char *), M_OFWPROP,
640                     M_WAITOK);
641                 clkdef.parent_names[0] = pclkname;
642                 clkdef.parent_cnt = 1;
643         } else
644                 clkdef.parent_cnt = 0;
645
646         if (aw_pll_func[type].init != NULL) {
647                 error = aw_pll_func[type].init(device_get_parent(dev),
648                     paddr, &clkdef);
649                 if (error != 0) {
650                         device_printf(dev, "clock %s init failed\n", clkname);
651                         return (error);
652                 }
653         }
654
655         clk = clknode_create(clkdom, &aw_pll_clknode_class, &clkdef);
656         if (clk == NULL) {
657                 device_printf(dev, "cannot create clock node\n");
658                 return (ENXIO);
659         }
660         sc = clknode_get_softc(clk);
661         sc->clkdev = device_get_parent(dev);
662         sc->reg = paddr;
663         sc->type = type;
664         sc->id = clkdef.id;
665
666         clknode_register(clkdom, clk);
667
668         free(__DECONST(char *, clkdef.parent_names), M_OFWPROP);
669
670         return (0);
671 }
672
673 static int
674 aw_pll_probe(device_t dev)
675 {
676         if (!ofw_bus_status_okay(dev))
677                 return (ENXIO);
678
679         if (ofw_bus_search_compatible(dev, compat_data)->ocd_data == 0)
680                 return (ENXIO);
681
682         device_set_desc(dev, "Allwinner PLL Clock");
683         return (BUS_PROBE_DEFAULT);
684 }
685
686 static int
687 aw_pll_attach(device_t dev)
688 {
689         struct clkdom *clkdom;
690         const char **names;
691         int index, nout, error;
692         clk_t clk_parent;
693         uint32_t *indices;
694         bus_addr_t paddr;
695         bus_size_t psize;
696         phandle_t node;
697
698         node = ofw_bus_get_node(dev);
699
700         if (ofw_reg_to_paddr(node, 0, &paddr, &psize, NULL) != 0) {
701                 device_printf(dev, "couldn't parse 'reg' property\n");
702                 return (ENXIO);
703         }
704
705         clkdom = clkdom_create(dev);
706
707         nout = clk_parse_ofw_out_names(dev, node, &names, &indices);
708         if (nout == 0) {
709                 device_printf(dev, "no clock outputs found\n");
710                 error = ENOENT;
711                 goto fail;
712         }
713
714         if (clk_get_by_ofw_index(dev, 0, &clk_parent) != 0)
715                 clk_parent = NULL;
716
717         for (index = 0; index < nout; index++) {
718                 error = aw_pll_create(dev, paddr, clkdom,
719                     clk_parent ? clk_get_name(clk_parent) : NULL,
720                     names[index], nout == 1 ? 1 : index);
721                 if (error)
722                         goto fail;
723         }
724
725         if (clkdom_finit(clkdom) != 0) {
726                 device_printf(dev, "cannot finalize clkdom initialization\n");
727                 error = ENXIO;
728                 goto fail;
729         }
730
731         if (bootverbose)
732                 clkdom_dump(clkdom);
733
734         return (0);
735
736 fail:
737         return (error);
738 }
739
740 static device_method_t aw_pll_methods[] = {
741         /* Device interface */
742         DEVMETHOD(device_probe,         aw_pll_probe),
743         DEVMETHOD(device_attach,        aw_pll_attach),
744
745         DEVMETHOD_END
746 };
747
748 static driver_t aw_pll_driver = {
749         "aw_pll",
750         aw_pll_methods,
751         0,
752 };
753
754 static devclass_t aw_pll_devclass;
755
756 EARLY_DRIVER_MODULE(aw_pll, simplebus, aw_pll_driver,
757     aw_pll_devclass, 0, 0, BUS_PASS_BUS + BUS_PASS_ORDER_MIDDLE);