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 --- |