Deleted Added
full compact
aw_pll.c (302408) aw_pll.c (305436)
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 unchanged lines hidden (view full) ---

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 *
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 unchanged lines hidden (view full) ---

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: stable/11/sys/arm/allwinner/clk/aw_pll.c 299703 2016-05-13 22:28:02Z gonzo $
26 * $FreeBSD: stable/11/sys/arm/allwinner/clk/aw_pll.c 305436 2016-09-05 20:17:18Z manu $
27 */
28
29/*
30 * Allwinner PLL clock
31 */
32
33#include <sys/cdefs.h>
27 */
28
29/*
30 * Allwinner PLL clock
31 */
32
33#include <sys/cdefs.h>
34__FBSDID("$FreeBSD: stable/11/sys/arm/allwinner/clk/aw_pll.c 299703 2016-05-13 22:28:02Z gonzo $");
34__FBSDID("$FreeBSD: stable/11/sys/arm/allwinner/clk/aw_pll.c 305436 2016-09-05 20:17:18Z manu $");
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
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 <arm/allwinner/allwinner_machdep.h>
53
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

--- 36 unchanged lines hidden (view full) ---

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
54#include "clkdev_if.h"
55
56#define AW_PLL_ENABLE (1 << 31)
57
58#define A10_PLL1_OUT_EXT_DIVP (0x3 << 16)
59#define A10_PLL1_OUT_EXT_DIVP_SHIFT 16
60#define A10_PLL1_FACTOR_N (0x1f << 8)
61#define A10_PLL1_FACTOR_N_SHIFT 8

--- 36 unchanged lines hidden (view full) ---

98#define A10_PLL6_FACTOR_N_SHIFT 8
99#define A10_PLL6_FACTOR_K (0x3 << 4)
100#define A10_PLL6_FACTOR_K_SHIFT 4
101#define A10_PLL6_FACTOR_M (0x3 << 0)
102#define A10_PLL6_FACTOR_M_SHIFT 0
103
104#define A10_PLL2_POST_DIV (0xf << 26)
105
106#define A13_PLL2_POST_DIV (0xf << 26)
107#define A13_PLL2_POST_DIV_SHIFT 26
108#define A13_PLL2_FACTOR_N (0x7f << 8)
109#define A13_PLL2_FACTOR_N_SHIFT 8
110#define A13_PLL2_PRE_DIV (0x1f << 0)
111#define A13_PLL2_PRE_DIV_SHIFT 0
112
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

--- 42 unchanged lines hidden (view full) ---

154#define CLKID_A31_PLL6_X2 1
155
156enum aw_pll_type {
157 AWPLL_A10_PLL1 = 1,
158 AWPLL_A10_PLL2,
159 AWPLL_A10_PLL3,
160 AWPLL_A10_PLL5,
161 AWPLL_A10_PLL6,
113#define A23_PLL1_FACTOR_N (0x1f << 8)
114#define A23_PLL1_FACTOR_N_SHIFT 8
115#define A23_PLL1_FACTOR_K (0x3 << 4)
116#define A23_PLL1_FACTOR_K_SHIFT 4
117#define A23_PLL1_FACTOR_M (0x3 << 0)
118#define A23_PLL1_FACTOR_M_SHIFT 0
119#define A23_PLL1_FACTOR_P (0x3 << 16)
120#define A23_PLL1_FACTOR_P_SHIFT 16

--- 42 unchanged lines hidden (view full) ---

163#define CLKID_A31_PLL6_X2 1
164
165enum aw_pll_type {
166 AWPLL_A10_PLL1 = 1,
167 AWPLL_A10_PLL2,
168 AWPLL_A10_PLL3,
169 AWPLL_A10_PLL5,
170 AWPLL_A10_PLL6,
171 AWPLL_A13_PLL2,
162 AWPLL_A23_PLL1,
163 AWPLL_A31_PLL1,
164 AWPLL_A31_PLL6,
165 AWPLL_A80_PLL4,
166};
167
168struct aw_pll_sc {
169 enum aw_pll_type type;

--- 287 unchanged lines hidden (view full) ---

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
464static int
172 AWPLL_A23_PLL1,
173 AWPLL_A31_PLL1,
174 AWPLL_A31_PLL6,
175 AWPLL_A80_PLL4,
176};
177
178struct aw_pll_sc {
179 enum aw_pll_type type;

--- 287 unchanged lines hidden (view full) ---

467 /* PLL6 SATA output has been set to 100MHz in a10_pll6_init */
468 if (*fout != 100000000)
469 return (ERANGE);
470
471 return (0);
472}
473
474static int
475a13_pll2_recalc(struct aw_pll_sc *sc, uint64_t *freq)
476{
477 uint32_t val, post_div, n, pre_div;
478
479 DEVICE_LOCK(sc);
480 PLL_READ(sc, &val);
481 DEVICE_UNLOCK(sc);
482
483 post_div = ((val & A13_PLL2_POST_DIV) >> A13_PLL2_POST_DIV_SHIFT) + 1;
484 if (post_div == 0)
485 post_div = 1;
486 n = (val & A13_PLL2_FACTOR_N) >> A13_PLL2_FACTOR_N_SHIFT;
487 if (n == 0)
488 n = 1;
489 pre_div = ((val & A13_PLL2_PRE_DIV) >> A13_PLL2_PRE_DIV_SHIFT) + 1;
490 if (pre_div == 0)
491 pre_div = 1;
492
493 switch (sc->id) {
494 case SUN4I_A10_PLL2_1X:
495 *freq = (*freq * 2 * n) / pre_div / post_div / 2;
496 break;
497 case SUN4I_A10_PLL2_2X:
498 *freq = (*freq * 2 * n) / pre_div / 4;
499 break;
500 case SUN4I_A10_PLL2_4X:
501 *freq = (*freq * 2 * n) / pre_div / 2;
502 break;
503 case SUN4I_A10_PLL2_8X:
504 *freq = (*freq * 2 * n) / pre_div;
505 break;
506 default:
507 return (EINVAL);
508 }
509
510 return (0);
511}
512
513static int
514a13_pll2_set_freq(struct aw_pll_sc *sc, uint64_t fin, uint64_t *fout,
515 int flags)
516{
517 uint32_t val, post_div, n, pre_div;
518
519 if (sc->id != SUN4I_A10_PLL2_1X)
520 return (ENXIO);
521
522 /*
523 * Audio Codec needs PLL2-1X to be either 24576000 or 22579200.
524 *
525 * PLL2-1X output frequency is (48MHz * n) / pre_div / post_div / 2.
526 * To get as close as possible to the desired rate, we use a
527 * pre-divider of 21 and a post-divider of 4. With these values,
528 * a multiplier of 86 or 79 gets us close to the target rates.
529 */
530 if (*fout != 24576000 && *fout != 22579200)
531 return (EINVAL);
532
533 pre_div = 21;
534 post_div = 4;
535 n = (*fout * pre_div * post_div * 2) / (2 * fin);
536
537 DEVICE_LOCK(sc);
538 PLL_READ(sc, &val);
539 val &= ~(A13_PLL2_POST_DIV | A13_PLL2_FACTOR_N | A13_PLL2_PRE_DIV);
540 val |= ((post_div - 1) << A13_PLL2_POST_DIV_SHIFT);
541 val |= (n << A13_PLL2_FACTOR_N_SHIFT);
542 val |= ((pre_div - 1) << A13_PLL2_PRE_DIV_SHIFT);
543 PLL_WRITE(sc, val);
544 DEVICE_UNLOCK(sc);
545
546 return (0);
547}
548
549static int
465a23_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

--- 113 unchanged lines hidden (view full) ---

586 }
587
588static 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),
550a23_pll1_recalc(struct aw_pll_sc *sc, uint64_t *freq)
551{
552 uint32_t val, m, n, k, p;
553
554 DEVICE_LOCK(sc);
555 PLL_READ(sc, &val);
556 DEVICE_UNLOCK(sc);
557

--- 113 unchanged lines hidden (view full) ---

671 }
672
673static struct aw_pll_funcs aw_pll_func[] = {
674 PLL(AWPLL_A10_PLL1, a10_pll1_recalc, NULL, NULL),
675 PLL(AWPLL_A10_PLL2, a10_pll2_recalc, a10_pll2_set_freq, NULL),
676 PLL(AWPLL_A10_PLL3, a10_pll3_recalc, a10_pll3_set_freq, a10_pll3_init),
677 PLL(AWPLL_A10_PLL5, a10_pll5_recalc, NULL, NULL),
678 PLL(AWPLL_A10_PLL6, a10_pll6_recalc, a10_pll6_set_freq, a10_pll6_init),
679 PLL(AWPLL_A13_PLL2, a13_pll2_recalc, a13_pll2_set_freq, NULL),
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
600static 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 },
680 PLL(AWPLL_A23_PLL1, a23_pll1_recalc, NULL, NULL),
681 PLL(AWPLL_A31_PLL1, a31_pll1_recalc, NULL, NULL),
682 PLL(AWPLL_A31_PLL6, a31_pll6_recalc, NULL, a31_pll6_init),
683 PLL(AWPLL_A80_PLL4, a80_pll4_recalc, NULL, NULL),
684};
685
686static struct ofw_compat_data compat_data[] = {
687 { "allwinner,sun4i-a10-pll1-clk", AWPLL_A10_PLL1 },
688 { "allwinner,sun4i-a10-pll2-clk", AWPLL_A10_PLL2 },
689 { "allwinner,sun4i-a10-pll3-clk", AWPLL_A10_PLL3 },
690 { "allwinner,sun4i-a10-pll5-clk", AWPLL_A10_PLL5 },
691 { "allwinner,sun4i-a10-pll6-clk", AWPLL_A10_PLL6 },
692 { "allwinner,sun5i-a13-pll2-clk", AWPLL_A13_PLL2 },
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
613static int

--- 202 unchanged lines hidden ---
693 { "allwinner,sun6i-a31-pll1-clk", AWPLL_A31_PLL1 },
694 { "allwinner,sun6i-a31-pll6-clk", AWPLL_A31_PLL6 },
695 { "allwinner,sun8i-a23-pll1-clk", AWPLL_A23_PLL1 },
696 { "allwinner,sun9i-a80-pll4-clk", AWPLL_A80_PLL4 },
697 { NULL, 0 }
698};
699
700static int

--- 202 unchanged lines hidden ---