diff options
| author | Icenowy Zheng <icenowy@aosc.io> | 2017-08-15 01:55:29 -0400 |
|---|---|---|
| committer | Chen-Yu Tsai <wens@csie.org> | 2017-08-19 05:04:37 -0400 |
| commit | cd030a78f7aa06fe216f6665a6ea84b8f3e5b3d3 (patch) | |
| tree | 435eb37fb76952e559c44676bfa902819e97d361 | |
| parent | 0a6341555e64915493d2925a1fca61efaa01f570 (diff) | |
clk: sunxi-ng: support R40 SoC
Allwinner R40 SoC have a clock controller module in the style of the
SoCs beyond sun6i, however, it's more rich and complex.
Add support for it.
Signed-off-by: Icenowy Zheng <icenowy@aosc.io>
Signed-off-by: Chen-Yu Tsai <wens@csie.org>
| -rw-r--r-- | drivers/clk/sunxi-ng/Kconfig | 5 | ||||
| -rw-r--r-- | drivers/clk/sunxi-ng/Makefile | 1 | ||||
| -rw-r--r-- | drivers/clk/sunxi-ng/ccu-sun8i-r40.c | 1290 | ||||
| -rw-r--r-- | drivers/clk/sunxi-ng/ccu-sun8i-r40.h | 69 | ||||
| -rw-r--r-- | include/dt-bindings/clock/sun8i-r40-ccu.h | 187 | ||||
| -rw-r--r-- | include/dt-bindings/reset/sun8i-r40-ccu.h | 130 |
6 files changed, 1682 insertions, 0 deletions
diff --git a/drivers/clk/sunxi-ng/Kconfig b/drivers/clk/sunxi-ng/Kconfig index 7342928c35cd..7a360737fe3c 100644 --- a/drivers/clk/sunxi-ng/Kconfig +++ b/drivers/clk/sunxi-ng/Kconfig | |||
| @@ -48,6 +48,11 @@ config SUN8I_V3S_CCU | |||
| 48 | config SUN8I_DE2_CCU | 48 | config SUN8I_DE2_CCU |
| 49 | bool "Support for the Allwinner SoCs DE2 CCU" | 49 | bool "Support for the Allwinner SoCs DE2 CCU" |
| 50 | 50 | ||
| 51 | config SUN8I_R40_CCU | ||
| 52 | bool "Support for the Allwinner R40 CCU" | ||
| 53 | default MACH_SUN8I | ||
| 54 | depends on MACH_SUN8I || COMPILE_TEST | ||
| 55 | |||
| 51 | config SUN9I_A80_CCU | 56 | config SUN9I_A80_CCU |
| 52 | bool "Support for the Allwinner A80 CCU" | 57 | bool "Support for the Allwinner A80 CCU" |
| 53 | default MACH_SUN9I | 58 | default MACH_SUN9I |
diff --git a/drivers/clk/sunxi-ng/Makefile b/drivers/clk/sunxi-ng/Makefile index 0c45fa50283d..58741cd647c3 100644 --- a/drivers/clk/sunxi-ng/Makefile +++ b/drivers/clk/sunxi-ng/Makefile | |||
| @@ -28,6 +28,7 @@ obj-$(CONFIG_SUN8I_H3_CCU) += ccu-sun8i-h3.o | |||
| 28 | obj-$(CONFIG_SUN8I_V3S_CCU) += ccu-sun8i-v3s.o | 28 | obj-$(CONFIG_SUN8I_V3S_CCU) += ccu-sun8i-v3s.o |
| 29 | obj-$(CONFIG_SUN8I_DE2_CCU) += ccu-sun8i-de2.o | 29 | obj-$(CONFIG_SUN8I_DE2_CCU) += ccu-sun8i-de2.o |
| 30 | obj-$(CONFIG_SUN8I_R_CCU) += ccu-sun8i-r.o | 30 | obj-$(CONFIG_SUN8I_R_CCU) += ccu-sun8i-r.o |
| 31 | obj-$(CONFIG_SUN8I_R40_CCU) += ccu-sun8i-r40.o | ||
| 31 | obj-$(CONFIG_SUN9I_A80_CCU) += ccu-sun9i-a80.o | 32 | obj-$(CONFIG_SUN9I_A80_CCU) += ccu-sun9i-a80.o |
| 32 | obj-$(CONFIG_SUN9I_A80_CCU) += ccu-sun9i-a80-de.o | 33 | obj-$(CONFIG_SUN9I_A80_CCU) += ccu-sun9i-a80-de.o |
| 33 | obj-$(CONFIG_SUN9I_A80_CCU) += ccu-sun9i-a80-usb.o | 34 | obj-$(CONFIG_SUN9I_A80_CCU) += ccu-sun9i-a80-usb.o |
diff --git a/drivers/clk/sunxi-ng/ccu-sun8i-r40.c b/drivers/clk/sunxi-ng/ccu-sun8i-r40.c new file mode 100644 index 000000000000..933f2e68f42a --- /dev/null +++ b/drivers/clk/sunxi-ng/ccu-sun8i-r40.c | |||
| @@ -0,0 +1,1290 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (c) 2017 Icenowy Zheng <icenowy@aosc.io> | ||
| 3 | * | ||
| 4 | * This software is licensed under the terms of the GNU General Public | ||
| 5 | * License version 2, as published by the Free Software Foundation, and | ||
| 6 | * may be copied, distributed, and modified under those terms. | ||
| 7 | * | ||
| 8 | * This program is distributed in the hope that it will be useful, | ||
| 9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 11 | * GNU General Public License for more details. | ||
| 12 | */ | ||
| 13 | |||
| 14 | #include <linux/clk-provider.h> | ||
| 15 | #include <linux/of_address.h> | ||
| 16 | |||
| 17 | #include "ccu_common.h" | ||
| 18 | #include "ccu_reset.h" | ||
| 19 | |||
| 20 | #include "ccu_div.h" | ||
| 21 | #include "ccu_gate.h" | ||
| 22 | #include "ccu_mp.h" | ||
| 23 | #include "ccu_mult.h" | ||
| 24 | #include "ccu_nk.h" | ||
| 25 | #include "ccu_nkm.h" | ||
| 26 | #include "ccu_nkmp.h" | ||
| 27 | #include "ccu_nm.h" | ||
| 28 | #include "ccu_phase.h" | ||
| 29 | |||
| 30 | #include "ccu-sun8i-r40.h" | ||
| 31 | |||
| 32 | /* TODO: The result of N*K is required to be in [10, 88] range. */ | ||
| 33 | static struct ccu_nkmp pll_cpu_clk = { | ||
| 34 | .enable = BIT(31), | ||
| 35 | .lock = BIT(28), | ||
| 36 | .n = _SUNXI_CCU_MULT(8, 5), | ||
| 37 | .k = _SUNXI_CCU_MULT(4, 2), | ||
| 38 | .m = _SUNXI_CCU_DIV(0, 2), | ||
| 39 | .p = _SUNXI_CCU_DIV_MAX(16, 2, 4), | ||
| 40 | .common = { | ||
| 41 | .reg = 0x000, | ||
| 42 | .hw.init = CLK_HW_INIT("pll-cpu", | ||
| 43 | "osc24M", | ||
| 44 | &ccu_nkmp_ops, | ||
| 45 | CLK_SET_RATE_UNGATE), | ||
| 46 | }, | ||
| 47 | }; | ||
| 48 | |||
| 49 | /* | ||
| 50 | * The Audio PLL is supposed to have 4 outputs: 3 fixed factors from | ||
| 51 | * the base (2x, 4x and 8x), and one variable divider (the one true | ||
| 52 | * pll audio). | ||
| 53 | * | ||
| 54 | * We don't have any need for the variable divider for now, so we just | ||
| 55 | * hardcode it to match with the clock names | ||
| 56 | */ | ||
| 57 | #define SUN8I_R40_PLL_AUDIO_REG 0x008 | ||
| 58 | |||
| 59 | static SUNXI_CCU_NM_WITH_GATE_LOCK(pll_audio_base_clk, "pll-audio-base", | ||
| 60 | "osc24M", 0x008, | ||
| 61 | 8, 7, /* N */ | ||
| 62 | 0, 5, /* M */ | ||
| 63 | BIT(31), /* gate */ | ||
| 64 | BIT(28), /* lock */ | ||
| 65 | CLK_SET_RATE_UNGATE); | ||
| 66 | |||
| 67 | /* TODO: The result of N/M is required to be in [8, 25] range. */ | ||
| 68 | static SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK(pll_video0_clk, "pll-video0", | ||
| 69 | "osc24M", 0x0010, | ||
| 70 | 8, 7, /* N */ | ||
| 71 | 0, 4, /* M */ | ||
| 72 | BIT(24), /* frac enable */ | ||
| 73 | BIT(25), /* frac select */ | ||
| 74 | 270000000, /* frac rate 0 */ | ||
| 75 | 297000000, /* frac rate 1 */ | ||
| 76 | BIT(31), /* gate */ | ||
| 77 | BIT(28), /* lock */ | ||
| 78 | CLK_SET_RATE_UNGATE); | ||
| 79 | |||
| 80 | /* TODO: The result of N/M is required to be in [8, 25] range. */ | ||
| 81 | static SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK(pll_ve_clk, "pll-ve", | ||
| 82 | "osc24M", 0x0018, | ||
| 83 | 8, 7, /* N */ | ||
| 84 | 0, 4, /* M */ | ||
| 85 | BIT(24), /* frac enable */ | ||
| 86 | BIT(25), /* frac select */ | ||
| 87 | 270000000, /* frac rate 0 */ | ||
| 88 | 297000000, /* frac rate 1 */ | ||
| 89 | BIT(31), /* gate */ | ||
| 90 | BIT(28), /* lock */ | ||
| 91 | CLK_SET_RATE_UNGATE); | ||
| 92 | |||
| 93 | /* TODO: The result of N*K is required to be in [10, 77] range. */ | ||
| 94 | static SUNXI_CCU_NKM_WITH_GATE_LOCK(pll_ddr0_clk, "pll-ddr0", | ||
| 95 | "osc24M", 0x020, | ||
| 96 | 8, 5, /* N */ | ||
| 97 | 4, 2, /* K */ | ||
| 98 | 0, 2, /* M */ | ||
| 99 | BIT(31), /* gate */ | ||
| 100 | BIT(28), /* lock */ | ||
| 101 | CLK_SET_RATE_UNGATE); | ||
| 102 | |||
| 103 | /* TODO: The result of N*K is required to be in [21, 58] range. */ | ||
| 104 | static struct ccu_nk pll_periph0_clk = { | ||
| 105 | .enable = BIT(31), | ||
| 106 | .lock = BIT(28), | ||
| 107 | .n = _SUNXI_CCU_MULT(8, 5), | ||
| 108 | .k = _SUNXI_CCU_MULT(4, 2), | ||
| 109 | .fixed_post_div = 2, | ||
| 110 | .common = { | ||
| 111 | .reg = 0x028, | ||
| 112 | .features = CCU_FEATURE_FIXED_POSTDIV, | ||
| 113 | .hw.init = CLK_HW_INIT("pll-periph0", "osc24M", | ||
| 114 | &ccu_nk_ops, | ||
| 115 | CLK_SET_RATE_UNGATE), | ||
| 116 | }, | ||
| 117 | }; | ||
| 118 | |||
| 119 | static struct ccu_div pll_periph0_sata_clk = { | ||
| 120 | .enable = BIT(24), | ||
| 121 | .div = _SUNXI_CCU_DIV(0, 2), | ||
| 122 | /* | ||
| 123 | * The formula of pll-periph0 (1x) is 24MHz*N*K/2, and the formula | ||
| 124 | * of pll-periph0-sata is 24MHz*N*K/M/6, so the postdiv here is | ||
| 125 | * 6/2 = 3. | ||
| 126 | */ | ||
| 127 | .fixed_post_div = 3, | ||
| 128 | .common = { | ||
| 129 | .reg = 0x028, | ||
| 130 | .features = CCU_FEATURE_FIXED_POSTDIV, | ||
| 131 | .hw.init = CLK_HW_INIT("pll-periph0-sata", | ||
| 132 | "pll-periph0", | ||
| 133 | &ccu_div_ops, 0), | ||
| 134 | }, | ||
| 135 | }; | ||
| 136 | |||
| 137 | /* TODO: The result of N*K is required to be in [21, 58] range. */ | ||
| 138 | static struct ccu_nk pll_periph1_clk = { | ||
| 139 | .enable = BIT(31), | ||
| 140 | .lock = BIT(28), | ||
| 141 | .n = _SUNXI_CCU_MULT(8, 5), | ||
| 142 | .k = _SUNXI_CCU_MULT(4, 2), | ||
| 143 | .fixed_post_div = 2, | ||
| 144 | .common = { | ||
| 145 | .reg = 0x02c, | ||
| 146 | .features = CCU_FEATURE_FIXED_POSTDIV, | ||
| 147 | .hw.init = CLK_HW_INIT("pll-periph1", "osc24M", | ||
| 148 | &ccu_nk_ops, | ||
| 149 | CLK_SET_RATE_UNGATE), | ||
| 150 | }, | ||
| 151 | }; | ||
| 152 | |||
| 153 | /* TODO: The result of N/M is required to be in [8, 25] range. */ | ||
| 154 | static SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK(pll_video1_clk, "pll-video1", | ||
| 155 | "osc24M", 0x030, | ||
| 156 | 8, 7, /* N */ | ||
| 157 | 0, 4, /* M */ | ||
| 158 | BIT(24), /* frac enable */ | ||
| 159 | BIT(25), /* frac select */ | ||
| 160 | 270000000, /* frac rate 0 */ | ||
| 161 | 297000000, /* frac rate 1 */ | ||
