aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorIcenowy Zheng <icenowy@aosc.io>2017-08-15 01:55:29 -0400
committerChen-Yu Tsai <wens@csie.org>2017-08-19 05:04:37 -0400
commitcd030a78f7aa06fe216f6665a6ea84b8f3e5b3d3 (patch)
tree435eb37fb76952e559c44676bfa902819e97d361
parent0a6341555e64915493d2925a1fca61efaa01f570 (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/Kconfig5
-rw-r--r--drivers/clk/sunxi-ng/Makefile1
-rw-r--r--drivers/clk/sunxi-ng/ccu-sun8i-r40.c1290
-rw-r--r--drivers/clk/sunxi-ng/ccu-sun8i-r40.h69
-rw-r--r--include/dt-bindings/clock/sun8i-r40-ccu.h187
-rw-r--r--include/dt-bindings/reset/sun8i-r40-ccu.h130
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
48config SUN8I_DE2_CCU 48config SUN8I_DE2_CCU
49 bool "Support for the Allwinner SoCs DE2 CCU" 49 bool "Support for the Allwinner SoCs DE2 CCU"
50 50
51config SUN8I_R40_CCU
52 bool "Support for the Allwinner R40 CCU"
53 default MACH_SUN8I
54 depends on MACH_SUN8I || COMPILE_TEST
55
51config SUN9I_A80_CCU 56config 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
28obj-$(CONFIG_SUN8I_V3S_CCU) += ccu-sun8i-v3s.o 28obj-$(CONFIG_SUN8I_V3S_CCU) += ccu-sun8i-v3s.o
29obj-$(CONFIG_SUN8I_DE2_CCU) += ccu-sun8i-de2.o 29obj-$(CONFIG_SUN8I_DE2_CCU) += ccu-sun8i-de2.o
30obj-$(CONFIG_SUN8I_R_CCU) += ccu-sun8i-r.o 30obj-$(CONFIG_SUN8I_R_CCU) += ccu-sun8i-r.o
31obj-$(CONFIG_SUN8I_R40_CCU) += ccu-sun8i-r40.o
31obj-$(CONFIG_SUN9I_A80_CCU) += ccu-sun9i-a80.o 32obj-$(CONFIG_SUN9I_A80_CCU) += ccu-sun9i-a80.o
32obj-$(CONFIG_SUN9I_A80_CCU) += ccu-sun9i-a80-de.o 33obj-$(CONFIG_SUN9I_A80_CCU) += ccu-sun9i-a80-de.o
33obj-$(CONFIG_SUN9I_A80_CCU) += ccu-sun9i-a80-usb.o 34obj-$(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. */
33static 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
59static 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. */
68static 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. */
81static 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. */
94static 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. */
104static 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
119static 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. */
138static 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. */
154static 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 */