aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStephen Boyd <sboyd@codeaurora.org>2016-09-14 14:10:15 -0400
committerStephen Boyd <sboyd@codeaurora.org>2016-09-14 14:10:15 -0400
commitde64f5c87d7422fbdc502aa5934fafecb4e2da32 (patch)
treec69675457f8f629835ed1866624aba9287f3f7bf
parent3db385ea144daea9c6e1a15f98eacafaec9ad9f1 (diff)
parentd63a5e7c713a68bd368016f2022326a1a91310d8 (diff)
Merge tag 'sunxi-clk-for-4.9' of https://git.kernel.org/pub/scm/linux/kernel/git/mripard/linux into clk-next
Pull Allwinner clock driver changes from Maxime Ripard: Four more SoCs converted to the new clock framework (A31, A31s, A23 and A33). * tag 'sunxi-clk-for-4.9' of https://git.kernel.org/pub/scm/linux/kernel/git/mripard/linux: clk: sunxi-ng: Add hardware dependency clk: sunxi-ng: Add A23 CCU clk: sunxi-ng: Add A33 CCU support clk: sunxi-ng: Add N-class clocks support clk: sunxi-ng: mux: Add mux table macro clk: sunxi-ng: div: Allow to set a maximum clk: sunxi-ng: div: Add kerneldoc for the _ccu_div structure clk: sunxi-ng: div: Add mux table macros clk: sunxi-ng: Add A31/A31s clocks clk: sunxi-ng: mux: Add clk notifier functions clk: sunxi-ng: mux: support fixed pre-dividers on multiple parents clk: sunxi-ng: mux: Add support for mux tables clk: sunxi-ng: mux: Rename mux macro to be consistent clk: sunxi-ng: nkm: Add mux to support multiple parents clk: sunxi-ng: mux: Increase fixed pre-divider div size
-rw-r--r--Documentation/devicetree/bindings/clock/sunxi-ccu.txt5
-rw-r--r--drivers/clk/sunxi-ng/Kconfig39
-rw-r--r--drivers/clk/sunxi-ng/Makefile4
-rw-r--r--drivers/clk/sunxi-ng/ccu-sun6i-a31.c1235
-rw-r--r--drivers/clk/sunxi-ng/ccu-sun6i-a31.h72
-rw-r--r--drivers/clk/sunxi-ng/ccu-sun8i-a23-a33.h63
-rw-r--r--drivers/clk/sunxi-ng/ccu-sun8i-a23.c737
-rw-r--r--drivers/clk/sunxi-ng/ccu-sun8i-a33.c780
-rw-r--r--drivers/clk/sunxi-ng/ccu-sun8i-h3.c10
-rw-r--r--drivers/clk/sunxi-ng/ccu_div.h66
-rw-r--r--drivers/clk/sunxi-ng/ccu_mp.c23
-rw-r--r--drivers/clk/sunxi-ng/ccu_mp.h2
-rw-r--r--drivers/clk/sunxi-ng/ccu_mult.c133
-rw-r--r--drivers/clk/sunxi-ng/ccu_mult.h35
-rw-r--r--drivers/clk/sunxi-ng/ccu_mux.c56
-rw-r--r--drivers/clk/sunxi-ng/ccu_mux.h68
-rw-r--r--drivers/clk/sunxi-ng/ccu_nkm.c44
-rw-r--r--drivers/clk/sunxi-ng/ccu_nkm.h23
-rw-r--r--drivers/clk/sunxi-ng/ccu_nkmp.c21
-rw-r--r--drivers/clk/sunxi-ng/ccu_nm.c16
-rw-r--r--include/dt-bindings/clock/sun6i-a31-ccu.h187
-rw-r--r--include/dt-bindings/clock/sun8i-a23-a33-ccu.h127
-rw-r--r--include/dt-bindings/reset/sun6i-a31-ccu.h106
-rw-r--r--include/dt-bindings/reset/sun8i-a23-a33-ccu.h87
24 files changed, 3860 insertions, 79 deletions
diff --git a/Documentation/devicetree/bindings/clock/sunxi-ccu.txt b/Documentation/devicetree/bindings/clock/sunxi-ccu.txt
index cb91507ffb1e..3868458a5feb 100644
--- a/Documentation/devicetree/bindings/clock/sunxi-ccu.txt
+++ b/Documentation/devicetree/bindings/clock/sunxi-ccu.txt
@@ -2,7 +2,10 @@ Allwinner Clock Control Unit Binding
2------------------------------------ 2------------------------------------
3 3
4Required properties : 4Required properties :
5- compatible: must contain one of the following compatible: 5- compatible: must contain one of the following compatibles:
6 - "allwinner,sun6i-a31-ccu"
7 - "allwinner,sun8i-a23-ccu"
8 - "allwinner,sun8i-a33-ccu"
6 - "allwinner,sun8i-h3-ccu" 9 - "allwinner,sun8i-h3-ccu"
7 10
8- reg: Must contain the registers base address and length 11- reg: Must contain the registers base address and length
diff --git a/drivers/clk/sunxi-ng/Kconfig b/drivers/clk/sunxi-ng/Kconfig
index 2afcbd39e41e..254d9526c018 100644
--- a/drivers/clk/sunxi-ng/Kconfig
+++ b/drivers/clk/sunxi-ng/Kconfig
@@ -1,5 +1,6 @@
1config SUNXI_CCU 1config SUNXI_CCU
2 bool "Clock support for Allwinner SoCs" 2 bool "Clock support for Allwinner SoCs"
3 depends on ARCH_SUNXI || COMPILE_TEST
3 default ARCH_SUNXI 4 default ARCH_SUNXI
4 5
5if SUNXI_CCU 6if SUNXI_CCU
@@ -19,6 +20,10 @@ config SUNXI_CCU_GATE
19config SUNXI_CCU_MUX 20config SUNXI_CCU_MUX
20 bool 21 bool
21 22
23config SUNXI_CCU_MULT
24 bool
25 select SUNXI_CCU_MUX
26
22config SUNXI_CCU_PHASE 27config SUNXI_CCU_PHASE
23 bool 28 bool
24 29
@@ -51,6 +56,40 @@ config SUNXI_CCU_MP
51 56
52# SoC Drivers 57# SoC Drivers
53 58
59config SUN6I_A31_CCU
60 bool "Support for the Allwinner A31/A31s CCU"
61 select SUNXI_CCU_DIV
62 select SUNXI_CCU_NK
63 select SUNXI_CCU_NKM
64 select SUNXI_CCU_NM
65 select SUNXI_CCU_MP
66 select SUNXI_CCU_PHASE
67 default MACH_SUN6I
68
69config SUN8I_A23_CCU
70 bool "Support for the Allwinner A23 CCU"
71 select SUNXI_CCU_DIV
72 select SUNXI_CCU_MULT
73 select SUNXI_CCU_NK
74 select SUNXI_CCU_NKM
75 select SUNXI_CCU_NKMP
76 select SUNXI_CCU_NM
77 select SUNXI_CCU_MP
78 select SUNXI_CCU_PHASE
79 default MACH_SUN8I
80
81config SUN8I_A33_CCU
82 bool "Support for the Allwinner A33 CCU"
83 select SUNXI_CCU_DIV
84 select SUNXI_CCU_MULT
85 select SUNXI_CCU_NK
86 select SUNXI_CCU_NKM
87 select SUNXI_CCU_NKMP
88 select SUNXI_CCU_NM
89 select SUNXI_CCU_MP
90 select SUNXI_CCU_PHASE
91 default MACH_SUN8I
92
54config SUN8I_H3_CCU 93config SUN8I_H3_CCU
55 bool "Support for the Allwinner H3 CCU" 94 bool "Support for the Allwinner H3 CCU"
56 select SUNXI_CCU_DIV 95 select SUNXI_CCU_DIV
diff --git a/drivers/clk/sunxi-ng/Makefile b/drivers/clk/sunxi-ng/Makefile
index 633ce642ffae..106cba27c331 100644
--- a/drivers/clk/sunxi-ng/Makefile
+++ b/drivers/clk/sunxi-ng/Makefile
@@ -7,6 +7,7 @@ obj-$(CONFIG_SUNXI_CCU_DIV) += ccu_div.o
7obj-$(CONFIG_SUNXI_CCU_FRAC) += ccu_frac.o 7obj-$(CONFIG_SUNXI_CCU_FRAC) += ccu_frac.o
8obj-$(CONFIG_SUNXI_CCU_GATE) += ccu_gate.o 8obj-$(CONFIG_SUNXI_CCU_GATE) += ccu_gate.o
9obj-$(CONFIG_SUNXI_CCU_MUX) += ccu_mux.o 9obj-$(CONFIG_SUNXI_CCU_MUX) += ccu_mux.o
10obj-$(CONFIG_SUNXI_CCU_MULT) += ccu_mult.o
10obj-$(CONFIG_SUNXI_CCU_PHASE) += ccu_phase.o 11obj-$(CONFIG_SUNXI_CCU_PHASE) += ccu_phase.o
11 12
12# Multi-factor clocks 13# Multi-factor clocks
@@ -17,4 +18,7 @@ obj-$(CONFIG_SUNXI_CCU_NM) += ccu_nm.o
17obj-$(CONFIG_SUNXI_CCU_MP) += ccu_mp.o 18obj-$(CONFIG_SUNXI_CCU_MP) += ccu_mp.o
18 19
19# SoC support 20# SoC support
21obj-$(CONFIG_SUN6I_A31_CCU) += ccu-sun6i-a31.o
22obj-$(CONFIG_SUN8I_A23_CCU) += ccu-sun8i-a23.o
23obj-$(CONFIG_SUN8I_A33_CCU) += ccu-sun8i-a33.o
20obj-$(CONFIG_SUN8I_H3_CCU) += ccu-sun8i-h3.o 24obj-$(CONFIG_SUN8I_H3_CCU) += ccu-sun8i-h3.o
diff --git a/drivers/clk/sunxi-ng/ccu-sun6i-a31.c b/drivers/clk/sunxi-ng/ccu-sun6i-a31.c
new file mode 100644
index 000000000000..f1d61faa5bd9
--- /dev/null
+++ b/drivers/clk/sunxi-ng/ccu-sun6i-a31.c
@@ -0,0 +1,1235 @@
1/*
2 * Copyright (c) 2016 Chen-Yu Tsai
3 *
4 * Chen-Yu Tsai <wens@csie.org>
5 *
6 * Based on ccu-sun8i-h3.c by Maxime Ripard.
7 *
8 * This software is licensed under the terms of the GNU General Public
9 * License version 2, as published by the Free Software Foundation, and
10 * may be copied, distributed, and modified under those terms.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 */
17
18#include <linux/clk-provider.h>
19#include <linux/of_address.h>
20
21#include "ccu_common.h"
22#include "ccu_reset.h"
23
24#include "ccu_div.h"
25#include "ccu_gate.h"
26#include "ccu_mp.h"
27#include "ccu_mult.h"
28#include "ccu_mux.h"
29#include "ccu_nk.h"
30#include "ccu_nkm.h"
31#include "ccu_nkmp.h"
32#include "ccu_nm.h"
33#include "ccu_phase.h"
34
35#include "ccu-sun6i-a31.h"
36
37static SUNXI_CCU_NKM_WITH_GATE_LOCK(pll_cpu_clk, "pll-cpu",
38 "osc24M", 0x000,
39 8, 5, /* N */
40 4, 2, /* K */
41 0, 2, /* M */
42 BIT(31), /* gate */
43 BIT(28), /* lock */
44 0);
45
46/*
47 * The Audio PLL is supposed to have 4 outputs: 3 fixed factors from
48 * the base (2x, 4x and 8x), and one variable divider (the one true
49 * pll audio).
50 *
51 * We don't have any need for the variable divider for now, so we just
52 * hardcode it to match with the clock names
53 */
54#define SUN6I_A31_PLL_AUDIO_REG 0x008
55
56static SUNXI_CCU_NM_WITH_GATE_LOCK(pll_audio_base_clk, "pll-audio-base",
57 "osc24M", 0x008,
58 8, 7, /* N */
59 0, 5, /* M */
60 BIT(31), /* gate */
61 BIT(28), /* lock */
62 0);
63
64static SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK(pll_video0_clk, "pll-video0",
65 "osc24M", 0x010,
66 8, 7, /* N */
67 0, 4, /* M */
68 BIT(24), /* frac enable */
69 BIT(25), /* frac select */
70 270000000, /* frac rate 0 */
71 297000000, /* frac rate 1 */
72 BIT(31), /* gate */
73 BIT(28), /* lock */
74 0);
75
76static SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK(pll_ve_clk, "pll-ve",
77 "osc24M", 0x018,
78 8, 7, /* N */
79 0, 4, /* M */
80 BIT(24), /* frac enable */
81 BIT(25), /* frac select */
82 270000000, /* frac rate 0 */
83 297000000, /* frac rate 1 */
84 BIT(31), /* gate */
85 BIT(28), /* lock */
86 0);
87
88static SUNXI_CCU_NKM_WITH_GATE_LOCK(pll_ddr_clk, "pll-ddr",
89 "osc24M", 0x020,
90 8, 5, /* N */
91 4, 2, /* K */
92 0, 2, /* M */
93 BIT(31), /* gate */
94 BIT(28), /* lock */
95 0);
96
97static SUNXI_CCU_NK_WITH_GATE_LOCK_POSTDIV(pll_periph_clk, "pll-periph",
98 "osc24M", 0x028,
99 8, 5, /* N */
100 4, 2, /* K */
101 BIT(31), /* gate */
102 BIT(28), /* lock */
103 2, /* post-div */
104 0);
105
106static SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK(pll_video1_clk, "pll-video1",
107 "osc24M", 0x030,
108 8, 7, /* N */
109 0, 4, /* M */
110 BIT(24), /* frac enable */
111 BIT(25), /* frac select */
112 270000000, /* frac rate 0 */
113 297000000, /* frac rate 1 */
114 BIT(31), /* gate */
115 BIT(28), /* lock */
116 0);
117
118static SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK(pll_gpu_clk, "pll-gpu",
119 "osc24M", 0x038,
120 8, 7, /* N */
121 0, 4, /* M */
122 BIT(24), /* frac enable */
123 BIT(25), /* frac select */
124 270000000, /* frac rate 0 */
125 297000000, /* frac rate 1 */
126 BIT(31), /* gate */
127 BIT(28), /* lock */
128 0);
129
130/*
131 * The MIPI PLL has 2 modes: "MIPI" and "HDMI".
132 *
133 * The MIPI mode is a standard NKM-style clock. The HDMI mode is an
134 * integer / fractional clock with switchable multipliers and dividers.
135 * This is not supported here. We hardcode the PLL to MIPI mode.
136 */
137#define SUN6I_A31_PLL_MIPI_REG 0x040
138
139static const char * const pll_mipi_parents[] = { "pll-video0", "pll-video1" };
140static SUNXI_CCU_NKM_WITH_MUX_GATE_LOCK(pll_mipi_clk, "pll-mipi",
141 pll_mipi_parents, 0x040,
142 8, 4, /* N */
143 4, 2, /* K */
144 0, 4, /* M */
145 21, 0, /* mux */
146 BIT(31), /* gate */
147 BIT(28), /* lock */
148 0);
149
150static SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK(pll9_clk, "pll9",
151 "osc24M", 0x044,
152 8, 7, /* N */
153 0, 4, /* M */
154 BIT(24), /* frac enable */
155 BIT(25), /* frac select */
156 270000000, /* frac rate 0 */
157 297000000, /* frac rate 1 */
158 BIT(31), /* gate */
159 BIT(28), /* lock */
160 0);
161
162static SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK(pll10_clk, "pll10",
163 "osc24M", 0x048,
164 8, 7, /* N */
165 0, 4, /* M */
166 BIT(24), /* frac enable */
167 BIT(25), /* frac select */
168 270000000, /* frac rate 0 */
169 297000000, /* frac rate 1 */
170 BIT(31), /* gate */
171 BIT(28), /* lock */
172 0);
173
174static const char * const cpux_parents[] = { "osc32k", "osc24M",
175 "pll-cpu", "pll-cpu" };
176static SUNXI_CCU_MUX(cpu_clk, "cpu", cpux_parents,
177 0x050, 16, 2, CLK_SET_RATE_PARENT | CLK_IS_CRITICAL);
178
179static struct clk_div_table axi_div_table[] = {
180 { .val = 0, .div = 1 },
181 { .val = 1, .div = 2 },
182 { .val = 2, .div = 3 },
183 { .val = 3, .div = 4 },
184 { .val = 4, .div = 4 },
185 { .val = 5, .div = 4 },
186 { .val = 6, .div = 4 },
187 { .val = 7, .div = 4 },
188 { /* Sentinel */ },
189};
190
191static SUNXI_CCU_DIV_TABLE(axi_clk, "axi", "cpu",
192 0x050, 0, 3, axi_div_table, 0);
193
194static const char * const ahb1_parents[] = { "osc32k", "osc24M",
195 "axi", "pll-periph" };
196
197static struct ccu_div ahb1_clk = {
198 .div = _SUNXI_CCU_DIV_FLAGS(4, 2, CLK_DIVIDER_POWER_OF_TWO),
199
200 .mux = {
201 .shift = 12,
202 .width = 2,
203
204 .variable_prediv = {
205 .index = 3,
206 .shift = 6,
207 .width = 2,
208 },
209 },
210
211 .common = {
212 .reg = 0x054,
213 .features = CCU_FEATURE_VARIABLE_PREDIV,
214 .hw.init = CLK_HW_INIT_PARENTS("ahb1",
215 ahb1_parents,
216 &ccu_div_ops,
217 0),
218 },
219};
220
221static struct clk_div_table apb1_div_table[] = {
222 { .val = 0, .div = 2 },
223 { .val = 1, .div = 2 },
224 { .val = 2, .div = 4 },
225 { .val = 3, .div = 8 },
226 { /* Sentinel */ },
227};
228
229static SUNXI_CCU_DIV_TABLE(apb1_clk, "apb1", "ahb1",
230 0x054, 8, 2, apb1_div_table, 0);
231
232static const char * const apb2_parents[] = { "osc32k", "osc24M",
233 "pll-periph", "pll-periph" };
234static SUNXI_CCU_MP_WITH_MUX(apb2_clk, "apb2", apb2_parents, 0x058,
235 0, 5, /* M */
236 16, 2, /* P */
237 24, 2, /* mux */
238 0);
239
240static SUNXI_CCU_GATE(ahb1_mipidsi_clk, "ahb1-mipidsi", "ahb1",
241 0x060, BIT(1), 0);
242static SUNXI_CCU_GATE(ahb1_ss_clk, "ahb1-ss", "ahb1",
243 0x060, BIT(5), 0);
244static SUNXI_CCU_GATE(ahb1_dma_clk, "ahb1-dma", "ahb1",
245 0x060, BIT(6), 0);
246static SUNXI_CCU_GATE(ahb1_mmc0_clk, "ahb1-mmc0", "ahb1",
247 0x060, BIT(8), 0);
248static SUNXI_CCU_GATE(ahb1_mmc1_clk, "ahb1-mmc1", "ahb1",
249 0x060, BIT(9), 0);
250static SUNXI_CCU_GATE(ahb1_mmc2_clk, "ahb1-mmc2", "ahb1",
251 0x060, BIT(10), 0);
252static SUNXI_CCU_GATE(ahb1_mmc3_clk, "ahb1-mmc3", "ahb1",
253 0x060, BIT(12), 0);
254static SUNXI_CCU_GATE(ahb1_nand1_clk, "ahb1-nand1", "ahb1",
255 0x060, BIT(13), 0);
256static SUNXI_CCU_GATE(ahb1_nand0_clk, "ahb1-nand0", "ahb1",
257 0x060, BIT(13), 0);
258static SUNXI_CCU_GATE(ahb1_sdram_clk, "ahb1-sdram", "ahb1",
259 0x060, BIT(14), 0);
260static SUNXI_CCU_GATE(ahb1_emac_clk, "ahb1-emac", "ahb1",
261 0x060, BIT(17), 0);
262static SUNXI_CCU_GATE(ahb1_ts_clk, "ahb1-ts", "ahb1",
263 0x060, BIT(18), 0);
264static SUNXI_CCU_GATE(ahb1_hstimer_clk, "ahb1-hstimer", "ahb1",
265 0x060, BIT(19), 0);
266static SUNXI_CCU_GATE(ahb1_spi0_clk, "ahb1-spi0", "ahb1",
267 0x060, BIT(20), 0);
268static SUNXI_CCU_GATE(ahb1_spi1_clk, "ahb1-spi1", "ahb1",
269 0x060, BIT(21), 0);
270static SUNXI_CCU_GATE(ahb1_spi2_clk, "ahb1-spi2", "ahb1",
271 0x060, BIT(22), 0);
272static SUNXI_CCU_GATE(ahb1_spi3_clk, "ahb1-spi3", "ahb1",
273 0x060, BIT(23), 0);
274static SUNXI_CCU_GATE(ahb1_otg_clk, "ahb1-otg", "ahb1",
275 0x060, BIT(24), 0);
276static SUNXI_CCU_GATE(ahb1_ehci0_clk, "ahb1-ehci0", "ahb1",
277 0x060, BIT(26), 0);
278static SUNXI_CCU_GATE(ahb1_ehci1_clk, "ahb1-ehci1", "ahb1",
279 0x060, BIT(27), 0);
280static SUNXI_CCU_GATE(ahb1_ohci0_clk, "ahb1-ohci0", "ahb1",
281 0x060, BIT(29), 0);
282static SUNXI_CCU_GATE(ahb1_ohci1_clk, "ahb1-ohci1", "ahb1",
283 0x060, BIT(30), 0);
284static SUNXI_CCU_GATE(ahb1_ohci2_clk, "ahb1-ohci2", "ahb1",
285 0x060, BIT(31), 0);
286
287static SUNXI_CCU_GATE(ahb1_ve_clk, "ahb1-ve", "ahb1",
288 0x064, BIT(0), 0);
289static SUNXI_CCU_GATE(ahb1_lcd0_clk, "ahb1-lcd0", "ahb1",
290 0x064, BIT(4), 0);
291static SUNXI_CCU_GATE(ahb1_lcd1_clk, "ahb1-lcd1", "ahb1",
292 0x064, BIT(5), 0);
293static SUNXI_CCU_GATE(ahb1_csi_clk, "ahb1-csi", "ahb1",
294 0x064, BIT(8), 0);
295static SUNXI_CCU_GATE(ahb1_hdmi_clk, "ahb1-hdmi", "ahb1",
296 0x064, BIT(11), 0);
297static SUNXI_CCU_GATE(ahb1_be0_clk, "ahb1-be0", "ahb1",
298 0x064, BIT(12), 0);
299static SUNXI_CCU_GATE(ahb1_be1_clk, "ahb1-be1", "ahb1",
300 0x064, BIT(13), 0);
301static SUNXI_CCU_GATE(ahb1_fe0_clk, "ahb1-fe0", "ahb1",
302 0x064, BIT(14), 0);
303static SUNXI_CCU_GATE(ahb1_fe1_clk, "ahb1-fe1", "ahb1",
304 0x064, BIT(15), 0);
305static SUNXI_CCU_GATE(ahb1_mp_clk, "ahb1-mp", "ahb1",
306 0x064, BIT(18), 0);
307static SUNXI_CCU_GATE(ahb1_gpu_clk, "ahb1-gpu", "ahb1",
308 0x064, BIT(20), 0);
309static SUNXI_CCU_GATE(ahb1_deu0_clk, "ahb1-deu0", "ahb1",
310 0x064, BIT(23), 0);
311static SUNXI_CCU_GATE(ahb1_deu1_clk, "ahb1-deu1", "ahb1",
312 0x064, BIT(24), 0);
313static SUNXI_CCU_GATE(ahb1_drc0_clk, "ahb1-drc0", "ahb1",
314 0x064, BIT(25), 0);
315static SUNXI_CCU_GATE(ahb1_drc1_clk, "ahb1-drc1", "ahb1",
316 0x064, BIT(26), 0);
317
318static SUNXI_CCU_GATE(apb1_codec_clk, "apb1-codec", "apb1",
319 0x068, BIT(0), 0);
320static SUNXI_CCU_GATE(apb1_spdif_clk, "apb1-spdif", "apb1",
321 0x068, BIT(1), 0);
322static SUNXI_CCU_GATE(apb1_digital_mic_clk, "apb1-digital-mic", "apb1",
323 0x068, BIT(4), 0);
324static SUNXI_CCU_GATE(apb1_pio_clk, "apb1-pio", "apb1",
325 0x068, BIT(5), 0);
326static SUNXI_CCU_GATE(apb1_daudio0_clk, "apb1-daudio0", "apb1",
327 0x068, BIT(12), 0);
328static SUNXI_CCU_GATE(apb1_daudio1_clk, "apb1-daudio1", "apb1",
329 0x068, BIT(13), 0);
330
331static SUNXI_CCU_GATE(apb2_i2c0_clk, "apb2-i2c0", "apb2",
332 0x06c, BIT(0), 0);
333static SUNXI_CCU_GATE(apb2_i2c1_clk, "apb2-i2c1", "apb2",
334 0x06c, BIT(1), 0);
335static SUNXI_CCU_GATE(apb2_i2c2_clk, "apb2-i2c2", "apb2",
336 0x06c, BIT(2), 0);
337static SUNXI_CCU_GATE(apb2_i2c3_clk, "apb2-i2c3", "apb2",
338 0x06c, BIT(3), 0);
339static SUNXI_CCU_GATE(apb2_uart0_clk, "apb2-uart0", "apb2",
340 0x06c, BIT(16), 0);
341static SUNXI_CCU_GATE(apb2_uart1_clk, "apb2-uart1", "apb2",
342 0x06c, BIT(17), 0);
343static SUNXI_CCU_GATE(apb2_uart2_clk, "apb2-uart2", "apb2",
344 0x06c, BIT(18), 0);
345static SUNXI_CCU_GATE(apb2_uart3_clk, "apb2-uart3", "apb2",
346 0x06c, BIT(19), 0);
347static SUNXI_CCU_GATE(apb2_uart4_clk, "apb2-uart4", "apb2",
348 0x06c, BIT(20), 0);
349static SUNXI_CCU_GATE(apb2_uart5_clk, "apb2-uart5", "apb2",
350 0x06c, BIT(21), 0);
351
352static const char * const mod0_default_parents[] = { "osc24M", "pll-periph" };
353static SUNXI_CCU_MP_WITH_MUX_GATE(nand0_clk, "nand0", mod0_default_parents,
354 0x080,
355 0, 4, /* M */
356 16, 2, /* P */
357 24, 2, /* mux */
358 BIT(31), /* gate */
359 0);
360
361static SUNXI_CCU_MP_WITH_MUX_GATE(nand1_clk, "nand1", mod0_default_parents,
362 0x084,
363 0, 4, /* M */
364 16, 2, /* P */
365 24, 2, /* mux */
366 BIT(31), /* gate */
367 0);
368
369static SUNXI_CCU_MP_WITH_MUX_GATE(mmc0_clk, "mmc0", mod0_default_parents,
370 0x088,
371 0, 4, /* M */
372 16, 2, /* P */
373 24, 2, /* mux */
374 BIT(31), /* gate */
375 0);
376
377static SUNXI_CCU_PHASE(mmc0_sample_clk, "mmc0_sample", "mmc0",
378 0x088, 20, 3, 0);
379static SUNXI_CCU_PHASE(mmc0_output_clk, "mmc0_output", "mmc0",
380 0x088, 8, 3, 0);
381
382static SUNXI_CCU_MP_WITH_MUX_GATE(mmc1_clk, "mmc1", mod0_default_parents,
383 0x08c,
384 0, 4, /* M */
385 16, 2, /* P */
386 24, 2, /* mux */
387 BIT(31), /* gate */
388 0);
389
390static SUNXI_CCU_PHASE(mmc1_sample_clk, "mmc1_sample", "mmc1",
391 0x08c, 20, 3, 0);
392static SUNXI_CCU_PHASE(mmc1_output_clk, "mmc1_output", "mmc1",
393 0x08c, 8, 3, 0);
394
395static SUNXI_CCU_MP_WITH_MUX_GATE(mmc2_clk, "mmc2", mod0_default_parents,
396 0x090,
397 0, 4, /* M */
398 16, 2, /* P */
399 24, 2, /* mux */
400 BIT(31), /* gate */
401 0);
402
403static SUNXI_CCU_PHASE(mmc2_sample_clk, "mmc2_sample", "mmc2",
404 0x090, 20, 3, 0);
405static SUNXI_CCU_PHASE(mmc2_output_clk, "mmc2_output", "mmc2",
406 0x090, 8, 3, 0);
407
408static SUNXI_CCU_MP_WITH_MUX_GATE(mmc3_clk, "mmc3", mod0_default_parents,
409 0x094,
410 0, 4, /* M */
411 16, 2, /* P */
412 24, 2, /* mux */
413 BIT(31), /* gate */
414 0);
415
416static SUNXI_CCU_PHASE(mmc3_sample_clk, "mmc3_sample", "mmc3",
417 0x094, 20, 3, 0);
418static SUNXI_CCU_PHASE(mmc3_output_clk, "mmc3_output", "mmc3",
419 0x094, 8, 3, 0);
420
421static SUNXI_CCU_MP_WITH_MUX_GATE(ts_clk, "ts", mod0_default_parents, 0x098,
422 0, 4, /* M */
423 16, 2, /* P */
424 24, 2, /* mux */
425 BIT(31), /* gate */
426 0);
427
428static SUNXI_CCU_MP_WITH_MUX_GATE(ss_clk, "ss", mod0_default_parents, 0x09c,
429 0, 4, /* M */
430 16, 2, /* P */
431 24, 2, /* mux */
432 BIT(31), /* gate */
433 0);
434
435static SUNXI_CCU_MP_WITH_MUX_GATE(spi0_clk, "spi0", mod0_default_parents, 0x0a0,
436 0, 4, /* M */
437 16, 2, /* P */
438 24, 2, /* mux */
439 BIT(31), /* gate */
440 0);
441
442static SUNXI_CCU_MP_WITH_MUX_GATE(spi1_clk, "spi1", mod0_default_parents, 0x0a4,
443 0, 4, /* M */
444 16, 2, /* P */
445 24, 2, /* mux */
446 BIT(31), /* gate */
447 0);
448static SUNXI_CCU_MP_WITH_MUX_GATE(spi2_clk, "spi2", mod0_default_parents, 0x0a8,
449 0, 4, /* M */
450 16, 2, /* P */
451 24, 2, /* mux */
452 BIT(31), /* gate */
453 0);
454
455static SUNXI_CCU_MP_WITH_MUX_GATE(spi3_clk, "spi3", mod0_default_parents, 0x0ac,
456 0, 4, /* M */
457 16, 2, /* P */
458 24, 2, /* mux */
459 BIT(31), /* gate */
460 0);
461
462static const char * const daudio_parents[] = { "pll-audio-8x", "pll-audio-4x",
463 "pll-audio-2x", "pll-audio" };
464static SUNXI_CCU_MUX_WITH_GATE(daudio0_clk, "daudio0", daudio_parents,
465 0x0b0, 16, 2, BIT(31), CLK_SET_RATE_PARENT);
466static SUNXI_CCU_MUX_WITH_GATE(daudio1_clk, "daudio1", daudio_parents,
467 0x0b4, 16, 2, BIT(31), CLK_SET_RATE_PARENT);
468
469static SUNXI_CCU_M_WITH_GATE(spdif_clk, "spdif", "pll-audio",
470 0x0c0, 0, 4, BIT(31), CLK_SET_RATE_PARENT);
471
472static SUNXI_CCU_GATE(usb_phy0_clk, "usb-phy0", "osc24M",
473 0x0cc, BIT(8), 0);
474static SUNXI_CCU_GATE(usb_phy1_clk, "usb-phy1", "osc24M",
475 0x0cc, BIT(9), 0);
476static SUNXI_CCU_GATE(usb_phy2_clk, "usb-phy2", "osc24M",
477 0x0cc, BIT(10), 0);
478static SUNXI_CCU_GATE(usb_ohci0_clk, "usb-ohci0", "osc24M",
479 0x0cc, BIT(16), 0);
480static SUNXI_CCU_GATE(usb_ohci1_clk, "usb-ohci1", "osc24M",
481 0x0cc, BIT(17), 0);
482static SUNXI_CCU_GATE(usb_ohci2_clk, "usb-ohci2", "osc24M",
483 0x0cc, BIT(18), 0);
484
485/* TODO emac clk not supported yet */
486
487static const char * const dram_parents[] = { "pll-ddr", "pll-periph" };
488static SUNXI_CCU_MP_WITH_MUX_GATE(mdfs_clk, "mdfs", dram_parents, 0x0f0,
489 0, 4, /* M */
490 16, 2, /* P */
491 24, 2, /* mux */
492 BIT(31), /* gate */
493 CLK_IS_CRITICAL);
494
495static SUNXI_CCU_M_WITH_MUX(sdram0_clk, "sdram0", dram_parents,
496 0x0f4, 0, 4, 4, 1, CLK_IS_CRITICAL);
497static SUNXI_CCU_M_WITH_MUX(sdram1_clk, "sdram1", dram_parents,
498 0x0f4, 8, 4, 12, 1, CLK_IS_CRITICAL);
499
500static SUNXI_CCU_GATE(dram_ve_clk, "dram-ve", "mdfs",
501 0x100, BIT(0), 0);
502static SUNXI_CCU_GATE(dram_csi_isp_clk, "dram-csi-isp", "mdfs",
503 0x100, BIT(1), 0);
504static SUNXI_CCU_GATE(dram_ts_clk, "dram-ts", "mdfs",
505 0x100, BIT(3), 0);
506static SUNXI_CCU_GATE(dram_drc0_clk, "dram-drc0", "mdfs",
507 0x100, BIT(16), 0);
508static SUNXI_CCU_GATE(dram_drc1_clk, "dram-drc1", "mdfs",
509 0x100, BIT(17), 0);
510static SUNXI_CCU_GATE(dram_deu0_clk, "dram-deu0", "mdfs",
511 0x100, BIT(18), 0);
512static SUNXI_CCU_GATE(dram_deu1_clk, "dram-deu1", "mdfs",
513 0x100, BIT(19), 0);
514static SUNXI_CCU_GATE(dram_fe0_clk, "dram-fe0", "mdfs",
515 0x100, BIT(24), 0);
516static SUNXI_CCU_GATE(dram_fe1_clk, "dram-fe1", "mdfs",
517 0x100, BIT(25), 0);
518static SUNXI_CCU_GATE(dram_be0_clk, "dram-be0", "mdfs",
519 0x100, BIT(26), 0);
520static SUNXI_CCU_GATE(dram_be1_clk, "dram-be1", "mdfs",
521 0x100, BIT(27), 0);
522static SUNXI_CCU_GATE(dram_mp_clk, "dram-mp", "mdfs",
523 0x100, BIT(28), 0);
524
525static const char * const de_parents[] = { "pll-video0", "pll-video1",
526 "pll-periph-2x", "pll-gpu",
527 "pll9", "pll10" };
528static SUNXI_CCU_M_WITH_MUX_GATE(be0_clk, "be0", de_parents,
529 0x104, 0, 4, 24, 3, BIT(31), 0);
530static SUNXI_CCU_M_WITH_MUX_GATE(be1_clk, "be1", de_parents,
531 0x108, 0, 4, 24, 3, BIT(31), 0);
532static SUNXI_CCU_M_WITH_MUX_GATE(fe0_clk, "fe0", de_parents,
533 0x10c, 0, 4, 24, 3, BIT(31), 0);
534static SUNXI_CCU_M_WITH_MUX_GATE(fe1_clk, "fe1", de_parents,
535 0x110, 0, 4, 24, 3, BIT(31), 0);
536
537static const char * const mp_parents[] = { "pll-video0", "pll-video1",
538 "pll9", "pll10" };
539static SUNXI_CCU_M_WITH_MUX_GATE(mp_clk, "mp", mp_parents,
540 0x114, 0, 4, 24, 3, BIT(31), 0);
541
542static const char * const lcd_ch0_parents[] = { "pll-video0", "pll-video1",
543 "pll-video0-2x",
544 "pll-video1-2x", "pll-mipi" };
545static SUNXI_CCU_MUX_WITH_GATE(lcd0_ch0_clk, "lcd0-ch0", lcd_ch0_parents,
546 0x118, 24, 2, BIT(31), 0);
547static SUNXI_CCU_MUX_WITH_GATE(lcd1_ch0_clk, "lcd1-ch0", lcd_ch0_parents,
548 0x11c, 24, 2, BIT(31), 0);
549
550static const char * const lcd_ch1_parents[] = { "pll-video0", "pll-video1",
551 "pll-video0-2x",
552 "pll-video1-2x" };
553static SUNXI_CCU_M_WITH_MUX_GATE(lcd0_ch1_clk, "lcd0-ch1", lcd_ch1_parents,
554 0x12c, 0, 4, 24, 3, BIT(31), 0);
555static SUNXI_CCU_M_WITH_MUX_GATE(lcd1_ch1_clk, "lcd1-ch1", lcd_ch1_parents,
556 0x12c, 0, 4, 24, 3, BIT(31), 0);
557
558static const char * const csi_sclk_parents[] = { "pll-video0", "pll-video1",
559 "pll9", "pll10", "pll-mipi",
560 "pll-ve" };
561static SUNXI_CCU_M_WITH_MUX_GATE(csi0_sclk_clk, "csi0-sclk", csi_sclk_parents,
562 0x134, 16, 4, 24, 3, BIT(31), 0);
563
564static const char * const csi_mclk_parents[] = { "pll-video0", "pll-video1",
565 "osc24M" };
566static const u8 csi_mclk_table[] = { 0, 1, 5 };
567static struct ccu_div csi0_mclk_clk = {
568 .enable = BIT(15),
569 .div = _SUNXI_CCU_DIV(0, 4),
570 .mux = _SUNXI_CCU_MUX_TABLE(8, 3, csi_mclk_table),
571 .common = {
572 .reg = 0x134,
573 .hw.init = CLK_HW_INIT_PARENTS("csi0-mclk",
574 csi_mclk_parents,
575 &ccu_div_ops,
576 0),
577 },
578};
579
580static struct ccu_div csi1_mclk_clk = {
581 .enable = BIT(15),
582 .div = _SUNXI_CCU_DIV(0, 4),
583 .mux = _SUNXI_CCU_MUX_TABLE(8, 3, csi_mclk_table),
584 .common = {
585 .reg = 0x138,
586 .hw.init = CLK_HW_INIT_PARENTS("csi1-mclk",
587 csi_mclk_parents,
588 &ccu_div_ops,
589 0),
590 },
591};
592
593static SUNXI_CCU_M_WITH_GATE(ve_clk, "ve", "pll-ve",
594 0x13c, 16, 3, BIT(31), 0);
595
596static SUNXI_CCU_GATE(codec_clk, "codec", "pll-audio",
597 0x140, BIT(31), CLK_SET_RATE_PARENT);
598static SUNXI_CCU_GATE(avs_clk, "avs", "osc24M",
599 0x144, BIT(31), 0);
600static SUNXI_CCU_GATE(digital_mic_clk, "digital-mic", "pll-audio",
601 0x148, BIT(31), CLK_SET_RATE_PARENT);
602
603static SUNXI_CCU_M_WITH_MUX_GATE(hdmi_clk, "hdmi", lcd_ch1_parents,
604 0x150, 0, 4, 24, 2, BIT(31), 0);
605
606static SUNXI_CCU_GATE(hdmi_ddc_clk, "hdmi-ddc", "osc24M", 0x150, BIT(31), 0);
607
608static SUNXI_CCU_GATE(ps_clk, "ps", "lcd1-ch1", 0x140, BIT(31), 0);
609
610static const char * const mbus_parents[] = { "osc24M", "pll-periph",
611 "pll-ddr" };
612static SUNXI_CCU_MP_WITH_MUX_GATE(mbus0_clk, "mbus0", mbus_parents, 0x15c,
613 0, 3, /* M */
614 16, 2, /* P */
615 24, 2, /* mux */
616 BIT(31), /* gate */
617 CLK_IS_CRITICAL);
618
619static SUNXI_CCU_MP_WITH_MUX_GATE(mbus1_clk, "mbus1", mbus_parents, 0x160,
620 0, 3, /* M */
621 16, 2, /* P */
622 24, 2, /* mux */
623 BIT(31), /* gate */
624 CLK_IS_CRITICAL);
625
626static SUNXI_CCU_M_WITH_MUX_GATE(mipi_dsi_clk, "mipi-dsi", lcd_ch1_parents,
627 0x168, 16, 3, 24, 2, BIT(31), 0);
628static SUNXI_CCU_M_WITH_MUX_GATE(mipi_dsi_dphy_clk, "mipi-dsi-dphy",
629 lcd_ch1_parents, 0x168, 0, 3, 8, 2,
630 BIT(15), 0);
631static SUNXI_CCU_M_WITH_MUX_GATE(mipi_csi_dphy_clk, "mipi-csi-dphy",
632 lcd_ch1_parents, 0x168, 0, 3, 8, 2,
633 BIT(15), 0);
634
635static SUNXI_CCU_M_WITH_MUX_GATE(iep_drc0_clk, "iep-drc0", de_parents,
636 0x180, 0, 3, 24, 2, BIT(31), 0);
637static SUNXI_CCU_M_WITH_MUX_GATE(iep_drc1_clk, "iep-drc1", de_parents,
638 0x184, 0, 3, 24, 2, BIT(31), 0);
639static SUNXI_CCU_M_WITH_MUX_GATE(iep_deu0_clk, "iep-deu0", de_parents,
640 0x188, 0, 3, 24, 2, BIT(31), 0);
641static SUNXI_CCU_M_WITH_MUX_GATE(iep_deu1_clk, "iep-deu1", de_parents,
642 0x18c, 0, 3, 24, 2, BIT(31), 0);
643
644static const char * const gpu_parents[] = { "pll-gpu", "pll-periph-2x",
645 "pll-video0", "pll-video1",
646 "pll9", "pll10" };
647static const struct ccu_mux_fixed_prediv gpu_predivs[] = {
648 { .index = 1, .div = 3, },
649};
650
651static struct ccu_div gpu_core_clk = {
652 .enable = BIT(31),
653 .div = _SUNXI_CCU_DIV(0, 3),
654 .mux = {
655 .shift = 24,
656 .width = 3,
657 .fixed_predivs = gpu_predivs,
658 .n_predivs = ARRAY_SIZE(gpu_predivs),
659 },
660 .common = {
661 .reg = 0x1a0,
662 .features = CCU_FEATURE_FIXED_PREDIV,
663 .hw.init = CLK_HW_INIT_PARENTS("gpu-core",
664 gpu_parents,
665 &ccu_div_ops,
666 0),
667 },
668};
669
670static struct ccu_div gpu_memory_clk = {
671 .enable = BIT(31),
672 .div = _SUNXI_CCU_DIV(0, 3),
673 .mux = {
674 .shift = 24,
675 .width = 3,
676 .fixed_predivs = gpu_predivs,
677 .n_predivs = ARRAY_SIZE(gpu_predivs),
678 },
679 .common = {
680 .reg = 0x1a4,
681 .features = CCU_FEATURE_FIXED_PREDIV,
682 .hw.init = CLK_HW_INIT_PARENTS("gpu-memory",
683 gpu_parents,
684 &ccu_div_ops,
685 0),
686 },
687};
688
689static struct ccu_div gpu_hyd_clk = {
690 .enable = BIT(31),
691 .div = _SUNXI_CCU_DIV(0, 3),
692 .mux = {
693 .shift = 24,
694 .width = 3,
695 .fixed_predivs = gpu_predivs,
696 .n_predivs = ARRAY_SIZE(gpu_predivs),
697 },
698 .common = {
699 .reg = 0x1a8,
700 .features = CCU_FEATURE_FIXED_PREDIV,
701 .hw.init = CLK_HW_INIT_PARENTS("gpu-hyd",
702 gpu_parents,
703 &ccu_div_ops,
704 0),
705 },
706};
707
708static SUNXI_CCU_M_WITH_MUX_GATE(ats_clk, "ats", mod0_default_parents, 0x1b0,
709 0, 3, /* M */
710 24, 2, /* mux */
711 BIT(31), /* gate */
712 0);
713
714static SUNXI_CCU_M_WITH_MUX_GATE(trace_clk, "trace", mod0_default_parents,
715 0x1b0,
716 0, 3, /* M */
717 24, 2, /* mux */
718 BIT(31), /* gate */
719 0);
720
721static const char * const clk_out_parents[] = { "osc24M", "osc32k", "osc24M",
722 "axi", "ahb1" };
723static const u8 clk_out_table[] = { 0, 1, 2, 11, 13 };
724
725static const struct ccu_mux_fixed_prediv clk_out_predivs[] = {
726 { .index = 0, .div = 750, },
727 { .index = 3, .div = 4, },
728 { .index = 4, .div = 4, },
729};
730
731static struct ccu_mp out_a_clk = {
732 .enable = BIT(31),
733 .m = _SUNXI_CCU_DIV(8, 5),
734 .p = _SUNXI_CCU_DIV(20, 2),
735 .mux = {
736 .shift = 24,
737 .width = 4,
738 .table = clk_out_table,
739 .fixed_predivs = clk_out_predivs,
740 .n_predivs = ARRAY_SIZE(clk_out_predivs),
741 },
742 .common = {
743 .reg = 0x300,
744 .features = CCU_FEATURE_FIXED_PREDIV,
745 .hw.init = CLK_HW_INIT_PARENTS("out-a",
746 clk_out_parents,
747 &ccu_div_ops,
748 0),
749 },
750};
751
752static struct ccu_mp out_b_clk = {
753 .enable = BIT(31),
754 .m = _SUNXI_CCU_DIV(8, 5),
755 .p = _SUNXI_CCU_DIV(20, 2),
756 .mux = {
757 .shift = 24,
758 .width = 4,
759 .table = clk_out_table,
760 .fixed_predivs = clk_out_predivs,
761 .n_predivs = ARRAY_SIZE(clk_out_predivs),
762 },
763 .common = {
764 .reg = 0x304,
765 .features = CCU_FEATURE_FIXED_PREDIV,
766 .hw.init = CLK_HW_INIT_PARENTS("out-b",
767 clk_out_parents,
768 &ccu_div_ops,
769 0),
770 },
771};
772
773static struct ccu_mp out_c_clk = {
774 .enable = BIT(31),
775 .m = _SUNXI_CCU_DIV(8, 5),
776 .p = _SUNXI_CCU_DIV(20, 2),
777 .mux = {
778 .shift = 24,
779 .width = 4,
780 .table = clk_out_table,
781 .fixed_predivs = clk_out_predivs,
782 .n_predivs = ARRAY_SIZE(clk_out_predivs),
783 },
784 .common = {
785 .reg = 0x308,
786 .features = CCU_FEATURE_FIXED_PREDIV,
787 .hw.init = CLK_HW_INIT_PARENTS("out-c",
788 clk_out_parents,
789 &ccu_div_ops,
790 0),
791 },
792};
793
794static struct ccu_common *sun6i_a31_ccu_clks[] = {
795 &pll_cpu_clk.common,
796 &pll_audio_base_clk.common,
797 &pll_video0_clk.common,
798 &pll_ve_clk.common,
799 &pll_ddr_clk.common,
800 &pll_periph_clk.common,
801 &pll_video1_clk.common,
802 &pll_gpu_clk.common,
803 &pll_mipi_clk.common,
804 &pll9_clk.common,
805 &pll10_clk.common,
806 &cpu_clk.common,
807 &axi_clk.common,
808 &ahb1_clk.common,
809 &apb1_clk.common,
810 &apb2_clk.common,
811 &ahb1_mipidsi_clk.common,
812 &ahb1_ss_clk.common,
813 &ahb1_dma_clk.common,
814 &ahb1_mmc0_clk.common,
815 &ahb1_mmc1_clk.common,
816 &ahb1_mmc2_clk.common,
817 &ahb1_mmc3_clk.common,
818 &ahb1_nand1_clk.common,
819 &ahb1_nand0_clk.common,
820 &ahb1_sdram_clk.common,
821 &ahb1_emac_clk.common,
822 &ahb1_ts_clk.common,
823 &ahb1_hstimer_clk.common,
824 &ahb1_spi0_clk.common,
825 &ahb1_spi1_clk.common,
826 &ahb1_spi2_clk.common,
827 &ahb1_spi3_clk.common,
828 &ahb1_otg_clk.common,
829 &ahb1_ehci0_clk.common,
830 &ahb1_ehci1_clk.common,
831 &ahb1_ohci0_clk.common,
832 &ahb1_ohci1_clk.common,
833 &ahb1_ohci2_clk.common,
834 &ahb1_ve_clk.common,
835 &ahb1_lcd0_clk.common,
836 &ahb1_lcd1_clk.common,
837 &ahb1_csi_clk.common,
838 &ahb1_hdmi_clk.common,
839 &ahb1_be0_clk.common,
840 &ahb1_be1_clk.common,
841 &ahb1_fe0_clk.common,
842 &ahb1_fe1_clk.common,
843 &ahb1_mp_clk.common,
844 &ahb1_gpu_clk.common,
845 &ahb1_deu0_clk.common,
846 &ahb1_deu1_clk.common,
847 &ahb1_drc0_clk.common,
848 &ahb1_drc1_clk.common,
849 &apb1_codec_clk.common,
850 &apb1_spdif_clk.common,
851 &apb1_digital_mic_clk.common,
852 &apb1_pio_clk.common,
853 &apb1_daudio0_clk.common,
854 &apb1_daudio1_clk.common,
855 &apb2_i2c0_clk.common,
856 &apb2_i2c1_clk.common,
857 &apb2_i2c2_clk.common,
858 &apb2_i2c3_clk.common,
859 &apb2_uart0_clk.common,
860 &apb2_uart1_clk.common,
861 &apb2_uart2_clk.common,
862 &apb2_uart3_clk.common,
863 &apb2_uart4_clk.common,
864 &apb2_uart5_clk.common,
865 &nand0_clk.common,
866 &nand1_clk.common,
867 &mmc0_clk.common,
868 &mmc0_sample_clk.common,
869 &mmc0_output_clk.common,
870 &mmc1_clk.common,
871 &mmc1_sample_clk.common,
872 &mmc1_output_clk.common,
873 &mmc2_clk.common,
874 &mmc2_sample_clk.common,
875 &mmc2_output_clk.common,
876 &mmc3_clk.common,
877 &mmc3_sample_clk.common,
878 &mmc3_output_clk.common,
879 &ts_clk.common,
880 &ss_clk.common,
881 &spi0_clk.common,
882 &spi1_clk.common,
883 &spi2_clk.common,
884 &spi3_clk.common,
885 &daudio0_clk.common,
886 &daudio1_clk.common,
887 &spdif_clk.common,
888 &usb_phy0_clk.common,
889 &usb_phy1_clk.common,
890 &usb_phy2_clk.common,
891 &usb_ohci0_clk.common,
892 &usb_ohci1_clk.common,
893 &usb_ohci2_clk.common,
894 &mdfs_clk.common,
895 &sdram0_clk.common,
896 &sdram1_clk.common,
897 &dram_ve_clk.common,
898 &dram_csi_isp_clk.common,
899 &dram_ts_clk.common,
900 &dram_drc0_clk.common,
901 &dram_drc1_clk.common,
902 &dram_deu0_clk.common,
903 &dram_deu1_clk.common,
904 &dram_fe0_clk.common,
905 &dram_fe1_clk.common,
906 &dram_be0_clk.common,
907 &dram_be1_clk.common,
908 &dram_mp_clk.common,
909 &be0_clk.common,
910 &be1_clk.common,
911 &fe0_clk.common,
912 &fe1_clk.common,
913 &mp_clk.common,
914 &lcd0_ch0_clk.common,
915 &lcd1_ch0_clk.common,
916 &lcd0_ch1_clk.common,
917 &lcd1_ch1_clk.common,
918 &csi0_sclk_clk.common,
919 &csi0_mclk_clk.common,
920 &csi1_mclk_clk.common,
921 &ve_clk.common,
922 &codec_clk.common,
923 &avs_clk.common,
924 &digital_mic_clk.common,
925 &hdmi_clk.common,
926 &hdmi_ddc_clk.common,
927 &ps_clk.common,
928 &mbus0_clk.common,
929 &mbus1_clk.common,
930 &mipi_dsi_clk.common,
931 &mipi_dsi_dphy_clk.common,
932 &mipi_csi_dphy_clk.common,
933 &iep_drc0_clk.common,
934 &iep_drc1_clk.common,
935 &iep_deu0_clk.common,
936 &iep_deu1_clk.common,
937 &gpu_core_clk.common,
938 &gpu_memory_clk.common,
939 &gpu_hyd_clk.common,
940 &ats_clk.common,
941 &trace_clk.common,
942 &out_a_clk.common,
943 &out_b_clk.common,
944 &out_c_clk.common,
945};
946
947/* We hardcode the divider to 4 for now */
948static CLK_FIXED_FACTOR(pll_audio_clk, "pll-audio",
949 "pll-audio-base", 4, 1, CLK_SET_RATE_PARENT);
950static CLK_FIXED_FACTOR(pll_audio_2x_clk, "pll-audio-2x",
951 "pll-audio-base", 2, 1, CLK_SET_RATE_PARENT);
952static CLK_FIXED_FACTOR(pll_audio_4x_clk, "pll-audio-4x",
953 "pll-audio-base", 1, 1, CLK_SET_RATE_PARENT);
954static CLK_FIXED_FACTOR(pll_audio_8x_clk, "pll-audio-8x",
955 "pll-audio-base", 1, 2, CLK_SET_RATE_PARENT);
956static CLK_FIXED_FACTOR(pll_periph_2x_clk, "pll-periph-2x",
957 "pll-periph", 1, 2, 0);
958static CLK_FIXED_FACTOR(pll_video0_2x_clk, "pll-video0-2x",
959 "pll-video0", 1, 2, 0);
960static CLK_FIXED_FACTOR(pll_video1_2x_clk, "pll-video1-2x",
961 "pll-video1", 1, 2, 0);
962
963static struct clk_hw_onecell_data sun6i_a31_hw_clks = {
964 .hws = {
965 [CLK_PLL_CPU] = &pll_cpu_clk.common.hw,
966 [CLK_PLL_AUDIO_BASE] = &pll_audio_base_clk.common.hw,
967 [CLK_PLL_AUDIO] = &pll_audio_clk.hw,
968 [CLK_PLL_AUDIO_2X] = &pll_audio_2x_clk.hw,
969 [CLK_PLL_AUDIO_4X] = &pll_audio_4x_clk.hw,
970 [CLK_PLL_AUDIO_8X] = &pll_audio_8x_clk.hw,
971 [CLK_PLL_VIDEO0] = &pll_video0_clk.common.hw,
972 [CLK_PLL_VIDEO0_2X] = &pll_video0_2x_clk.hw,
973 [CLK_PLL_VE] = &pll_ve_clk.common.hw,
974 [CLK_PLL_DDR] = &pll_ddr_clk.common.hw,
975 [CLK_PLL_PERIPH] = &pll_periph_clk.common.hw,
976 [CLK_PLL_PERIPH_2X] = &pll_periph_2x_clk.hw,
977 [CLK_PLL_VIDEO1] = &pll_video1_clk.common.hw,
978 [CLK_PLL_VIDEO1_2X] = &pll_video1_2x_clk.hw,
979 [CLK_PLL_GPU] = &pll_gpu_clk.common.hw,
980 [CLK_PLL_MIPI] = &pll_mipi_clk.common.hw,
981 [CLK_PLL9] = &pll9_clk.common.hw,
982 [CLK_PLL10] = &pll10_clk.common.hw,
983 [CLK_CPU] = &cpu_clk.common.hw,
984 [CLK_AXI] = &axi_clk.common.hw,
985 [CLK_AHB1] = &ahb1_clk.common.hw,
986 [CLK_APB1] = &apb1_clk.common.hw,
987 [CLK_APB2] = &apb2_clk.common.hw,
988 [CLK_AHB1_MIPIDSI] = &ahb1_mipidsi_clk.common.hw,
989 [CLK_AHB1_SS] = &ahb1_ss_clk.common.hw,
990 [CLK_AHB1_DMA] = &ahb1_dma_clk.common.hw,
991 [CLK_AHB1_MMC0] = &ahb1_mmc0_clk.common.hw,
992 [CLK_AHB1_MMC1] = &ahb1_mmc1_clk.common.hw,
993 [CLK_AHB1_MMC2] = &ahb1_mmc2_clk.common.hw,
994 [CLK_AHB1_MMC3] = &ahb1_mmc3_clk.common.hw,
995 [CLK_AHB1_NAND1] = &ahb1_nand1_clk.common.hw,
996 [CLK_AHB1_NAND0] = &ahb1_nand0_clk.common.hw,
997 [CLK_AHB1_SDRAM] = &ahb1_sdram_clk.common.hw,
998 [CLK_AHB1_EMAC] = &ahb1_emac_clk.common.hw,
999 [CLK_AHB1_TS] = &ahb1_ts_clk.common.hw,
1000 [CLK_AHB1_HSTIMER] = &ahb1_hstimer_clk.common.hw,
1001 [CLK_AHB1_SPI0] = &ahb1_spi0_clk.common.hw,
1002 [CLK_AHB1_SPI1] = &ahb1_spi1_clk.common.hw,
1003 [CLK_AHB1_SPI2] = &ahb1_spi2_clk.common.hw,
1004 [CLK_AHB1_SPI3] = &ahb1_spi3_clk.common.hw,
1005 [CLK_AHB1_OTG] = &ahb1_otg_clk.common.hw,
1006 [CLK_AHB1_EHCI0] = &ahb1_ehci0_clk.common.hw,
1007 [CLK_AHB1_EHCI1] = &ahb1_ehci1_clk.common.hw,
1008 [CLK_AHB1_OHCI0] = &ahb1_ohci0_clk.common.hw,
1009 [CLK_AHB1_OHCI1] = &ahb1_ohci1_clk.common.hw,
1010 [CLK_AHB1_OHCI2] = &ahb1_ohci2_clk.common.hw,
1011 [CLK_AHB1_VE] = &ahb1_ve_clk.common.hw,
1012 [CLK_AHB1_LCD0] = &ahb1_lcd0_clk.common.hw,
1013 [CLK_AHB1_LCD1] = &ahb1_lcd1_clk.common.hw,
1014 [CLK_AHB1_CSI] = &ahb1_csi_clk.common.hw,
1015 [CLK_AHB1_HDMI] = &ahb1_hdmi_clk.common.hw,
1016 [CLK_AHB1_BE0] = &ahb1_be0_clk.common.hw,
1017 [CLK_AHB1_BE1] = &ahb1_be1_clk.common.hw,
1018 [CLK_AHB1_FE0] = &ahb1_fe0_clk.common.hw,
1019 [CLK_AHB1_FE1] = &ahb1_fe1_clk.common.hw,
1020 [CLK_AHB1_MP] = &ahb1_mp_clk.common.hw,
1021 [CLK_AHB1_GPU] = &ahb1_gpu_clk.common.hw,
1022 [CLK_AHB1_DEU0] = &ahb1_deu0_clk.common.hw,
1023 [CLK_AHB1_DEU1] = &ahb1_deu1_clk.common.hw,
1024 [CLK_AHB1_DRC0] = &ahb1_drc0_clk.common.hw,
1025 [CLK_AHB1_DRC1] = &ahb1_drc1_clk.common.hw,
1026 [CLK_APB1_CODEC] = &apb1_codec_clk.common.hw,
1027 [CLK_APB1_SPDIF] = &apb1_spdif_clk.common.hw,
1028 [CLK_APB1_DIGITAL_MIC] = &apb1_digital_mic_clk.common.hw,
1029 [CLK_APB1_PIO] = &apb1_pio_clk.common.hw,
1030 [CLK_APB1_DAUDIO0] = &apb1_daudio0_clk.common.hw,
1031 [CLK_APB1_DAUDIO1] = &apb1_daudio1_clk.common.hw,
1032 [CLK_APB2_I2C0] = &apb2_i2c0_clk.common.hw,
1033 [CLK_APB2_I2C1] = &apb2_i2c1_clk.common.hw,
1034 [CLK_APB2_I2C2] = &apb2_i2c2_clk.common.hw,
1035 [CLK_APB2_I2C3] = &apb2_i2c3_clk.common.hw,
1036 [CLK_APB2_UART0] = &apb2_uart0_clk.common.hw,
1037 [CLK_APB2_UART1] = &apb2_uart1_clk.common.hw,
1038 [CLK_APB2_UART2] = &apb2_uart2_clk.common.hw,
1039 [CLK_APB2_UART3] = &apb2_uart3_clk.common.hw,
1040 [CLK_APB2_UART4] = &apb2_uart4_clk.common.hw,
1041 [CLK_APB2_UART5] = &apb2_uart5_clk.common.hw,
1042 [CLK_NAND0] = &nand0_clk.common.hw,
1043 [CLK_NAND1] = &nand1_clk.common.hw,
1044 [CLK_MMC0] = &mmc0_clk.common.hw,
1045 [CLK_MMC0_SAMPLE] = &mmc0_sample_clk.common.hw,
1046 [CLK_MMC0_OUTPUT] = &mmc0_output_clk.common.hw,
1047 [CLK_MMC1] = &mmc1_clk.common.hw,
1048 [CLK_MMC1_SAMPLE] = &mmc1_sample_clk.common.hw,
1049 [CLK_MMC1_OUTPUT] = &mmc1_output_clk.common.hw,
1050 [CLK_MMC2] = &mmc2_clk.common.hw,
1051 [CLK_MMC2_SAMPLE] = &mmc2_sample_clk.common.hw,
1052 [CLK_MMC2_OUTPUT] = &mmc2_output_clk.common.hw,
1053 [CLK_MMC3] = &mmc3_clk.common.hw,
1054 [CLK_MMC3_SAMPLE] = &mmc3_sample_clk.common.hw,
1055 [CLK_MMC3_OUTPUT] = &mmc3_output_clk.common.hw,
1056 [CLK_TS] = &ts_clk.common.hw,
1057 [CLK_SS] = &ss_clk.common.hw,
1058 [CLK_SPI0] = &spi0_clk.common.hw,
1059 [CLK_SPI1] = &spi1_clk.common.hw,
1060 [CLK_SPI2] = &spi2_clk.common.hw,
1061 [CLK_SPI3] = &spi3_clk.common.hw,
1062 [CLK_DAUDIO0] = &daudio0_clk.common.hw,
1063 [CLK_DAUDIO1] = &daudio1_clk.common.hw,
1064 [CLK_SPDIF] = &spdif_clk.common.hw,
1065 [CLK_USB_PHY0] = &usb_phy0_clk.common.hw,
1066 [CLK_USB_PHY1] = &usb_phy1_clk.common.hw,
1067 [CLK_USB_PHY2] = &usb_phy2_clk.common.hw,
1068 [CLK_USB_OHCI0] = &usb_ohci0_clk.common.hw,
1069 [CLK_USB_OHCI1] = &usb_ohci1_clk.common.hw,
1070 [CLK_USB_OHCI2] = &usb_ohci2_clk.common.hw,
1071 [CLK_MDFS] = &mdfs_clk.common.hw,
1072 [CLK_SDRAM0] = &sdram0_clk.common.hw,
1073 [CLK_SDRAM1] = &sdram1_clk.common.hw,
1074 [CLK_DRAM_VE] = &dram_ve_clk.common.hw,
1075 [CLK_DRAM_CSI_ISP] = &dram_csi_isp_clk.common.hw,
1076 [CLK_DRAM_TS] = &dram_ts_clk.common.hw,
1077 [CLK_DRAM_DRC0] = &dram_drc0_clk.common.hw,
1078 [CLK_DRAM_DRC1] = &dram_drc1_clk.common.hw,
1079 [CLK_DRAM_DEU0] = &dram_deu0_clk.common.hw,
1080 [CLK_DRAM_DEU1] = &dram_deu1_clk.common.hw,
1081 [CLK_DRAM_FE0] = &dram_fe0_clk.common.hw,
1082 [CLK_DRAM_FE1] = &dram_fe1_clk.common.hw,
1083 [CLK_DRAM_BE0] = &dram_be0_clk.common.hw,
1084 [CLK_DRAM_BE1] = &dram_be1_clk.common.hw,
1085 [CLK_DRAM_MP] = &dram_mp_clk.common.hw,
1086 [CLK_BE0] = &be0_clk.common.hw,
1087 [CLK_BE1] = &be1_clk.common.hw,
1088 [CLK_FE0] = &fe0_clk.common.hw,
1089 [CLK_FE1] = &fe1_clk.common.hw,
1090 [CLK_MP] = &mp_clk.common.hw,
1091 [CLK_LCD0_CH0] = &lcd0_ch0_clk.common.hw,
1092 [CLK_LCD1_CH0] = &lcd1_ch0_clk.common.hw,
1093 [CLK_LCD0_CH1] = &lcd0_ch1_clk.common.hw,
1094 [CLK_LCD1_CH1] = &lcd1_ch1_clk.common.hw,
1095 [CLK_CSI0_SCLK] = &csi0_sclk_clk.common.hw,
1096 [CLK_CSI0_MCLK] = &csi0_mclk_clk.common.hw,
1097 [CLK_CSI1_MCLK] = &csi1_mclk_clk.common.hw,
1098 [CLK_VE] = &ve_clk.common.hw,
1099 [CLK_CODEC] = &codec_clk.common.hw,
1100 [CLK_AVS] = &avs_clk.common.hw,
1101 [CLK_DIGITAL_MIC] = &digital_mic_clk.common.hw,
1102 [CLK_HDMI] = &hdmi_clk.common.hw,
1103 [CLK_HDMI_DDC] = &hdmi_ddc_clk.common.hw,
1104 [CLK_PS] = &ps_clk.common.hw,
1105 [CLK_MBUS0] = &mbus0_clk.common.hw,
1106 [CLK_MBUS1] = &mbus1_clk.common.hw,
1107 [CLK_MIPI_DSI] = &mipi_dsi_clk.common.hw,
1108 [CLK_MIPI_DSI_DPHY] = &mipi_dsi_dphy_clk.common.hw,
1109 [CLK_MIPI_CSI_DPHY] = &mipi_csi_dphy_clk.common.hw,
1110 [CLK_IEP_DRC0] = &iep_drc0_clk.common.hw,
1111 [CLK_IEP_DRC1] = &iep_drc1_clk.common.hw,
1112 [CLK_IEP_DEU0] = &iep_deu0_clk.common.hw,
1113 [CLK_IEP_DEU1] = &iep_deu1_clk.common.hw,
1114 [CLK_GPU_CORE] = &gpu_core_clk.common.hw,
1115 [CLK_GPU_MEMORY] = &gpu_memory_clk.common.hw,
1116 [CLK_GPU_HYD] = &gpu_hyd_clk.common.hw,
1117 [CLK_ATS] = &ats_clk.common.hw,
1118 [CLK_TRACE] = &trace_clk.common.hw,
1119 [CLK_OUT_A] = &out_a_clk.common.hw,
1120 [CLK_OUT_B] = &out_b_clk.common.hw,
1121 [CLK_OUT_C] = &out_c_clk.common.hw,
1122 },
1123 .num = CLK_NUMBER,
1124};
1125
1126static struct ccu_reset_map sun6i_a31_ccu_resets[] = {
1127 [RST_USB_PHY0] = { 0x0cc, BIT(0) },
1128 [RST_USB_PHY1] = { 0x0cc, BIT(1) },
1129 [RST_USB_PHY2] = { 0x0cc, BIT(2) },
1130
1131 [RST_AHB1_MIPI_DSI] = { 0x2c0, BIT(1) },
1132 [RST_AHB1_SS] = { 0x2c0, BIT(5) },
1133 [RST_AHB1_DMA] = { 0x2c0, BIT(6) },
1134 [RST_AHB1_MMC0] = { 0x2c0, BIT(8) },
1135 [RST_AHB1_MMC1] = { 0x2c0, BIT(9) },
1136 [RST_AHB1_MMC2] = { 0x2c0, BIT(10) },
1137 [RST_AHB1_MMC3] = { 0x2c0, BIT(11) },
1138 [RST_AHB1_NAND1] = { 0x2c0, BIT(12) },
1139 [RST_AHB1_NAND0] = { 0x2c0, BIT(13) },
1140 [RST_AHB1_SDRAM] = { 0x2c0, BIT(14) },
1141 [RST_AHB1_EMAC] = { 0x2c0, BIT(17) },
1142 [RST_AHB1_TS] = { 0x2c0, BIT(18) },
1143 [RST_AHB1_HSTIMER] = { 0x2c0, BIT(19) },
1144 [RST_AHB1_SPI0] = { 0x2c0, BIT(20) },
1145 [RST_AHB1_SPI1] = { 0x2c0, BIT(21) },
1146 [RST_AHB1_SPI2] = { 0x2c0, BIT(22) },
1147 [RST_AHB1_SPI3] = { 0x2c0, BIT(23) },
1148 [RST_AHB1_OTG] = { 0x2c0, BIT(24) },
1149 [RST_AHB1_EHCI0] = { 0x2c0, BIT(26) },
1150 [RST_AHB1_EHCI1] = { 0x2c0, BIT(27) },
1151 [RST_AHB1_OHCI0] = { 0x2c0, BIT(29) },
1152 [RST_AHB1_OHCI1] = { 0x2c0, BIT(30) },
1153 [RST_AHB1_OHCI2] = { 0x2c0, BIT(31) },
1154
1155 [RST_AHB1_VE] = { 0x2c4, BIT(0) },
1156 [RST_AHB1_LCD0] = { 0x2c4, BIT(4) },
1157 [RST_AHB1_LCD1] = { 0x2c4, BIT(5) },
1158 [RST_AHB1_CSI] = { 0x2c4, BIT(8) },
1159 [RST_AHB1_HDMI] = { 0x2c4, BIT(11) },
1160 [RST_AHB1_BE0] = { 0x2c4, BIT(12) },
1161 [RST_AHB1_BE1] = { 0x2c4, BIT(13) },
1162 [RST_AHB1_FE0] = { 0x2c4, BIT(14) },
1163 [RST_AHB1_FE1] = { 0x2c4, BIT(15) },
1164 [RST_AHB1_MP] = { 0x2c4, BIT(18) },
1165 [RST_AHB1_GPU] = { 0x2c4, BIT(20) },
1166 [RST_AHB1_DEU0] = { 0x2c4, BIT(23) },
1167 [RST_AHB1_DEU1] = { 0x2c4, BIT(24) },
1168 [RST_AHB1_DRC0] = { 0x2c4, BIT(25) },
1169 [RST_AHB1_DRC1] = { 0x2c4, BIT(26) },
1170 [RST_AHB1_LVDS] = { 0x2c8, BIT(0) },
1171
1172 [RST_APB1_CODEC] = { 0x2d0, BIT(0) },
1173 [RST_APB1_SPDIF] = { 0x2d0, BIT(1) },
1174 [RST_APB1_DIGITAL_MIC] = { 0x2d0, BIT(4) },
1175 [RST_APB1_DAUDIO0] = { 0x2d0, BIT(12) },
1176 [RST_APB1_DAUDIO1] = { 0x2d0, BIT(13) },
1177
1178 [RST_APB2_I2C0] = { 0x2d8, BIT(0) },
1179 [RST_APB2_I2C1] = { 0x2d8, BIT(1) },
1180 [RST_APB2_I2C2] = { 0x2d8, BIT(2) },
1181 [RST_APB2_I2C3] = { 0x2d8, BIT(3) },
1182 [RST_APB2_UART0] = { 0x2d8, BIT(16) },
1183 [RST_APB2_UART1] = { 0x2d8, BIT(17) },
1184 [RST_APB2_UART2] = { 0x2d8, BIT(18) },
1185 [RST_APB2_UART3] = { 0x2d8, BIT(19) },
1186 [RST_APB2_UART4] = { 0x2d8, BIT(20) },
1187 [RST_APB2_UART5] = { 0x2d8, BIT(21) },
1188};
1189
1190static const struct sunxi_ccu_desc sun6i_a31_ccu_desc = {
1191 .ccu_clks = sun6i_a31_ccu_clks,
1192 .num_ccu_clks = ARRAY_SIZE(sun6i_a31_ccu_clks),
1193
1194 .hw_clks = &sun6i_a31_hw_clks,
1195
1196 .resets = sun6i_a31_ccu_resets,
1197 .num_resets = ARRAY_SIZE(sun6i_a31_ccu_resets),
1198};
1199
1200static struct ccu_mux_nb sun6i_a31_cpu_nb = {
1201 .common = &cpu_clk.common,
1202 .cm = &cpu_clk.mux,
1203 .delay_us = 1, /* > 8 clock cycles at 24 MHz */
1204 .bypass_index = 1, /* index of 24 MHz oscillator */
1205};
1206
1207static void __init sun6i_a31_ccu_setup(struct device_node *node)
1208{
1209 void __iomem *reg;
1210 u32 val;
1211
1212 reg = of_io_request_and_map(node, 0, of_node_full_name(node));
1213 if (IS_ERR(reg)) {
1214 pr_err("%s: Could not map the clock registers\n",
1215 of_node_full_name(node));
1216 return;
1217 }
1218
1219 /* Force the PLL-Audio-1x divider to 4 */
1220 val = readl(reg + SUN6I_A31_PLL_AUDIO_REG);
1221 val &= ~GENMASK(19, 16);
1222 writel(val | (3 << 16), reg + SUN6I_A31_PLL_AUDIO_REG);
1223
1224 /* Force PLL-MIPI to MIPI mode */
1225 val = readl(reg + SUN6I_A31_PLL_MIPI_REG);
1226 val &= BIT(16);
1227 writel(val, reg + SUN6I_A31_PLL_MIPI_REG);
1228
1229 sunxi_ccu_probe(node, reg, &sun6i_a31_ccu_desc);
1230
1231 ccu_mux_notifier_register(pll_cpu_clk.common.hw.clk,
1232 &sun6i_a31_cpu_nb);
1233}
1234CLK_OF_DECLARE(sun6i_a31_ccu, "allwinner,sun6i-a31-ccu",
1235 sun6i_a31_ccu_setup);
diff --git a/drivers/clk/sunxi-ng/ccu-sun6i-a31.h b/drivers/clk/sunxi-ng/ccu-sun6i-a31.h
new file mode 100644
index 000000000000..4e434011e9e7
--- /dev/null
+++ b/drivers/clk/sunxi-ng/ccu-sun6i-a31.h
@@ -0,0 +1,72 @@
1/*
2 * Copyright 2016 Chen-Yu Tsai
3 *
4 * Chen-Yu Tsai <wens@csie.org>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 */
16
17#ifndef _CCU_SUN6I_A31_H_
18#define _CCU_SUN6I_A31_H_
19
20#include <dt-bindings/clock/sun6i-a31-ccu.h>
21#include <dt-bindings/reset/sun6i-a31-ccu.h>
22
23#define CLK_PLL_CPU 0
24#define CLK_PLL_AUDIO_BASE 1
25#define CLK_PLL_AUDIO 2
26#define CLK_PLL_AUDIO_2X 3
27#define CLK_PLL_AUDIO_4X 4
28#define CLK_PLL_AUDIO_8X 5
29#define CLK_PLL_VIDEO0 6
30#define CLK_PLL_VIDEO0_2X 7
31#define CLK_PLL_VE 8
32#define CLK_PLL_DDR 9
33
34/* The PLL_PERIPH clock is exported */
35
36#define CLK_PLL_PERIPH_2X 11
37#define CLK_PLL_VIDEO1 12
38#define CLK_PLL_VIDEO1_2X 13
39#define CLK_PLL_GPU 14
40#define CLK_PLL_MIPI 15
41#define CLK_PLL9 16
42#define CLK_PLL10 17
43
44/* The CPUX clock is exported */
45
46#define CLK_AXI 19
47#define CLK_AHB1 20
48#define CLK_APB1 21
49#define CLK_APB2 22
50
51/* All the bus gates are exported */
52
53/* The first bunch of module clocks are exported */
54
55/* EMAC clock is not implemented */
56
57#define CLK_MDFS 107
58#define CLK_SDRAM0 108
59#define CLK_SDRAM1 109
60
61/* All the DRAM gates are exported */
62
63/* Some more module clocks are exported */
64
65#define CLK_MBUS0 141
66#define CLK_MBUS1 142
67
68/* Some more module clocks and external clock outputs are exported */
69
70#define CLK_NUMBER (CLK_OUT_C + 1)
71
72#endif /* _CCU_SUN6I_A31_H_ */
diff --git a/drivers/clk/sunxi-ng/ccu-sun8i-a23-a33.h b/drivers/clk/sunxi-ng/ccu-sun8i-a23-a33.h
new file mode 100644
index 000000000000..62c0f8d49ef8
--- /dev/null
+++ b/drivers/clk/sunxi-ng/ccu-sun8i-a23-a33.h
@@ -0,0 +1,63 @@
1/*
2 * Copyright 2016 Maxime Ripard
3 *
4 * Maxime Ripard <maxime.ripard@free-electrons.com>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 */
16
17#ifndef _CCU_SUN8I_A23_A33_H_
18#define _CCU_SUN8I_A23_A33_H_
19
20#include <dt-bindings/clock/sun8i-a23-a33-ccu.h>
21#include <dt-bindings/reset/sun8i-a23-a33-ccu.h>
22
23#define CLK_PLL_CPUX 0
24#define CLK_PLL_AUDIO_BASE 1
25#define CLK_PLL_AUDIO 2
26#define CLK_PLL_AUDIO_2X 3
27#define CLK_PLL_AUDIO_4X 4
28#define CLK_PLL_AUDIO_8X 5
29#define CLK_PLL_VIDEO 6
30#define CLK_PLL_VIDEO_2X 7
31#define CLK_PLL_VE 8
32#define CLK_PLL_DDR0 9
33#define CLK_PLL_PERIPH 10
34#define CLK_PLL_PERIPH_2X 11
35#define CLK_PLL_GPU 12
36#define CLK_PLL_MIPI 13
37#define CLK_PLL_HSIC 14
38#define CLK_PLL_DE 15
39#define CLK_PLL_DDR1 16
40#define CLK_PLL_DDR 17
41
42/* The CPUX clock is exported */
43
44#define CLK_AXI 19
45#define CLK_AHB1 20
46#define CLK_APB1 21
47#define CLK_APB2 22
48
49/* All the bus gates are exported */
50
51/* The first part of the mod clocks is exported */
52
53#define CLK_DRAM 79
54
55/* Some more module clocks are exported */
56
57#define CLK_MBUS 95
58
59/* And the last module clocks are exported */
60
61#define CLK_NUMBER (CLK_ATS + 1)
62
63#endif /* _CCU_SUN8I_A23_A33_H_ */
diff --git a/drivers/clk/sunxi-ng/ccu-sun8i-a23.c b/drivers/clk/sunxi-ng/ccu-sun8i-a23.c
new file mode 100644
index 000000000000..11e624ab28b1
--- /dev/null
+++ b/drivers/clk/sunxi-ng/ccu-sun8i-a23.c
@@ -0,0 +1,737 @@
1/*
2 * Copyright (c) 2016 Maxime Ripard. All rights reserved.
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-a23-a33.h"
31
32
33static struct ccu_nkmp pll_cpux_clk = {
34 .enable = BIT(31),
35 .lock = BIT(28),
36
37 .n = _SUNXI_CCU_MULT(8, 5),
38 .k = _SUNXI_CCU_MULT(4, 2),
39 .m = _SUNXI_CCU_DIV(0, 2),
40 .p = _SUNXI_CCU_DIV_MAX(16, 2, 4),
41
42 .common = {
43 .reg = 0x000,
44 .hw.init = CLK_HW_INIT("pll-cpux", "osc24M",
45 &ccu_nkmp_ops,
46 0),
47 },
48};
49
50/*
51 * The Audio PLL is supposed to have 4 outputs: 3 fixed factors from
52 * the base (2x, 4x and 8x), and one variable divider (the one true
53 * pll audio).
54 *
55 * We don't have any need for the variable divider for now, so we just
56 * hardcode it to match with the clock names
57 */
58#define SUN8I_A23_PLL_AUDIO_REG 0x008
59
60static SUNXI_CCU_NM_WITH_GATE_LOCK(pll_audio_base_clk, "pll-audio-base",
61 "osc24M", 0x008,
62 8, 7, /* N */
63 0, 5, /* M */
64 BIT(31), /* gate */
65 BIT(28), /* lock */
66 CLK_SET_RATE_UNGATE);
67
68static SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK(pll_video_clk, "pll-video",
69 "osc24M", 0x010,
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
80static SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK(pll_ve_clk, "pll-ve",
81 "osc24M", 0x018,
82 8, 7, /* N */
83 0, 4, /* M */
84 BIT(24), /* frac enable */
85 BIT(25), /* frac select */
86 270000000, /* frac rate 0 */
87 297000000, /* frac rate 1 */
88 BIT(31), /* gate */
89 BIT(28), /* lock */
90 CLK_SET_RATE_UNGATE);
91
92static SUNXI_CCU_NKM_WITH_GATE_LOCK(pll_ddr_clk, "pll-ddr",
93 "osc24M", 0x020,
94 8, 5, /* N */
95 4, 2, /* K */
96 0, 2, /* M */
97 BIT(31), /* gate */
98 BIT(28), /* lock */
99 0);
100
101static SUNXI_CCU_NK_WITH_GATE_LOCK_POSTDIV(pll_periph_clk, "pll-periph",
102 "osc24M", 0x028,
103 8, 5, /* N */
104 4, 2, /* K */
105 BIT(31), /* gate */
106 BIT(28), /* lock */
107 2, /* post-div */
108 CLK_SET_RATE_UNGATE);
109
110static SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK(pll_gpu_clk, "pll-gpu",
111 "osc24M", 0x038,
112 8, 7, /* N */
113 0, 4, /* M */
114 BIT(24), /* frac enable */
115 BIT(25), /* frac select */
116 270000000, /* frac rate 0 */
117 297000000, /* frac rate 1 */
118 BIT(31), /* gate */
119 BIT(28), /* lock */
120 CLK_SET_RATE_UNGATE);
121
122/*
123 * The MIPI PLL has 2 modes: "MIPI" and "HDMI".
124 *
125 * The MIPI mode is a standard NKM-style clock. The HDMI mode is an
126 * integer / fractional clock with switchable multipliers and dividers.
127 * This is not supported here. We hardcode the PLL to MIPI mode.
128 */
129#define SUN8I_A23_PLL_MIPI_REG 0x040
130static SUNXI_CCU_NKM_WITH_GATE_LOCK(pll_mipi_clk, "pll-mipi",
131 "pll-video", 0x040,
132 8, 4, /* N */
133 4, 2, /* K */
134 0, 4, /* M */
135 BIT(31), /* gate */
136 BIT(28), /* lock */
137 CLK_SET_RATE_UNGATE);
138
139static SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK(pll_hsic_clk, "pll-hsic",
140 "osc24M", 0x044,
141 8, 7, /* N */
142 0, 4, /* M */
143 BIT(24), /* frac enable */
144 BIT(25), /* frac select */
145 270000000, /* frac rate 0 */
146 297000000, /* frac rate 1 */
147 BIT(31), /* gate */
148 BIT(28), /* lock */
149 CLK_SET_RATE_UNGATE);
150
151static SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK(pll_de_clk, "pll-de",
152 "osc24M", 0x048,
153 8, 7, /* N */
154 0, 4, /* M */
155 BIT(24), /* frac enable */
156 BIT(25), /* frac select */
157 270000000, /* frac rate 0 */
158 297000000, /* frac rate 1 */
159 BIT(31), /* gate */
160 BIT(28), /* lock */
161 CLK_SET_RATE_UNGATE);
162
163static const char * const cpux_parents[] = { "osc32k", "osc24M",
164 "pll-cpux" , "pll-cpux" };
165static SUNXI_CCU_MUX(cpux_clk, "cpux", cpux_parents,
166 0x050, 16, 2, CLK_IS_CRITICAL);
167
168static SUNXI_CCU_M(axi_clk, "axi", "cpux", 0x050, 0, 2, 0);
169
170static const char * const ahb1_parents[] = { "osc32k", "osc24M",
171 "axi" , "pll-periph" };
172static struct ccu_div ahb1_clk = {
173 .div = _SUNXI_CCU_DIV_FLAGS(4, 2, CLK_DIVIDER_POWER_OF_TWO),
174
175 .mux = {
176 .shift = 12,
177 .width = 2,
178
179 .variable_prediv = {
180 .index = 3,
181 .shift = 6,
182 .width = 2,
183 },
184 },
185
186 .common = {
187 .reg = 0x054,
188 .features = CCU_FEATURE_VARIABLE_PREDIV,
189 .hw.init = CLK_HW_INIT_PARENTS("ahb1",
190 ahb1_parents,
191 &ccu_div_ops,
192 0),
193 },
194};
195
196static struct clk_div_table apb1_div_table[] = {
197 { .val = 0, .div = 2 },
198 { .val = 1, .div = 2 },
199 { .val = 2, .div = 4 },
200 { .val = 3, .div = 8 },
201 { /* Sentinel */ },
202};
203static SUNXI_CCU_DIV_TABLE(apb1_clk, "apb1", "ahb1",
204 0x054, 8, 2, apb1_div_table, 0);
205
206static const char * const apb2_parents[] = { "osc32k", "osc24M",
207 "pll-periph" , "pll-periph" };
208static SUNXI_CCU_MP_WITH_MUX(apb2_clk, "apb2", apb2_parents, 0x058,
209 0, 5, /* M */
210 16, 2, /* P */
211 24, 2, /* mux */
212 0);
213
214static SUNXI_CCU_GATE(bus_mipi_dsi_clk, "bus-mipi-dsi", "ahb1",
215 0x060, BIT(1), 0);
216static SUNXI_CCU_GATE(bus_dma_clk, "bus-dma", "ahb1",
217 0x060, BIT(6), 0);
218static SUNXI_CCU_GATE(bus_mmc0_clk, "bus-mmc0", "ahb1",
219 0x060, BIT(8), 0);
220static SUNXI_CCU_GATE(bus_mmc1_clk, "bus-mmc1", "ahb1",
221 0x060, BIT(9), 0);
222static SUNXI_CCU_GATE(bus_mmc2_clk, "bus-mmc2", "ahb1",
223 0x060, BIT(10), 0);
224static SUNXI_CCU_GATE(bus_nand_clk, "bus-nand", "ahb1",
225 0x060, BIT(13), 0);
226static SUNXI_CCU_GATE(bus_dram_clk, "bus-dram", "ahb1",
227 0x060, BIT(14), 0);
228static SUNXI_CCU_GATE(bus_hstimer_clk, "bus-hstimer", "ahb1",
229 0x060, BIT(19), 0);
230static SUNXI_CCU_GATE(bus_spi0_clk, "bus-spi0", "ahb1",
231 0x060, BIT(20), 0);
232static SUNXI_CCU_GATE(bus_spi1_clk, "bus-spi1", "ahb1",
233 0x060, BIT(21), 0);
234static SUNXI_CCU_GATE(bus_otg_clk, "bus-otg", "ahb1",
235 0x060, BIT(24), 0);
236static SUNXI_CCU_GATE(bus_ehci_clk, "bus-ehci", "ahb1",
237 0x060, BIT(26), 0);
238static SUNXI_CCU_GATE(bus_ohci_clk, "bus-ohci", "ahb1",
239 0x060, BIT(29), 0);
240
241static SUNXI_CCU_GATE(bus_ve_clk, "bus-ve", "ahb1",
242 0x064, BIT(0), 0);
243static SUNXI_CCU_GATE(bus_lcd_clk, "bus-lcd", "ahb1",
244 0x064, BIT(4), 0);
245static SUNXI_CCU_GATE(bus_csi_clk, "bus-csi", "ahb1",
246 0x064, BIT(8), 0);
247static SUNXI_CCU_GATE(bus_de_be_clk, "bus-de-be", "ahb1",
248 0x064, BIT(12), 0);
249static SUNXI_CCU_GATE(bus_de_fe_clk, "bus-de-fe", "ahb1",
250 0x064, BIT(14), 0);
251static SUNXI_CCU_GATE(bus_gpu_clk, "bus-gpu", "ahb1",
252 0x064, BIT(20), 0);
253static SUNXI_CCU_GATE(bus_msgbox_clk, "bus-msgbox", "ahb1",
254 0x064, BIT(21), 0);
255static SUNXI_CCU_GATE(bus_spinlock_clk, "bus-spinlock", "ahb1",
256 0x064, BIT(22), 0);
257static SUNXI_CCU_GATE(bus_drc_clk, "bus-drc", "ahb1",
258 0x064, BIT(25), 0);
259
260static SUNXI_CCU_GATE(bus_codec_clk, "bus-codec", "apb1",
261 0x068, BIT(0), 0);
262static SUNXI_CCU_GATE(bus_pio_clk, "bus-pio", "apb1",
263 0x068, BIT(5), 0);
264static SUNXI_CCU_GATE(bus_i2s0_clk, "bus-i2s0", "apb1",
265 0x068, BIT(12), 0);
266static SUNXI_CCU_GATE(bus_i2s1_clk, "bus-i2s1", "apb1",
267 0x068, BIT(13), 0);
268
269static SUNXI_CCU_GATE(bus_i2c0_clk, "bus-i2c0", "apb2",
270 0x06c, BIT(0), 0);
271static SUNXI_CCU_GATE(bus_i2c1_clk, "bus-i2c1", "apb2",
272 0x06c, BIT(1), 0);
273static SUNXI_CCU_GATE(bus_i2c2_clk, "bus-i2c2", "apb2",
274 0x06c, BIT(2), 0);
275static SUNXI_CCU_GATE(bus_uart0_clk, "bus-uart0", "apb2",
276 0x06c, BIT(16), 0);
277static SUNXI_CCU_GATE(bus_uart1_clk, "bus-uart1", "apb2",
278 0x06c, BIT(17), 0);
279static SUNXI_CCU_GATE(bus_uart2_clk, "bus-uart2", "apb2",
280 0x06c, BIT(18), 0);
281static SUNXI_CCU_GATE(bus_uart3_clk, "bus-uart3", "apb2",
282 0x06c, BIT(19), 0);
283static SUNXI_CCU_GATE(bus_uart4_clk, "bus-uart4", "apb2",
284 0x06c, BIT(20), 0);
285
286static const char * const mod0_default_parents[] = { "osc24M", "pll-periph" };
287static SUNXI_CCU_MP_WITH_MUX_GATE(nand_clk, "nand", mod0_default_parents, 0x080,
288 0, 4, /* M */
289 16, 2, /* P */
290 24, 2, /* mux */
291 BIT(31), /* gate */
292 0);
293
294static SUNXI_CCU_MP_WITH_MUX_GATE(mmc0_clk, "mmc0", mod0_default_parents, 0x088,
295 0, 4, /* M */
296 16, 2, /* P */
297 24, 2, /* mux */
298 BIT(31), /* gate */
299 0);
300
301static SUNXI_CCU_PHASE(mmc0_sample_clk, "mmc0_sample", "mmc0",
302 0x088, 20, 3, 0);
303static SUNXI_CCU_PHASE(mmc0_output_clk, "mmc0_output", "mmc0",
304 0x088, 8, 3, 0);
305
306static SUNXI_CCU_MP_WITH_MUX_GATE(mmc1_clk, "mmc1", mod0_default_parents, 0x08c,
307 0, 4, /* M */
308 16, 2, /* P */
309 24, 2, /* mux */
310 BIT(31), /* gate */
311 0);
312
313static SUNXI_CCU_PHASE(mmc1_sample_clk, "mmc1_sample", "mmc1",
314 0x08c, 20, 3, 0);
315static SUNXI_CCU_PHASE(mmc1_output_clk, "mmc1_output", "mmc1",
316 0x08c, 8, 3, 0);
317
318static SUNXI_CCU_MP_WITH_MUX_GATE(mmc2_clk, "mmc2", mod0_default_parents, 0x090,
319 0, 4, /* M */
320 16, 2, /* P */
321 24, 2, /* mux */
322 BIT(31), /* gate */
323 0);
324
325static SUNXI_CCU_PHASE(mmc2_sample_clk, "mmc2_sample", "mmc2",
326 0x090, 20, 3, 0);
327static SUNXI_CCU_PHASE(mmc2_output_clk, "mmc2_output", "mmc2",
328 0x090, 8, 3, 0);
329
330static SUNXI_CCU_MP_WITH_MUX_GATE(spi0_clk, "spi0", mod0_default_parents, 0x0a0,
331 0, 4, /* M */
332 16, 2, /* P */
333 24, 2, /* mux */
334 BIT(31), /* gate */
335 0);
336
337static SUNXI_CCU_MP_WITH_MUX_GATE(spi1_clk, "spi1", mod0_default_parents, 0x0a4,
338 0, 4, /* M */
339 16, 2, /* P */
340 24, 2, /* mux */
341 BIT(31), /* gate */
342 0);
343
344static const char * const i2s_parents[] = { "pll-audio-8x", "pll-audio-4x",
345 "pll-audio-2x", "pll-audio" };
346static SUNXI_CCU_MUX_WITH_GATE(i2s0_clk, "i2s0", i2s_parents,
347 0x0b0, 16, 2, BIT(31), 0);
348
349static SUNXI_CCU_MUX_WITH_GATE(i2s1_clk, "i2s1", i2s_parents,
350 0x0b4, 16, 2, BIT(31), 0);
351
352/* TODO: the parent for most of the USB clocks is not known */
353static SUNXI_CCU_GATE(usb_phy0_clk, "usb-phy0", "osc24M",
354 0x0cc, BIT(8), 0);
355static SUNXI_CCU_GATE(usb_phy1_clk, "usb-phy1", "osc24M",
356 0x0cc, BIT(9), 0);
357static SUNXI_CCU_GATE(usb_hsic_clk, "usb-hsic", "pll-hsic",
358 0x0cc, BIT(10), 0);
359static SUNXI_CCU_GATE(usb_hsic_12M_clk, "usb-hsic-12M", "osc24M",
360 0x0cc, BIT(11), 0);
361static SUNXI_CCU_GATE(usb_ohci_clk, "usb-ohci", "osc24M",
362 0x0cc, BIT(16), 0);
363
364static SUNXI_CCU_GATE(dram_ve_clk, "dram-ve", "pll-ddr",
365 0x100, BIT(0), 0);
366static SUNXI_CCU_GATE(dram_csi_clk, "dram-csi", "pll-ddr",
367 0x100, BIT(1), 0);
368static SUNXI_CCU_GATE(dram_drc_clk, "dram-drc", "pll-ddr",
369 0x100, BIT(16), 0);
370static SUNXI_CCU_GATE(dram_de_fe_clk, "dram-de-fe", "pll-ddr",
371 0x100, BIT(24), 0);
372static SUNXI_CCU_GATE(dram_de_be_clk, "dram-de-be", "pll-ddr",
373 0x100, BIT(26), 0);
374
375static const char * const de_parents[] = { "pll-video", "pll-periph-2x",
376 "pll-gpu", "pll-de" };
377static const u8 de_table[] = { 0, 2, 3, 5 };
378static SUNXI_CCU_M_WITH_MUX_TABLE_GATE(de_be_clk, "de-be",
379 de_parents, de_table,
380 0x104, 0, 4, 24, 3, BIT(31), 0);
381
382static SUNXI_CCU_M_WITH_MUX_TABLE_GATE(de_fe_clk, "de-fe",
383 de_parents, de_table,
384 0x10c, 0, 4, 24, 3, BIT(31), 0);
385
386static const char * const lcd_ch0_parents[] = { "pll-video", "pll-video-2x",
387 "pll-mipi" };
388static const u8 lcd_ch0_table[] = { 0, 2, 4 };
389static SUNXI_CCU_MUX_TABLE_WITH_GATE(lcd_ch0_clk, "lcd-ch0",
390 lcd_ch0_parents, lcd_ch0_table,
391 0x118, 24, 3, BIT(31),
392 CLK_SET_RATE_PARENT);
393
394static const char * const lcd_ch1_parents[] = { "pll-video", "pll-video-2x" };
395static const u8 lcd_ch1_table[] = { 0, 2 };
396static SUNXI_CCU_M_WITH_MUX_TABLE_GATE(lcd_ch1_clk, "lcd-ch1",
397 lcd_ch1_parents, lcd_ch1_table,
398 0x12c, 0, 4, 24, 2, BIT(31), 0);
399
400static const char * const csi_sclk_parents[] = { "pll-video", "pll-de",
401 "pll-mipi", "pll-ve" };
402static const u8 csi_sclk_table[] = { 0, 3, 4, 5 };
403static SUNXI_CCU_M_WITH_MUX_TABLE_GATE(csi_sclk_clk, "csi-sclk",
404 csi_sclk_parents, csi_sclk_table,
405 0x134, 16, 4, 24, 3, BIT(31), 0);
406
407static const char * const csi_mclk_parents[] = { "pll-video", "pll-de",
408 "osc24M" };
409static const u8 csi_mclk_table[] = { 0, 3, 5 };
410static SUNXI_CCU_M_WITH_MUX_TABLE_GATE(csi_mclk_clk, "csi-mclk",
411 csi_mclk_parents, csi_mclk_table,
412 0x134, 0, 5, 8, 3, BIT(15), 0);
413
414static SUNXI_CCU_M_WITH_GATE(ve_clk, "ve", "pll-ve",
415 0x13c, 16, 3, BIT(31), CLK_SET_RATE_PARENT);
416
417static SUNXI_CCU_GATE(ac_dig_clk, "ac-dig", "pll-audio",
418 0x140, BIT(31), 0);
419static SUNXI_CCU_GATE(avs_clk, "avs", "osc24M",
420 0x144, BIT(31), 0);
421
422static const char * const mbus_parents[] = { "osc24M", "pll-periph-2x",
423 "pll-ddr" };
424static SUNXI_CCU_M_WITH_MUX_GATE(mbus_clk, "mbus", mbus_parents,
425 0x15c, 0, 3, 24, 2, BIT(31), CLK_IS_CRITICAL);
426
427static const char * const dsi_sclk_parents[] = { "pll-video", "pll-video-2x" };
428static const u8 dsi_sclk_table[] = { 0, 2 };
429static SUNXI_CCU_M_WITH_MUX_TABLE_GATE(dsi_sclk_clk, "dsi-sclk",
430 dsi_sclk_parents, dsi_sclk_table,
431 0x168, 16, 4, 24, 2, BIT(31), 0);
432
433static const char * const dsi_dphy_parents[] = { "pll-video", "pll-periph" };
434static const u8 dsi_dphy_table[] = { 0, 2 };
435static SUNXI_CCU_M_WITH_MUX_TABLE_GATE(dsi_dphy_clk, "dsi-dphy",
436 dsi_dphy_parents, dsi_dphy_table,
437 0x168, 0, 4, 8, 2, BIT(15), 0);
438
439static SUNXI_CCU_M_WITH_MUX_TABLE_GATE(drc_clk, "drc",
440 de_parents, de_table,
441 0x180, 0, 4, 24, 3, BIT(31), 0);
442
443static SUNXI_CCU_M_WITH_GATE(gpu_clk, "gpu", "pll-gpu",
444 0x1a0, 0, 3, BIT(31), 0);
445
446static const char * const ats_parents[] = { "osc24M", "pll-periph" };
447static SUNXI_CCU_M_WITH_MUX_GATE(ats_clk, "ats", ats_parents,
448 0x1b0, 0, 3, 24, 2, BIT(31), 0);
449
450static struct ccu_common *sun8i_a23_ccu_clks[] = {
451 &pll_cpux_clk.common,
452 &pll_audio_base_clk.common,
453 &pll_video_clk.common,
454 &pll_ve_clk.common,
455 &pll_ddr_clk.common,
456 &pll_periph_clk.common,
457 &pll_gpu_clk.common,
458 &pll_mipi_clk.common,
459 &pll_hsic_clk.common,
460 &pll_de_clk.common,
461 &cpux_clk.common,
462 &axi_clk.common,
463 &ahb1_clk.common,
464 &apb1_clk.common,
465 &apb2_clk.common,
466 &bus_mipi_dsi_clk.common,
467 &bus_dma_clk.common,
468 &bus_mmc0_clk.common,
469 &bus_mmc1_clk.common,
470 &bus_mmc2_clk.common,
471 &bus_nand_clk.common,
472 &bus_dram_clk.common,
473 &bus_hstimer_clk.common,
474 &bus_spi0_clk.common,
475 &bus_spi1_clk.common,
476 &bus_otg_clk.common,
477 &bus_ehci_clk.common,
478 &bus_ohci_clk.common,
479 &bus_ve_clk.common,
480 &bus_lcd_clk.common,
481 &bus_csi_clk.common,
482 &bus_de_fe_clk.common,
483 &bus_de_be_clk.common,
484 &bus_gpu_clk.common,
485 &bus_msgbox_clk.common,
486 &bus_spinlock_clk.common,
487 &bus_drc_clk.common,
488 &bus_codec_clk.common,
489 &bus_pio_clk.common,
490 &bus_i2s0_clk.common,
491 &bus_i2s1_clk.common,
492 &bus_i2c0_clk.common,
493 &bus_i2c1_clk.common,
494 &bus_i2c2_clk.common,
495 &bus_uart0_clk.common,
496 &bus_uart1_clk.common,
497 &bus_uart2_clk.common,
498 &bus_uart3_clk.common,
499 &bus_uart4_clk.common,
500 &nand_clk.common,
501 &mmc0_clk.common,
502 &mmc0_sample_clk.common,
503 &mmc0_output_clk.common,
504 &mmc1_clk.common,
505 &mmc1_sample_clk.common,
506 &mmc1_output_clk.common,
507 &mmc2_clk.common,
508 &mmc2_sample_clk.common,
509 &mmc2_output_clk.common,
510 &spi0_clk.common,
511 &spi1_clk.common,
512 &i2s0_clk.common,
513 &i2s1_clk.common,
514 &usb_phy0_clk.common,
515 &usb_phy1_clk.common,
516 &usb_hsic_clk.common,
517 &usb_hsic_12M_clk.common,
518 &usb_ohci_clk.common,
519 &dram_ve_clk.common,
520 &dram_csi_clk.common,
521 &dram_drc_clk.common,
522 &dram_de_fe_clk.common,
523 &dram_de_be_clk.common,
524 &de_be_clk.common,
525 &de_fe_clk.common,
526 &lcd_ch0_clk.common,
527 &lcd_ch1_clk.common,
528 &csi_sclk_clk.common,
529 &csi_mclk_clk.common,
530 &ve_clk.common,
531 &ac_dig_clk.common,
532 &avs_clk.common,
533 &mbus_clk.common,
534 &dsi_sclk_clk.common,
535 &dsi_dphy_clk.common,
536 &drc_clk.common,
537 &gpu_clk.common,
538 &ats_clk.common,
539};
540
541/* We hardcode the divider to 4 for now */
542static CLK_FIXED_FACTOR(pll_audio_clk, "pll-audio",
543 "pll-audio-base", 4, 1, CLK_SET_RATE_PARENT);
544static CLK_FIXED_FACTOR(pll_audio_2x_clk, "pll-audio-2x",
545 "pll-audio-base", 2, 1, CLK_SET_RATE_PARENT);
546static CLK_FIXED_FACTOR(pll_audio_4x_clk, "pll-audio-4x",
547 "pll-audio-base", 1, 1, CLK_SET_RATE_PARENT);
548static CLK_FIXED_FACTOR(pll_audio_8x_clk, "pll-audio-8x",
549 "pll-audio-base", 1, 2, CLK_SET_RATE_PARENT);
550static CLK_FIXED_FACTOR(pll_periph_2x_clk, "pll-periph-2x",
551 "pll-periph", 1, 2, 0);
552static CLK_FIXED_FACTOR(pll_video_2x_clk, "pll-video-2x",
553 "pll-video", 1, 2, 0);
554
555static struct clk_hw_onecell_data sun8i_a23_hw_clks = {
556 .hws = {
557 [CLK_PLL_CPUX] = &pll_cpux_clk.common.hw,
558 [CLK_PLL_AUDIO_BASE] = &pll_audio_base_clk.common.hw,
559 [CLK_PLL_AUDIO] = &pll_audio_clk.hw,
560 [CLK_PLL_AUDIO_2X] = &pll_audio_2x_clk.hw,
561 [CLK_PLL_AUDIO_4X] = &pll_audio_4x_clk.hw,
562 [CLK_PLL_AUDIO_8X] = &pll_audio_8x_clk.hw,
563 [CLK_PLL_VIDEO] = &pll_video_clk.common.hw,
564 [CLK_PLL_VIDEO_2X] = &pll_video_2x_clk.hw,
565 [CLK_PLL_VE] = &pll_ve_clk.common.hw,
566 [CLK_PLL_DDR0] = &pll_ddr_clk.common.hw,
567 [CLK_PLL_PERIPH] = &pll_periph_clk.common.hw,
568 [CLK_PLL_PERIPH_2X] = &pll_periph_2x_clk.hw,
569 [CLK_PLL_GPU] = &pll_gpu_clk.common.hw,
570 [CLK_PLL_MIPI] = &pll_mipi_clk.common.hw,
571 [CLK_PLL_HSIC] = &pll_hsic_clk.common.hw,
572 [CLK_PLL_DE] = &pll_de_clk.common.hw,
573 [CLK_CPUX] = &cpux_clk.common.hw,
574 [CLK_AXI] = &axi_clk.common.hw,
575 [CLK_AHB1] = &ahb1_clk.common.hw,
576 [CLK_APB1] = &apb1_clk.common.hw,
577 [CLK_APB2] = &apb2_clk.common.hw,
578 [CLK_BUS_MIPI_DSI] = &bus_mipi_dsi_clk.common.hw,
579 [CLK_BUS_DMA] = &bus_dma_clk.common.hw,
580 [CLK_BUS_MMC0] = &bus_mmc0_clk.common.hw,
581 [CLK_BUS_MMC1] = &bus_mmc1_clk.common.hw,
582 [CLK_BUS_MMC2] = &bus_mmc2_clk.common.hw,
583 [CLK_BUS_NAND] = &bus_nand_clk.common.hw,
584 [CLK_BUS_DRAM] = &bus_dram_clk.common.hw,
585 [CLK_BUS_HSTIMER] = &bus_hstimer_clk.common.hw,
586 [CLK_BUS_SPI0] = &bus_spi0_clk.common.hw,
587 [CLK_BUS_SPI1] = &bus_spi1_clk.common.hw,
588 [CLK_BUS_OTG] = &bus_otg_clk.common.hw,
589 [CLK_BUS_EHCI] = &bus_ehci_clk.common.hw,
590 [CLK_BUS_OHCI] = &bus_ohci_clk.common.hw,
591 [CLK_BUS_VE] = &bus_ve_clk.common.hw,
592 [CLK_BUS_LCD] = &bus_lcd_clk.common.hw,
593 [CLK_BUS_CSI] = &bus_csi_clk.common.hw,
594 [CLK_BUS_DE_BE] = &bus_de_be_clk.common.hw,
595 [CLK_BUS_DE_FE] = &bus_de_fe_clk.common.hw,
596 [CLK_BUS_GPU] = &bus_gpu_clk.common.hw,
597 [CLK_BUS_MSGBOX] = &bus_msgbox_clk.common.hw,
598 [CLK_BUS_SPINLOCK] = &bus_spinlock_clk.common.hw,
599 [CLK_BUS_DRC] = &bus_drc_clk.common.hw,
600 [CLK_BUS_CODEC] = &bus_codec_clk.common.hw,
601 [CLK_BUS_PIO] = &bus_pio_clk.common.hw,
602 [CLK_BUS_I2S0] = &bus_i2s0_clk.common.hw,
603 [CLK_BUS_I2S1] = &bus_i2s1_clk.common.hw,
604 [CLK_BUS_I2C0] = &bus_i2c0_clk.common.hw,
605 [CLK_BUS_I2C1] = &bus_i2c1_clk.common.hw,
606 [CLK_BUS_I2C2] = &bus_i2c2_clk.common.hw,
607 [CLK_BUS_UART0] = &bus_uart0_clk.common.hw,
608 [CLK_BUS_UART1] = &bus_uart1_clk.common.hw,
609 [CLK_BUS_UART2] = &bus_uart2_clk.common.hw,
610 [CLK_BUS_UART3] = &bus_uart3_clk.common.hw,
611 [CLK_BUS_UART4] = &bus_uart4_clk.common.hw,
612 [CLK_NAND] = &nand_clk.common.hw,
613 [CLK_MMC0] = &mmc0_clk.common.hw,
614 [CLK_MMC0_SAMPLE] = &mmc0_sample_clk.common.hw,
615 [CLK_MMC0_OUTPUT] = &mmc0_output_clk.common.hw,
616 [CLK_MMC1] = &mmc1_clk.common.hw,
617 [CLK_MMC1_SAMPLE] = &mmc1_sample_clk.common.hw,
618 [CLK_MMC1_OUTPUT] = &mmc1_output_clk.common.hw,
619 [CLK_MMC2] = &mmc2_clk.common.hw,
620 [CLK_MMC2_SAMPLE] = &mmc2_sample_clk.common.hw,
621 [CLK_MMC2_OUTPUT] = &mmc2_output_clk.common.hw,
622 [CLK_SPI0] = &spi0_clk.common.hw,
623 [CLK_SPI1] = &spi1_clk.common.hw,
624 [CLK_I2S0] = &i2s0_clk.common.hw,
625 [CLK_I2S1] = &i2s1_clk.common.hw,
626 [CLK_USB_PHY0] = &usb_phy0_clk.common.hw,
627 [CLK_USB_PHY1] = &usb_phy1_clk.common.hw,
628 [CLK_USB_HSIC] = &usb_hsic_clk.common.hw,
629 [CLK_USB_HSIC_12M] = &usb_hsic_12M_clk.common.hw,
630 [CLK_USB_OHCI] = &usb_ohci_clk.common.hw,
631 [CLK_DRAM_VE] = &dram_ve_clk.common.hw,
632 [CLK_DRAM_CSI] = &dram_csi_clk.common.hw,
633 [CLK_DRAM_DRC] = &dram_drc_clk.common.hw,
634 [CLK_DRAM_DE_FE] = &dram_de_fe_clk.common.hw,
635 [CLK_DRAM_DE_BE] = &dram_de_be_clk.common.hw,
636 [CLK_DE_BE] = &de_be_clk.common.hw,
637 [CLK_DE_FE] = &de_fe_clk.common.hw,
638 [CLK_LCD_CH0] = &lcd_ch0_clk.common.hw,
639 [CLK_LCD_CH1] = &lcd_ch1_clk.common.hw,
640 [CLK_CSI_SCLK] = &csi_sclk_clk.common.hw,
641 [CLK_CSI_MCLK] = &csi_mclk_clk.common.hw,
642 [CLK_VE] = &ve_clk.common.hw,
643 [CLK_AC_DIG] = &ac_dig_clk.common.hw,
644 [CLK_AVS] = &avs_clk.common.hw,
645 [CLK_MBUS] = &mbus_clk.common.hw,
646 [CLK_DSI_SCLK] = &dsi_sclk_clk.common.hw,
647 [CLK_DSI_DPHY] = &dsi_dphy_clk.common.hw,
648 [CLK_DRC] = &drc_clk.common.hw,
649 [CLK_GPU] = &gpu_clk.common.hw,
650 [CLK_ATS] = &ats_clk.common.hw,
651 },
652 .num = CLK_NUMBER,
653};
654
655static struct ccu_reset_map sun8i_a23_ccu_resets[] = {
656 [RST_USB_PHY0] = { 0x0cc, BIT(0) },
657 [RST_USB_PHY1] = { 0x0cc, BIT(1) },
658 [RST_USB_HSIC] = { 0x0cc, BIT(2) },
659
660 [RST_MBUS] = { 0x0fc, BIT(31) },
661
662 [RST_BUS_MIPI_DSI] = { 0x2c0, BIT(1) },
663 [RST_BUS_DMA] = { 0x2c0, BIT(6) },
664 [RST_BUS_MMC0] = { 0x2c0, BIT(8) },
665 [RST_BUS_MMC1] = { 0x2c0, BIT(9) },
666 [RST_BUS_MMC2] = { 0x2c0, BIT(10) },
667 [RST_BUS_NAND] = { 0x2c0, BIT(13) },
668 [RST_BUS_DRAM] = { 0x2c0, BIT(14) },
669 [RST_BUS_HSTIMER] = { 0x2c0, BIT(19) },
670 [RST_BUS_SPI0] = { 0x2c0, BIT(20) },
671 [RST_BUS_SPI1] = { 0x2c0, BIT(21) },
672 [RST_BUS_OTG] = { 0x2c0, BIT(24) },
673 [RST_BUS_EHCI] = { 0x2c0, BIT(26) },
674 [RST_BUS_OHCI] = { 0x2c0, BIT(29) },
675
676 [RST_BUS_VE] = { 0x2c4, BIT(0) },
677 [RST_BUS_LCD] = { 0x2c4, BIT(4) },
678 [RST_BUS_CSI] = { 0x2c4, BIT(8) },
679 [RST_BUS_DE_BE] = { 0x2c4, BIT(12) },
680 [RST_BUS_DE_FE] = { 0x2c4, BIT(14) },
681 [RST_BUS_GPU] = { 0x2c4, BIT(20) },
682 [RST_BUS_MSGBOX] = { 0x2c4, BIT(21) },
683 [RST_BUS_SPINLOCK] = { 0x2c4, BIT(22) },
684 [RST_BUS_DRC] = { 0x2c4, BIT(25) },
685
686 [RST_BUS_LVDS] = { 0x2c8, BIT(0) },
687
688 [RST_BUS_CODEC] = { 0x2d0, BIT(0) },
689 [RST_BUS_I2S0] = { 0x2d0, BIT(12) },
690 [RST_BUS_I2S1] = { 0x2d0, BIT(13) },
691
692 [RST_BUS_I2C0] = { 0x2d4, BIT(0) },
693 [RST_BUS_I2C1] = { 0x2d4, BIT(1) },
694 [RST_BUS_I2C2] = { 0x2d4, BIT(2) },
695 [RST_BUS_UART0] = { 0x2d4, BIT(16) },
696 [RST_BUS_UART1] = { 0x2d4, BIT(17) },
697 [RST_BUS_UART2] = { 0x2d4, BIT(18) },
698 [RST_BUS_UART3] = { 0x2d4, BIT(19) },
699 [RST_BUS_UART4] = { 0x2d4, BIT(20) },
700};
701
702static const struct sunxi_ccu_desc sun8i_a23_ccu_desc = {
703 .ccu_clks = sun8i_a23_ccu_clks,
704 .num_ccu_clks = ARRAY_SIZE(sun8i_a23_ccu_clks),
705
706 .hw_clks = &sun8i_a23_hw_clks,
707
708 .resets = sun8i_a23_ccu_resets,
709 .num_resets = ARRAY_SIZE(sun8i_a23_ccu_resets),
710};
711
712static void __init sun8i_a23_ccu_setup(struct device_node *node)
713{
714 void __iomem *reg;
715 u32 val;
716
717 reg = of_io_request_and_map(node, 0, of_node_full_name(node));
718 if (IS_ERR(reg)) {
719 pr_err("%s: Could not map the clock registers\n",
720 of_node_full_name(node));
721 return;
722 }
723
724 /* Force the PLL-Audio-1x divider to 4 */
725 val = readl(reg + SUN8I_A23_PLL_AUDIO_REG);
726 val &= ~GENMASK(19, 16);
727 writel(val | (3 << 16), reg + SUN8I_A23_PLL_AUDIO_REG);
728
729 /* Force PLL-MIPI to MIPI mode */
730 val = readl(reg + SUN8I_A23_PLL_MIPI_REG);
731 val &= ~BIT(16);
732 writel(val, reg + SUN8I_A23_PLL_MIPI_REG);
733
734 sunxi_ccu_probe(node, reg, &sun8i_a23_ccu_desc);
735}
736CLK_OF_DECLARE(sun8i_a23_ccu, "allwinner,sun8i-a23-ccu",
737 sun8i_a23_ccu_setup);
diff --git a/drivers/clk/sunxi-ng/ccu-sun8i-a33.c b/drivers/clk/sunxi-ng/ccu-sun8i-a33.c
new file mode 100644
index 000000000000..fc00892906d8
--- /dev/null
+++ b/drivers/clk/sunxi-ng/ccu-sun8i-a33.c
@@ -0,0 +1,780 @@
1/*
2 * Copyright (c) 2016 Maxime Ripard. All rights reserved.
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-a23-a33.h"
31
32static struct ccu_nkmp pll_cpux_clk = {
33 .enable = BIT(31),
34 .lock = BIT(28),
35
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
41 .common = {
42 .reg = 0x000,
43 .hw.init = CLK_HW_INIT("pll-cpux", "osc24M",
44 &ccu_nkmp_ops,
45 0),
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_A33_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
67static SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK(pll_video_clk, "pll-video",
68 "osc24M", 0x010,
69 8, 7, /* N */
70 0, 4, /* M */
71 BIT(24), /* frac enable */
72 BIT(25), /* frac select */
73 270000000, /* frac rate 0 */
74 297000000, /* frac rate 1 */
75 BIT(31), /* gate */
76 BIT(28), /* lock */
77 CLK_SET_RATE_UNGATE);
78
79static SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK(pll_ve_clk, "pll-ve",
80 "osc24M", 0x018,
81 8, 7, /* N */
82 0, 4, /* M */
83 BIT(24), /* frac enable */
84 BIT(25), /* frac select */
85 270000000, /* frac rate 0 */
86 297000000, /* frac rate 1 */
87 BIT(31), /* gate */
88 BIT(28), /* lock */
89 CLK_SET_RATE_UNGATE);
90
91static SUNXI_CCU_NKM_WITH_GATE_LOCK(pll_ddr0_clk, "pll-ddr0",
92 "osc24M", 0x020,
93 8, 5, /* N */
94 4, 2, /* K */
95 0, 2, /* M */
96 BIT(31), /* gate */
97 BIT(28), /* lock */
98 0);
99
100static SUNXI_CCU_NK_WITH_GATE_LOCK_POSTDIV(pll_periph_clk, "pll-periph",
101 "osc24M", 0x028,
102 8, 5, /* N */
103 4, 2, /* K */
104 BIT(31), /* gate */
105 BIT(28), /* lock */
106 2, /* post-div */
107 CLK_SET_RATE_UNGATE);
108
109static SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK(pll_gpu_clk, "pll-gpu",
110 "osc24M", 0x038,
111 8, 7, /* N */
112 0, 4, /* M */
113 BIT(24), /* frac enable */
114 BIT(25), /* frac select */
115 270000000, /* frac rate 0 */
116 297000000, /* frac rate 1 */
117 BIT(31), /* gate */
118 BIT(28), /* lock */
119 CLK_SET_RATE_UNGATE);
120
121/*
122 * The MIPI PLL has 2 modes: "MIPI" and "HDMI".
123 *
124 * The MIPI mode is a standard NKM-style clock. The HDMI mode is an
125 * integer / fractional clock with switchable multipliers and dividers.
126 * This is not supported here. We hardcode the PLL to MIPI mode.
127 */
128#define SUN8I_A33_PLL_MIPI_REG 0x040
129static SUNXI_CCU_NKM_WITH_GATE_LOCK(pll_mipi_clk, "pll-mipi",
130 "pll-video", 0x040,
131 8, 4, /* N */
132 4, 2, /* K */
133 0, 4, /* M */
134 BIT(31), /* gate */
135 BIT(28), /* lock */
136 CLK_SET_RATE_UNGATE);
137
138static SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK(pll_hsic_clk, "pll-hsic",
139 "osc24M", 0x044,
140 8, 7, /* N */
141 0, 4, /* M */
142 BIT(24), /* frac enable */
143 BIT(25), /* frac select */
144 270000000, /* frac rate 0 */
145 297000000, /* frac rate 1 */
146 BIT(31), /* gate */
147 BIT(28), /* lock */
148 CLK_SET_RATE_UNGATE);
149
150static SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK(pll_de_clk, "pll-de",
151 "osc24M", 0x048,
152 8, 7, /* N */
153 0, 4, /* M */
154 BIT(24), /* frac enable */
155 BIT(25), /* frac select */
156 270000000, /* frac rate 0 */
157 297000000, /* frac rate 1 */
158 BIT(31), /* gate */
159 BIT(28), /* lock */
160 CLK_SET_RATE_UNGATE);
161
162/* TODO: Fix N */
163static SUNXI_CCU_N_WITH_GATE_LOCK(pll_ddr1_clk, "pll-ddr1",
164 "osc24M", 0x04c,
165 8, 6, /* N */
166 BIT(31), /* gate */
167 BIT(28), /* lock */
168 CLK_SET_RATE_UNGATE);
169
170static const char * const cpux_parents[] = { "osc32k", "osc24M",
171 "pll-cpux" , "pll-cpux" };
172static SUNXI_CCU_MUX(cpux_clk, "cpux", cpux_parents,
173 0x050, 16, 2, CLK_IS_CRITICAL);
174
175static SUNXI_CCU_M(axi_clk, "axi", "cpux", 0x050, 0, 2, 0);
176
177static const char * const ahb1_parents[] = { "osc32k", "osc24M",
178 "axi" , "pll-periph" };
179static struct ccu_div ahb1_clk = {
180 .div = _SUNXI_CCU_DIV_FLAGS(4, 2, CLK_DIVIDER_POWER_OF_TWO),
181
182 .mux = {
183 .shift = 12,
184 .width = 2,
185
186 .variable_prediv = {
187 .index = 3,
188 .shift = 6,
189 .width = 2,
190 },
191 },
192
193 .common = {
194 .reg = 0x054,
195 .features = CCU_FEATURE_VARIABLE_PREDIV,
196 .hw.init = CLK_HW_INIT_PARENTS("ahb1",
197 ahb1_parents,
198 &ccu_div_ops,
199 0),
200 },
201};
202
203static struct clk_div_table apb1_div_table[] = {
204 { .val = 0, .div = 2 },
205 { .val = 1, .div = 2 },
206 { .val = 2, .div = 4 },
207 { .val = 3, .div = 8 },
208 { /* Sentinel */ },
209};
210static SUNXI_CCU_DIV_TABLE(apb1_clk, "apb1", "ahb1",
211 0x054, 8, 2, apb1_div_table, 0);
212
213static const char * const apb2_parents[] = { "osc32k", "osc24M",
214 "pll-periph" , "pll-periph" };
215static SUNXI_CCU_MP_WITH_MUX(apb2_clk, "apb2", apb2_parents, 0x058,
216 0, 5, /* M */
217 16, 2, /* P */
218 24, 2, /* mux */
219 0);
220
221static SUNXI_CCU_GATE(bus_mipi_dsi_clk, "bus-mipi-dsi", "ahb1",
222 0x060, BIT(1), 0);
223static SUNXI_CCU_GATE(bus_ss_clk, "bus-ss", "ahb1",
224 0x060, BIT(5), 0);
225static SUNXI_CCU_GATE(bus_dma_clk, "bus-dma", "ahb1",
226 0x060, BIT(6), 0);
227static SUNXI_CCU_GATE(bus_mmc0_clk, "bus-mmc0", "ahb1",
228 0x060, BIT(8), 0);
229static SUNXI_CCU_GATE(bus_mmc1_clk, "bus-mmc1", "ahb1",
230 0x060, BIT(9), 0);
231static SUNXI_CCU_GATE(bus_mmc2_clk, "bus-mmc2", "ahb1",
232 0x060, BIT(10), 0);
233static SUNXI_CCU_GATE(bus_nand_clk, "bus-nand", "ahb1",
234 0x060, BIT(13), 0);
235static SUNXI_CCU_GATE(bus_dram_clk, "bus-dram", "ahb1",
236 0x060, BIT(14), 0);
237static SUNXI_CCU_GATE(bus_hstimer_clk, "bus-hstimer", "ahb1",
238 0x060, BIT(19), 0);
239static SUNXI_CCU_GATE(bus_spi0_clk, "bus-spi0", "ahb1",
240 0x060, BIT(20), 0);
241static SUNXI_CCU_GATE(bus_spi1_clk, "bus-spi1", "ahb1",
242 0x060, BIT(21), 0);
243static SUNXI_CCU_GATE(bus_otg_clk, "bus-otg", "ahb1",
244 0x060, BIT(24), 0);
245static SUNXI_CCU_GATE(bus_ehci_clk, "bus-ehci", "ahb1",
246 0x060, BIT(26), 0);
247static SUNXI_CCU_GATE(bus_ohci_clk, "bus-ohci", "ahb1",
248 0x060, BIT(29), 0);
249
250static SUNXI_CCU_GATE(bus_ve_clk, "bus-ve", "ahb1",
251 0x064, BIT(0), 0);
252static SUNXI_CCU_GATE(bus_lcd_clk, "bus-lcd", "ahb1",
253 0x064, BIT(4), 0);
254static SUNXI_CCU_GATE(bus_csi_clk, "bus-csi", "ahb1",
255 0x064, BIT(8), 0);
256static SUNXI_CCU_GATE(bus_de_be_clk, "bus-de-be", "ahb1",
257 0x064, BIT(12), 0);
258static SUNXI_CCU_GATE(bus_de_fe_clk, "bus-de-fe", "ahb1",
259 0x064, BIT(14), 0);
260static SUNXI_CCU_GATE(bus_gpu_clk, "bus-gpu", "ahb1",
261 0x064, BIT(20), 0);
262static SUNXI_CCU_GATE(bus_msgbox_clk, "bus-msgbox", "ahb1",
263 0x064, BIT(21), 0);
264static SUNXI_CCU_GATE(bus_spinlock_clk, "bus-spinlock", "ahb1",
265 0x064, BIT(22), 0);
266static SUNXI_CCU_GATE(bus_drc_clk, "bus-drc", "ahb1",
267 0x064, BIT(25), 0);
268static SUNXI_CCU_GATE(bus_sat_clk, "bus-sat", "ahb1",
269 0x064, BIT(26), 0);
270
271static SUNXI_CCU_GATE(bus_codec_clk, "bus-codec", "apb1",
272 0x068, BIT(0), 0);
273static SUNXI_CCU_GATE(bus_pio_clk, "bus-pio", "apb1",
274 0x068, BIT(5), 0);
275static SUNXI_CCU_GATE(bus_i2s0_clk, "bus-i2s0", "apb1",
276 0x068, BIT(12), 0);
277static SUNXI_CCU_GATE(bus_i2s1_clk, "bus-i2s1", "apb1",
278 0x068, BIT(13), 0);
279
280static SUNXI_CCU_GATE(bus_i2c0_clk, "bus-i2c0", "apb2",
281 0x06c, BIT(0), 0);
282static SUNXI_CCU_GATE(bus_i2c1_clk, "bus-i2c1", "apb2",
283 0x06c, BIT(1), 0);
284static SUNXI_CCU_GATE(bus_i2c2_clk, "bus-i2c2", "apb2",
285 0x06c, BIT(2), 0);
286static SUNXI_CCU_GATE(bus_uart0_clk, "bus-uart0", "apb2",
287 0x06c, BIT(16), 0);
288static SUNXI_CCU_GATE(bus_uart1_clk, "bus-uart1", "apb2",
289 0x06c, BIT(17), 0);
290static SUNXI_CCU_GATE(bus_uart2_clk, "bus-uart2", "apb2",
291 0x06c, BIT(18), 0);
292static SUNXI_CCU_GATE(bus_uart3_clk, "bus-uart3", "apb2",
293 0x06c, BIT(19), 0);
294static SUNXI_CCU_GATE(bus_uart4_clk, "bus-uart4", "apb2",
295 0x06c, BIT(20), 0);
296
297static const char * const mod0_default_parents[] = { "osc24M", "pll-periph" };
298static SUNXI_CCU_MP_WITH_MUX_GATE(nand_clk, "nand", mod0_default_parents, 0x080,
299 0, 4, /* M */
300 16, 2, /* P */
301 24, 2, /* mux */
302 BIT(31), /* gate */
303 0);
304
305static SUNXI_CCU_MP_WITH_MUX_GATE(mmc0_clk, "mmc0", mod0_default_parents, 0x088,
306 0, 4, /* M */
307 16, 2, /* P */
308 24, 2, /* mux */
309 BIT(31), /* gate */
310 0);
311
312static SUNXI_CCU_PHASE(mmc0_sample_clk, "mmc0_sample", "mmc0",
313 0x088, 20, 3, 0);
314static SUNXI_CCU_PHASE(mmc0_output_clk, "mmc0_output", "mmc0",
315 0x088, 8, 3, 0);
316
317static SUNXI_CCU_MP_WITH_MUX_GATE(mmc1_clk, "mmc1", mod0_default_parents, 0x08c,
318 0, 4, /* M */
319 16, 2, /* P */
320 24, 2, /* mux */
321 BIT(31), /* gate */
322 0);
323
324static SUNXI_CCU_PHASE(mmc1_sample_clk, "mmc1_sample", "mmc1",
325 0x08c, 20, 3, 0);
326static SUNXI_CCU_PHASE(mmc1_output_clk, "mmc1_output", "mmc1",
327 0x08c, 8, 3, 0);
328
329static SUNXI_CCU_MP_WITH_MUX_GATE(mmc2_clk, "mmc2", mod0_default_parents, 0x090,
330 0, 4, /* M */
331 16, 2, /* P */
332 24, 2, /* mux */
333 BIT(31), /* gate */
334 0);
335
336static SUNXI_CCU_PHASE(mmc2_sample_clk, "mmc2_sample", "mmc2",
337 0x090, 20, 3, 0);
338static SUNXI_CCU_PHASE(mmc2_output_clk, "mmc2_output", "mmc2",
339 0x090, 8, 3, 0);
340
341static SUNXI_CCU_MP_WITH_MUX_GATE(ss_clk, "ss", mod0_default_parents, 0x09c,
342 0, 4, /* M */
343 16, 2, /* P */
344 24, 2, /* mux */
345 BIT(31), /* gate */
346 0);
347
348static SUNXI_CCU_MP_WITH_MUX_GATE(spi0_clk, "spi0", mod0_default_parents, 0x0a0,
349 0, 4, /* M */
350 16, 2, /* P */
351 24, 2, /* mux */
352 BIT(31), /* gate */
353 0);
354
355static SUNXI_CCU_MP_WITH_MUX_GATE(spi1_clk, "spi1", mod0_default_parents, 0x0a4,
356 0, 4, /* M */
357 16, 2, /* P */
358 24, 2, /* mux */
359 BIT(31), /* gate */
360 0);
361
362static const char * const i2s_parents[] = { "pll-audio-8x", "pll-audio-4x",
363 "pll-audio-2x", "pll-audio" };
364static SUNXI_CCU_MUX_WITH_GATE(i2s0_clk, "i2s0", i2s_parents,
365 0x0b0, 16, 2, BIT(31), 0);
366
367static SUNXI_CCU_MUX_WITH_GATE(i2s1_clk, "i2s1", i2s_parents,
368 0x0b4, 16, 2, BIT(31), 0);
369
370/* TODO: the parent for most of the USB clocks is not known */
371static SUNXI_CCU_GATE(usb_phy0_clk, "usb-phy0", "osc24M",
372 0x0cc, BIT(8), 0);
373static SUNXI_CCU_GATE(usb_phy1_clk, "usb-phy1", "osc24M",
374 0x0cc, BIT(9), 0);
375static SUNXI_CCU_GATE(usb_hsic_clk, "usb-hsic", "pll-hsic",
376 0x0cc, BIT(10), 0);
377static SUNXI_CCU_GATE(usb_hsic_12M_clk, "usb-hsic-12M", "osc24M",
378 0x0cc, BIT(11), 0);
379static SUNXI_CCU_GATE(usb_ohci_clk, "usb-ohci", "osc24M",
380 0x0cc, BIT(16), 0);
381
382static SUNXI_CCU_M(dram_clk, "dram", "pll-ddr",
383 0x0f4, 0, 4, CLK_IS_CRITICAL);
384
385static const char * const pll_ddr_parents[] = { "pll-ddr0", "pll-ddr1" };
386static SUNXI_CCU_MUX(pll_ddr_clk, "pll-ddr", pll_ddr_parents,
387 0x0f8, 16, 1, 0);
388
389static SUNXI_CCU_GATE(dram_ve_clk, "dram-ve", "dram",
390 0x100, BIT(0), 0);
391static SUNXI_CCU_GATE(dram_csi_clk, "dram-csi", "dram",
392 0x100, BIT(1), 0);
393static SUNXI_CCU_GATE(dram_drc_clk, "dram-drc", "dram",
394 0x100, BIT(16), 0);
395static SUNXI_CCU_GATE(dram_de_fe_clk, "dram-de-fe", "dram",
396 0x100, BIT(24), 0);
397static SUNXI_CCU_GATE(dram_de_be_clk, "dram-de-be", "dram",
398 0x100, BIT(26), 0);
399
400static const char * const de_parents[] = { "pll-video", "pll-periph-2x",
401 "pll-gpu", "pll-de" };
402static const u8 de_table[] = { 0, 2, 3, 5 };
403static SUNXI_CCU_M_WITH_MUX_TABLE_GATE(de_be_clk, "de-be",
404 de_parents, de_table,
405 0x104, 0, 4, 24, 3, BIT(31), 0);
406
407static SUNXI_CCU_M_WITH_MUX_TABLE_GATE(de_fe_clk, "de-fe",
408 de_parents, de_table,
409 0x10c, 0, 4, 24, 3, BIT(31), 0);
410
411static const char * const lcd_ch0_parents[] = { "pll-video", "pll-video-2x",
412 "pll-mipi" };
413static const u8 lcd_ch0_table[] = { 0, 2, 4 };
414static SUNXI_CCU_MUX_TABLE_WITH_GATE(lcd_ch0_clk, "lcd-ch0",
415 lcd_ch0_parents, lcd_ch0_table,
416 0x118, 24, 3, BIT(31),
417 CLK_SET_RATE_PARENT);
418
419static const char * const lcd_ch1_parents[] = { "pll-video", "pll-video-2x" };
420static const u8 lcd_ch1_table[] = { 0, 2 };
421static SUNXI_CCU_M_WITH_MUX_TABLE_GATE(lcd_ch1_clk, "lcd-ch1",
422 lcd_ch1_parents, lcd_ch1_table,
423 0x12c, 0, 4, 24, 2, BIT(31), 0);
424
425static const char * const csi_sclk_parents[] = { "pll-video", "pll-de",
426 "pll-mipi", "pll-ve" };
427static const u8 csi_sclk_table[] = { 0, 3, 4, 5 };
428static SUNXI_CCU_M_WITH_MUX_TABLE_GATE(csi_sclk_clk, "csi-sclk",
429 csi_sclk_parents, csi_sclk_table,
430 0x134, 16, 4, 24, 3, BIT(31), 0);
431
432static const char * const csi_mclk_parents[] = { "pll-video", "pll-de",
433 "osc24M" };
434static const u8 csi_mclk_table[] = { 0, 3, 5 };
435static SUNXI_CCU_M_WITH_MUX_TABLE_GATE(csi_mclk_clk, "csi-mclk",
436 csi_mclk_parents, csi_mclk_table,
437 0x134, 0, 5, 8, 3, BIT(15), 0);
438
439static SUNXI_CCU_M_WITH_GATE(ve_clk, "ve", "pll-ve",
440 0x13c, 16, 3, BIT(31), CLK_SET_RATE_PARENT);
441
442static SUNXI_CCU_GATE(ac_dig_clk, "ac-dig", "pll-audio",
443 0x140, BIT(31), 0);
444static SUNXI_CCU_GATE(ac_dig_4x_clk, "ac-dig-4x", "pll-audio-4x",
445 0x140, BIT(30), 0);
446static SUNXI_CCU_GATE(avs_clk, "avs", "osc24M",
447 0x144, BIT(31), 0);
448
449static const char * const mbus_parents[] = { "osc24M", "pll-periph-2x",
450 "pll-ddr0", "pll-ddr1" };
451static SUNXI_CCU_M_WITH_MUX_GATE(mbus_clk, "mbus", mbus_parents,
452 0x15c, 0, 3, 24, 2, BIT(31), CLK_IS_CRITICAL);
453
454static const char * const dsi_sclk_parents[] = { "pll-video", "pll-video-2x" };
455static const u8 dsi_sclk_table[] = { 0, 2 };
456static SUNXI_CCU_M_WITH_MUX_TABLE_GATE(dsi_sclk_clk, "dsi-sclk",
457 dsi_sclk_parents, dsi_sclk_table,
458 0x168, 16, 4, 24, 2, BIT(31), 0);
459
460static const char * const dsi_dphy_parents[] = { "pll-video", "pll-periph" };
461static const u8 dsi_dphy_table[] = { 0, 2 };
462static SUNXI_CCU_M_WITH_MUX_TABLE_GATE(dsi_dphy_clk, "dsi-dphy",
463 dsi_dphy_parents, dsi_dphy_table,
464 0x168, 0, 4, 8, 2, BIT(15), 0);
465
466static SUNXI_CCU_M_WITH_MUX_TABLE_GATE(drc_clk, "drc",
467 de_parents, de_table,
468 0x180, 0, 4, 24, 3, BIT(31), 0);
469
470static SUNXI_CCU_M_WITH_GATE(gpu_clk, "gpu", "pll-gpu",
471 0x1a0, 0, 3, BIT(31), 0);
472
473static const char * const ats_parents[] = { "osc24M", "pll-periph" };
474static SUNXI_CCU_M_WITH_MUX_GATE(ats_clk, "ats", ats_parents,
475 0x1b0, 0, 3, 24, 2, BIT(31), 0);
476
477static struct ccu_common *sun8i_a33_ccu_clks[] = {
478 &pll_cpux_clk.common,
479 &pll_audio_base_clk.common,
480 &pll_video_clk.common,
481 &pll_ve_clk.common,
482 &pll_ddr0_clk.common,
483 &pll_periph_clk.common,
484 &pll_gpu_clk.common,
485 &pll_mipi_clk.common,
486 &pll_hsic_clk.common,
487 &pll_de_clk.common,
488 &pll_ddr1_clk.common,
489 &pll_ddr_clk.common,
490 &cpux_clk.common,
491 &axi_clk.common,
492 &ahb1_clk.common,
493 &apb1_clk.common,
494 &apb2_clk.common,
495 &bus_mipi_dsi_clk.common,
496 &bus_ss_clk.common,
497 &bus_dma_clk.common,
498 &bus_mmc0_clk.common,
499 &bus_mmc1_clk.common,
500 &bus_mmc2_clk.common,
501 &bus_nand_clk.common,
502 &bus_dram_clk.common,
503 &bus_hstimer_clk.common,
504 &bus_spi0_clk.common,
505 &bus_spi1_clk.common,
506 &bus_otg_clk.common,
507 &bus_ehci_clk.common,
508 &bus_ohci_clk.common,
509 &bus_ve_clk.common,
510 &bus_lcd_clk.common,
511 &bus_csi_clk.common,
512 &bus_de_fe_clk.common,
513 &bus_de_be_clk.common,
514 &bus_gpu_clk.common,
515 &bus_msgbox_clk.common,
516 &bus_spinlock_clk.common,
517 &bus_drc_clk.common,
518 &bus_sat_clk.common,
519 &bus_codec_clk.common,
520 &bus_pio_clk.common,
521 &bus_i2s0_clk.common,
522 &bus_i2s1_clk.common,
523 &bus_i2c0_clk.common,
524 &bus_i2c1_clk.common,
525 &bus_i2c2_clk.common,
526 &bus_uart0_clk.common,
527 &bus_uart1_clk.common,
528 &bus_uart2_clk.common,
529 &bus_uart3_clk.common,
530 &bus_uart4_clk.common,
531 &nand_clk.common,
532 &mmc0_clk.common,
533 &mmc0_sample_clk.common,
534 &mmc0_output_clk.common,
535 &mmc1_clk.common,
536 &mmc1_sample_clk.common,
537 &mmc1_output_clk.common,
538 &mmc2_clk.common,
539 &mmc2_sample_clk.common,
540 &mmc2_output_clk.common,
541 &ss_clk.common,
542 &spi0_clk.common,
543 &spi1_clk.common,
544 &i2s0_clk.common,
545 &i2s1_clk.common,
546 &usb_phy0_clk.common,
547 &usb_phy1_clk.common,
548 &usb_hsic_clk.common,
549 &usb_hsic_12M_clk.common,
550 &usb_ohci_clk.common,
551 &dram_clk.common,
552 &dram_ve_clk.common,
553 &dram_csi_clk.common,
554 &dram_drc_clk.common,
555 &dram_de_fe_clk.common,
556 &dram_de_be_clk.common,
557 &de_be_clk.common,
558 &de_fe_clk.common,
559 &lcd_ch0_clk.common,
560 &lcd_ch1_clk.common,
561 &csi_sclk_clk.common,
562 &csi_mclk_clk.common,
563 &ve_clk.common,
564 &ac_dig_clk.common,
565 &ac_dig_4x_clk.common,
566 &avs_clk.common,
567 &mbus_clk.common,
568 &dsi_sclk_clk.common,
569 &dsi_dphy_clk.common,
570 &drc_clk.common,
571 &gpu_clk.common,
572 &ats_clk.common,
573};
574
575/* We hardcode the divider to 4 for now */
576static CLK_FIXED_FACTOR(pll_audio_clk, "pll-audio",
577 "pll-audio-base", 4, 1, CLK_SET_RATE_PARENT);
578static CLK_FIXED_FACTOR(pll_audio_2x_clk, "pll-audio-2x",
579 "pll-audio-base", 2, 1, CLK_SET_RATE_PARENT);
580static CLK_FIXED_FACTOR(pll_audio_4x_clk, "pll-audio-4x",
581 "pll-audio-base", 1, 1, CLK_SET_RATE_PARENT);
582static CLK_FIXED_FACTOR(pll_audio_8x_clk, "pll-audio-8x",
583 "pll-audio-base", 1, 2, CLK_SET_RATE_PARENT);
584static CLK_FIXED_FACTOR(pll_periph_2x_clk, "pll-periph-2x",
585 "pll-periph", 1, 2, 0);
586static CLK_FIXED_FACTOR(pll_video_2x_clk, "pll-video-2x",
587 "pll-video", 1, 2, 0);
588
589static struct clk_hw_onecell_data sun8i_a33_hw_clks = {
590 .hws = {
591 [CLK_PLL_CPUX] = &pll_cpux_clk.common.hw,
592 [CLK_PLL_AUDIO_BASE] = &pll_audio_base_clk.common.hw,
593 [CLK_PLL_AUDIO] = &pll_audio_clk.hw,
594 [CLK_PLL_AUDIO_2X] = &pll_audio_2x_clk.hw,
595 [CLK_PLL_AUDIO_4X] = &pll_audio_4x_clk.hw,
596 [CLK_PLL_AUDIO_8X] = &pll_audio_8x_clk.hw,
597 [CLK_PLL_VIDEO] = &pll_video_clk.common.hw,
598 [CLK_PLL_VIDEO_2X] = &pll_video_2x_clk.hw,
599 [CLK_PLL_VE] = &pll_ve_clk.common.hw,
600 [CLK_PLL_DDR0] = &pll_ddr0_clk.common.hw,
601 [CLK_PLL_PERIPH] = &pll_periph_clk.common.hw,
602 [CLK_PLL_PERIPH_2X] = &pll_periph_2x_clk.hw,
603 [CLK_PLL_GPU] = &pll_gpu_clk.common.hw,
604 [CLK_PLL_MIPI] = &pll_mipi_clk.common.hw,
605 [CLK_PLL_HSIC] = &pll_hsic_clk.common.hw,
606 [CLK_PLL_DE] = &pll_de_clk.common.hw,
607 [CLK_PLL_DDR1] = &pll_ddr1_clk.common.hw,
608 [CLK_PLL_DDR] = &pll_ddr_clk.common.hw,
609 [CLK_CPUX] = &cpux_clk.common.hw,
610 [CLK_AXI] = &axi_clk.common.hw,
611 [CLK_AHB1] = &ahb1_clk.common.hw,
612 [CLK_APB1] = &apb1_clk.common.hw,
613 [CLK_APB2] = &apb2_clk.common.hw,
614 [CLK_BUS_MIPI_DSI] = &bus_mipi_dsi_clk.common.hw,
615 [CLK_BUS_SS] = &bus_ss_clk.common.hw,
616 [CLK_BUS_DMA] = &bus_dma_clk.common.hw,
617 [CLK_BUS_MMC0] = &bus_mmc0_clk.common.hw,
618 [CLK_BUS_MMC1] = &bus_mmc1_clk.common.hw,
619 [CLK_BUS_MMC2] = &bus_mmc2_clk.common.hw,
620 [CLK_BUS_NAND] = &bus_nand_clk.common.hw,
621 [CLK_BUS_DRAM] = &bus_dram_clk.common.hw,
622 [CLK_BUS_HSTIMER] = &bus_hstimer_clk.common.hw,
623 [CLK_BUS_SPI0] = &bus_spi0_clk.common.hw,
624 [CLK_BUS_SPI1] = &bus_spi1_clk.common.hw,
625 [CLK_BUS_OTG] = &bus_otg_clk.common.hw,
626 [CLK_BUS_EHCI] = &bus_ehci_clk.common.hw,
627 [CLK_BUS_OHCI] = &bus_ohci_clk.common.hw,
628 [CLK_BUS_VE] = &bus_ve_clk.common.hw,
629 [CLK_BUS_LCD] = &bus_lcd_clk.common.hw,
630 [CLK_BUS_CSI] = &bus_csi_clk.common.hw,
631 [CLK_BUS_DE_BE] = &bus_de_be_clk.common.hw,
632 [CLK_BUS_DE_FE] = &bus_de_fe_clk.common.hw,
633 [CLK_BUS_GPU] = &bus_gpu_clk.common.hw,
634 [CLK_BUS_MSGBOX] = &bus_msgbox_clk.common.hw,
635 [CLK_BUS_SPINLOCK] = &bus_spinlock_clk.common.hw,
636 [CLK_BUS_DRC] = &bus_drc_clk.common.hw,
637 [CLK_BUS_SAT] = &bus_sat_clk.common.hw,
638 [CLK_BUS_CODEC] = &bus_codec_clk.common.hw,
639 [CLK_BUS_PIO] = &bus_pio_clk.common.hw,
640 [CLK_BUS_I2S0] = &bus_i2s0_clk.common.hw,
641 [CLK_BUS_I2S1] = &bus_i2s1_clk.common.hw,
642 [CLK_BUS_I2C0] = &bus_i2c0_clk.common.hw,
643 [CLK_BUS_I2C1] = &bus_i2c1_clk.common.hw,
644 [CLK_BUS_I2C2] = &bus_i2c2_clk.common.hw,
645 [CLK_BUS_UART0] = &bus_uart0_clk.common.hw,
646 [CLK_BUS_UART1] = &bus_uart1_clk.common.hw,
647 [CLK_BUS_UART2] = &bus_uart2_clk.common.hw,
648 [CLK_BUS_UART3] = &bus_uart3_clk.common.hw,
649 [CLK_BUS_UART4] = &bus_uart4_clk.common.hw,
650 [CLK_NAND] = &nand_clk.common.hw,
651 [CLK_MMC0] = &mmc0_clk.common.hw,
652 [CLK_MMC0_SAMPLE] = &mmc0_sample_clk.common.hw,
653 [CLK_MMC0_OUTPUT] = &mmc0_output_clk.common.hw,
654 [CLK_MMC1] = &mmc1_clk.common.hw,
655 [CLK_MMC1_SAMPLE] = &mmc1_sample_clk.common.hw,
656 [CLK_MMC1_OUTPUT] = &mmc1_output_clk.common.hw,
657 [CLK_MMC2] = &mmc2_clk.common.hw,
658 [CLK_MMC2_SAMPLE] = &mmc2_sample_clk.common.hw,
659 [CLK_MMC2_OUTPUT] = &mmc2_output_clk.common.hw,
660 [CLK_SS] = &ss_clk.common.hw,
661 [CLK_SPI0] = &spi0_clk.common.hw,
662 [CLK_SPI1] = &spi1_clk.common.hw,
663 [CLK_I2S0] = &i2s0_clk.common.hw,
664 [CLK_I2S1] = &i2s1_clk.common.hw,
665 [CLK_USB_PHY0] = &usb_phy0_clk.common.hw,
666 [CLK_USB_PHY1] = &usb_phy1_clk.common.hw,
667 [CLK_USB_HSIC] = &usb_hsic_clk.common.hw,
668 [CLK_USB_HSIC_12M] = &usb_hsic_12M_clk.common.hw,
669 [CLK_USB_OHCI] = &usb_ohci_clk.common.hw,
670 [CLK_DRAM] = &dram_clk.common.hw,
671 [CLK_DRAM_VE] = &dram_ve_clk.common.hw,
672 [CLK_DRAM_CSI] = &dram_csi_clk.common.hw,
673 [CLK_DRAM_DRC] = &dram_drc_clk.common.hw,
674 [CLK_DRAM_DE_FE] = &dram_de_fe_clk.common.hw,
675 [CLK_DRAM_DE_BE] = &dram_de_be_clk.common.hw,
676 [CLK_DE_BE] = &de_be_clk.common.hw,
677 [CLK_DE_FE] = &de_fe_clk.common.hw,
678 [CLK_LCD_CH0] = &lcd_ch0_clk.common.hw,
679 [CLK_LCD_CH1] = &lcd_ch1_clk.common.hw,
680 [CLK_CSI_SCLK] = &csi_sclk_clk.common.hw,
681 [CLK_CSI_MCLK] = &csi_mclk_clk.common.hw,
682 [CLK_VE] = &ve_clk.common.hw,
683 [CLK_AC_DIG] = &ac_dig_clk.common.hw,
684 [CLK_AC_DIG_4X] = &ac_dig_4x_clk.common.hw,
685 [CLK_AVS] = &avs_clk.common.hw,
686 [CLK_MBUS] = &mbus_clk.common.hw,
687 [CLK_DSI_SCLK] = &dsi_sclk_clk.common.hw,
688 [CLK_DSI_DPHY] = &dsi_dphy_clk.common.hw,
689 [CLK_DRC] = &drc_clk.common.hw,
690 [CLK_GPU] = &gpu_clk.common.hw,
691 [CLK_ATS] = &ats_clk.common.hw,
692 },
693 .num = CLK_NUMBER,
694};
695
696static struct ccu_reset_map sun8i_a33_ccu_resets[] = {
697 [RST_USB_PHY0] = { 0x0cc, BIT(0) },
698 [RST_USB_PHY1] = { 0x0cc, BIT(1) },
699 [RST_USB_HSIC] = { 0x0cc, BIT(2) },
700
701 [RST_MBUS] = { 0x0fc, BIT(31) },
702
703 [RST_BUS_MIPI_DSI] = { 0x2c0, BIT(1) },
704 [RST_BUS_SS] = { 0x2c0, BIT(5) },
705 [RST_BUS_DMA] = { 0x2c0, BIT(6) },
706 [RST_BUS_MMC0] = { 0x2c0, BIT(8) },
707 [RST_BUS_MMC1] = { 0x2c0, BIT(9) },
708 [RST_BUS_MMC2] = { 0x2c0, BIT(10) },
709 [RST_BUS_NAND] = { 0x2c0, BIT(13) },
710 [RST_BUS_DRAM] = { 0x2c0, BIT(14) },
711 [RST_BUS_HSTIMER] = { 0x2c0, BIT(19) },
712 [RST_BUS_SPI0] = { 0x2c0, BIT(20) },
713 [RST_BUS_SPI1] = { 0x2c0, BIT(21) },
714 [RST_BUS_OTG] = { 0x2c0, BIT(24) },
715 [RST_BUS_EHCI] = { 0x2c0, BIT(26) },
716 [RST_BUS_OHCI] = { 0x2c0, BIT(29) },
717
718 [RST_BUS_VE] = { 0x2c4, BIT(0) },
719 [RST_BUS_LCD] = { 0x2c4, BIT(4) },
720 [RST_BUS_CSI] = { 0x2c4, BIT(8) },
721 [RST_BUS_DE_BE] = { 0x2c4, BIT(12) },
722 [RST_BUS_DE_FE] = { 0x2c4, BIT(14) },
723 [RST_BUS_GPU] = { 0x2c4, BIT(20) },
724 [RST_BUS_MSGBOX] = { 0x2c4, BIT(21) },
725 [RST_BUS_SPINLOCK] = { 0x2c4, BIT(22) },
726 [RST_BUS_DRC] = { 0x2c4, BIT(25) },
727 [RST_BUS_SAT] = { 0x2c4, BIT(26) },
728
729 [RST_BUS_LVDS] = { 0x2c8, BIT(0) },
730
731 [RST_BUS_CODEC] = { 0x2d0, BIT(0) },
732 [RST_BUS_I2S0] = { 0x2d0, BIT(12) },
733 [RST_BUS_I2S1] = { 0x2d0, BIT(13) },
734
735 [RST_BUS_I2C0] = { 0x2d4, BIT(0) },
736 [RST_BUS_I2C1] = { 0x2d4, BIT(1) },
737 [RST_BUS_I2C2] = { 0x2d4, BIT(2) },
738 [RST_BUS_UART0] = { 0x2d4, BIT(16) },
739 [RST_BUS_UART1] = { 0x2d4, BIT(17) },
740 [RST_BUS_UART2] = { 0x2d4, BIT(18) },
741 [RST_BUS_UART3] = { 0x2d4, BIT(19) },
742 [RST_BUS_UART4] = { 0x2d4, BIT(20) },
743};
744
745static const struct sunxi_ccu_desc sun8i_a33_ccu_desc = {
746 .ccu_clks = sun8i_a33_ccu_clks,
747 .num_ccu_clks = ARRAY_SIZE(sun8i_a33_ccu_clks),
748
749 .hw_clks = &sun8i_a33_hw_clks,
750
751 .resets = sun8i_a33_ccu_resets,
752 .num_resets = ARRAY_SIZE(sun8i_a33_ccu_resets),
753};
754
755static void __init sun8i_a33_ccu_setup(struct device_node *node)
756{
757 void __iomem *reg;
758 u32 val;
759
760 reg = of_io_request_and_map(node, 0, of_node_full_name(node));
761 if (IS_ERR(reg)) {
762 pr_err("%s: Could not map the clock registers\n",
763 of_node_full_name(node));
764 return;
765 }
766
767 /* Force the PLL-Audio-1x divider to 4 */
768 val = readl(reg + SUN8I_A33_PLL_AUDIO_REG);
769 val &= ~GENMASK(19, 16);
770 writel(val | (3 << 16), reg + SUN8I_A33_PLL_AUDIO_REG);
771
772 /* Force PLL-MIPI to MIPI mode */
773 val = readl(reg + SUN8I_A33_PLL_MIPI_REG);
774 val &= ~BIT(16);
775 writel(val, reg + SUN8I_A33_PLL_MIPI_REG);
776
777 sunxi_ccu_probe(node, reg, &sun8i_a33_ccu_desc);
778}
779CLK_OF_DECLARE(sun8i_a33_ccu, "allwinner,sun8i-a33-ccu",
780 sun8i_a33_ccu_setup);
diff --git a/drivers/clk/sunxi-ng/ccu-sun8i-h3.c b/drivers/clk/sunxi-ng/ccu-sun8i-h3.c
index 267f99523fbe..4d70590f05e3 100644
--- a/drivers/clk/sunxi-ng/ccu-sun8i-h3.c
+++ b/drivers/clk/sunxi-ng/ccu-sun8i-h3.c
@@ -184,15 +184,15 @@ static SUNXI_CCU_MP_WITH_MUX(apb2_clk, "apb2", apb2_parents, 0x058,
184 0); 184 0);
185 185
186static const char * const ahb2_parents[] = { "ahb1" , "pll-periph0" }; 186static const char * const ahb2_parents[] = { "ahb1" , "pll-periph0" };
187static const struct ccu_mux_fixed_prediv ahb2_fixed_predivs[] = {
188 { .index = 1, .div = 2 },
189};
187static struct ccu_mux ahb2_clk = { 190static struct ccu_mux ahb2_clk = {
188 .mux = { 191 .mux = {
189 .shift = 0, 192 .shift = 0,
190 .width = 1, 193 .width = 1,
191 194 .fixed_predivs = ahb2_fixed_predivs,
192 .fixed_prediv = { 195 .n_predivs = ARRAY_SIZE(ahb2_fixed_predivs),
193 .index = 1,
194 .div = 2,
195 },
196 }, 196 },
197 197
198 .common = { 198 .common = {
diff --git a/drivers/clk/sunxi-ng/ccu_div.h b/drivers/clk/sunxi-ng/ccu_div.h
index 653ade5769b3..34c338832c0d 100644
--- a/drivers/clk/sunxi-ng/ccu_div.h
+++ b/drivers/clk/sunxi-ng/ccu_div.h
@@ -19,10 +19,29 @@
19#include "ccu_common.h" 19#include "ccu_common.h"
20#include "ccu_mux.h" 20#include "ccu_mux.h"
21 21
22/**
23 * struct _ccu_div - Internal divider description
24 * @shift: Bit offset of the divider in its register
25 * @width: Width of the divider field in its register
26 * @max: Maximum value allowed for that divider. This is the
27 * arithmetic value, not the maximum value to be set in the
28 * register.
29 * @flags: clk_divider flags to apply on this divider
30 * @table: Divider table pointer (if applicable)
31 *
32 * That structure represents a single divider, and is meant to be
33 * embedded in other structures representing the various clock
34 * classes.
35 *
36 * It is basically a wrapper around the clk_divider functions
37 * arguments.
38 */
22struct _ccu_div { 39struct _ccu_div {
23 u8 shift; 40 u8 shift;
24 u8 width; 41 u8 width;
25 42
43 u32 max;
44
26 u32 flags; 45 u32 flags;
27 46
28 struct clk_div_table *table; 47 struct clk_div_table *table;
@@ -36,14 +55,25 @@ struct _ccu_div {
36 .table = _table, \ 55 .table = _table, \
37 } 56 }
38 57
39#define _SUNXI_CCU_DIV_FLAGS(_shift, _width, _flags) \
40 _SUNXI_CCU_DIV_TABLE_FLAGS(_shift, _width, NULL, _flags)
41
42#define _SUNXI_CCU_DIV_TABLE(_shift, _width, _table) \ 58#define _SUNXI_CCU_DIV_TABLE(_shift, _width, _table) \
43 _SUNXI_CCU_DIV_TABLE_FLAGS(_shift, _width, _table, 0) 59 _SUNXI_CCU_DIV_TABLE_FLAGS(_shift, _width, _table, 0)
44 60
61#define _SUNXI_CCU_DIV_MAX_FLAGS(_shift, _width, _max, _flags) \
62 { \
63 .shift = _shift, \
64 .width = _width, \
65 .flags = _flags, \
66 .max = _max, \
67 }
68
69#define _SUNXI_CCU_DIV_FLAGS(_shift, _width, _flags) \
70 _SUNXI_CCU_DIV_MAX_FLAGS(_shift, _width, 0, _flags)
71
72#define _SUNXI_CCU_DIV_MAX(_shift, _width, _max) \
73 _SUNXI_CCU_DIV_MAX_FLAGS(_shift, _width, _max, 0)
74
45#define _SUNXI_CCU_DIV(_shift, _width) \ 75#define _SUNXI_CCU_DIV(_shift, _width) \
46 _SUNXI_CCU_DIV_TABLE_FLAGS(_shift, _width, NULL, 0) 76 _SUNXI_CCU_DIV_FLAGS(_shift, _width, 0)
47 77
48struct ccu_div { 78struct ccu_div {
49 u32 enable; 79 u32 enable;
@@ -77,13 +107,16 @@ struct ccu_div {
77 _shift, _width, _table, 0, \ 107 _shift, _width, _table, 0, \
78 _flags) 108 _flags)
79 109
80#define SUNXI_CCU_M_WITH_MUX_GATE(_struct, _name, _parents, _reg, \ 110#define SUNXI_CCU_M_WITH_MUX_TABLE_GATE(_struct, _name, \
81 _mshift, _mwidth, _muxshift, _muxwidth, \ 111 _parents, _table, \
82 _gate, _flags) \ 112 _reg, \
113 _mshift, _mwidth, \
114 _muxshift, _muxwidth, \
115 _gate, _flags) \
83 struct ccu_div _struct = { \ 116 struct ccu_div _struct = { \
84 .enable = _gate, \ 117 .enable = _gate, \
85 .div = _SUNXI_CCU_DIV(_mshift, _mwidth), \ 118 .div = _SUNXI_CCU_DIV(_mshift, _mwidth), \
86 .mux = SUNXI_CLK_MUX(_muxshift, _muxwidth), \ 119 .mux = _SUNXI_CCU_MUX_TABLE(_muxshift, _muxwidth, _table), \
87 .common = { \ 120 .common = { \
88 .reg = _reg, \ 121 .reg = _reg, \
89 .hw.init = CLK_HW_INIT_PARENTS(_name, \ 122 .hw.init = CLK_HW_INIT_PARENTS(_name, \
@@ -93,12 +126,23 @@ struct ccu_div {
93 }, \ 126 }, \
94 } 127 }
95 128
129#define SUNXI_CCU_M_WITH_MUX_GATE(_struct, _name, _parents, _reg, \
130 _mshift, _mwidth, _muxshift, _muxwidth, \
131 _gate, _flags) \
132 SUNXI_CCU_M_WITH_MUX_TABLE_GATE(_struct, _name, \
133 _parents, NULL, \
134 _reg, _mshift, _mwidth, \
135 _muxshift, _muxwidth, \
136 _gate, _flags)
137
96#define SUNXI_CCU_M_WITH_MUX(_struct, _name, _parents, _reg, \ 138#define SUNXI_CCU_M_WITH_MUX(_struct, _name, _parents, _reg, \
97 _mshift, _mwidth, _muxshift, _muxwidth, \ 139 _mshift, _mwidth, _muxshift, _muxwidth, \
98 _flags) \ 140 _flags) \
99 SUNXI_CCU_M_WITH_MUX_GATE(_struct, _name, _parents, _reg, \ 141 SUNXI_CCU_M_WITH_MUX_TABLE_GATE(_struct, _name, \
100 _mshift, _mwidth, _muxshift, _muxwidth, \ 142 _parents, NULL, \
101 0, _flags) 143 _reg, _mshift, _mwidth, \
144 _muxshift, _muxwidth, \
145 0, _flags)
102 146
103 147
104#define SUNXI_CCU_M_WITH_GATE(_struct, _name, _parent, _reg, \ 148#define SUNXI_CCU_M_WITH_GATE(_struct, _name, _parent, _reg, \
diff --git a/drivers/clk/sunxi-ng/ccu_mp.c b/drivers/clk/sunxi-ng/ccu_mp.c
index cbf33ef5faa9..ebb1b31568a5 100644
--- a/drivers/clk/sunxi-ng/ccu_mp.c
+++ b/drivers/clk/sunxi-ng/ccu_mp.c
@@ -21,9 +21,9 @@ static void ccu_mp_find_best(unsigned long parent, unsigned long rate,
21 unsigned int best_m = 0, best_p = 0; 21 unsigned int best_m = 0, best_p = 0;
22 unsigned int _m, _p; 22 unsigned int _m, _p;
23 23
24 for (_p = 0; _p <= max_p; _p++) { 24 for (_p = 1; _p <= max_p; _p <<= 1) {
25 for (_m = 1; _m <= max_m; _m++) { 25 for (_m = 1; _m <= max_m; _m++) {
26 unsigned long tmp_rate = (parent >> _p) / _m; 26 unsigned long tmp_rate = parent / _p / _m;
27 27
28 if (tmp_rate > rate) 28 if (tmp_rate > rate)
29 continue; 29 continue;
@@ -46,13 +46,15 @@ static unsigned long ccu_mp_round_rate(struct ccu_mux_internal *mux,
46 void *data) 46 void *data)
47{ 47{
48 struct ccu_mp *cmp = data; 48 struct ccu_mp *cmp = data;
49 unsigned int max_m, max_p;
49 unsigned int m, p; 50 unsigned int m, p;
50 51
51 ccu_mp_find_best(parent_rate, rate, 52 max_m = cmp->m.max ?: 1 << cmp->m.width;
52 1 << cmp->m.width, (1 << cmp->p.width) - 1, 53 max_p = cmp->p.max ?: 1 << ((1 << cmp->p.width) - 1);
53 &m, &p);
54 54
55 return (parent_rate >> p) / m; 55 ccu_mp_find_best(parent_rate, rate, max_m, max_p, &m, &p);
56
57 return parent_rate / p / m;
56} 58}
57 59
58static void ccu_mp_disable(struct clk_hw *hw) 60static void ccu_mp_disable(struct clk_hw *hw)
@@ -108,13 +110,14 @@ static int ccu_mp_set_rate(struct clk_hw *hw, unsigned long rate,
108{ 110{
109 struct ccu_mp *cmp = hw_to_ccu_mp(hw); 111 struct ccu_mp *cmp = hw_to_ccu_mp(hw);
110 unsigned long flags; 112 unsigned long flags;
113 unsigned int max_m, max_p;
111 unsigned int m, p; 114 unsigned int m, p;
112 u32 reg; 115 u32 reg;
113 116
114 ccu_mp_find_best(parent_rate, rate, 117 max_m = cmp->m.max ?: 1 << cmp->m.width;
115 1 << cmp->m.width, (1 << cmp->p.width) - 1, 118 max_p = cmp->p.max ?: 1 << ((1 << cmp->p.width) - 1);
116 &m, &p);
117 119
120 ccu_mp_find_best(parent_rate, rate, max_m, max_p, &m, &p);
118 121
119 spin_lock_irqsave(cmp->common.lock, flags); 122 spin_lock_irqsave(cmp->common.lock, flags);
120 123
@@ -122,7 +125,7 @@ static int ccu_mp_set_rate(struct clk_hw *hw, unsigned long rate,
122 reg &= ~GENMASK(cmp->m.width + cmp->m.shift - 1, cmp->m.shift); 125 reg &= ~GENMASK(cmp->m.width + cmp->m.shift - 1, cmp->m.shift);
123 reg &= ~GENMASK(cmp->p.width + cmp->p.shift - 1, cmp->p.shift); 126 reg &= ~GENMASK(cmp->p.width + cmp->p.shift - 1, cmp->p.shift);
124 127
125 writel(reg | (p << cmp->p.shift) | ((m - 1) << cmp->m.shift), 128 writel(reg | (ilog2(p) << cmp->p.shift) | ((m - 1) << cmp->m.shift),
126 cmp->common.base + cmp->common.reg); 129 cmp->common.base + cmp->common.reg);
127 130
128 spin_unlock_irqrestore(cmp->common.lock, flags); 131 spin_unlock_irqrestore(cmp->common.lock, flags);
diff --git a/drivers/clk/sunxi-ng/ccu_mp.h b/drivers/clk/sunxi-ng/ccu_mp.h
index 3cf12bf95962..edf9215ea8cc 100644
--- a/drivers/clk/sunxi-ng/ccu_mp.h
+++ b/drivers/clk/sunxi-ng/ccu_mp.h
@@ -44,7 +44,7 @@ struct ccu_mp {
44 .enable = _gate, \ 44 .enable = _gate, \
45 .m = _SUNXI_CCU_DIV(_mshift, _mwidth), \ 45 .m = _SUNXI_CCU_DIV(_mshift, _mwidth), \
46 .p = _SUNXI_CCU_DIV(_pshift, _pwidth), \ 46 .p = _SUNXI_CCU_DIV(_pshift, _pwidth), \
47 .mux = SUNXI_CLK_MUX(_muxshift, _muxwidth), \ 47 .mux = _SUNXI_CCU_MUX(_muxshift, _muxwidth), \
48 .common = { \ 48 .common = { \
49 .reg = _reg, \ 49 .reg = _reg, \
50 .hw.init = CLK_HW_INIT_PARENTS(_name, \ 50 .hw.init = CLK_HW_INIT_PARENTS(_name, \
diff --git a/drivers/clk/sunxi-ng/ccu_mult.c b/drivers/clk/sunxi-ng/ccu_mult.c
new file mode 100644
index 000000000000..010e9424691d
--- /dev/null
+++ b/drivers/clk/sunxi-ng/ccu_mult.c
@@ -0,0 +1,133 @@
1/*
2 * Copyright (C) 2016 Maxime Ripard
3 * Maxime Ripard <maxime.ripard@free-electrons.com>
4 *
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License as
7 * published by the Free Software Foundation; either version 2 of
8 * the License, or (at your option) any later version.
9 */
10
11#include <linux/clk-provider.h>
12
13#include "ccu_gate.h"
14#include "ccu_mult.h"
15
16static void ccu_mult_find_best(unsigned long parent, unsigned long rate,
17 unsigned int max_n, unsigned int *n)
18{
19 *n = rate / parent;
20}
21
22static unsigned long ccu_mult_round_rate(struct ccu_mux_internal *mux,
23 unsigned long parent_rate,
24 unsigned long rate,
25 void *data)
26{
27 struct ccu_mult *cm = data;
28 unsigned int n;
29
30 ccu_mult_find_best(parent_rate, rate, 1 << cm->mult.width, &n);
31
32 return parent_rate * n;
33}
34
35static void ccu_mult_disable(struct clk_hw *hw)
36{
37 struct ccu_mult *cm = hw_to_ccu_mult(hw);
38
39 return ccu_gate_helper_disable(&cm->common, cm->enable);
40}
41
42static int ccu_mult_enable(struct clk_hw *hw)
43{
44 struct ccu_mult *cm = hw_to_ccu_mult(hw);
45
46 return ccu_gate_helper_enable(&cm->common, cm->enable);
47}
48
49static int ccu_mult_is_enabled(struct clk_hw *hw)
50{
51 struct ccu_mult *cm = hw_to_ccu_mult(hw);
52
53 return ccu_gate_helper_is_enabled(&cm->common, cm->enable);
54}
55
56static unsigned long ccu_mult_recalc_rate(struct clk_hw *hw,
57 unsigned long parent_rate)
58{
59 struct ccu_mult *cm = hw_to_ccu_mult(hw);
60 unsigned long val;
61 u32 reg;
62
63 reg = readl(cm->common.base + cm->common.reg);
64 val = reg >> cm->mult.shift;
65 val &= (1 << cm->mult.width) - 1;
66
67 ccu_mux_helper_adjust_parent_for_prediv(&cm->common, &cm->mux, -1,
68 &parent_rate);
69
70 return parent_rate * (val + 1);
71}
72
73static int ccu_mult_determine_rate(struct clk_hw *hw,
74 struct clk_rate_request *req)
75{
76 struct ccu_mult *cm = hw_to_ccu_mult(hw);
77
78 return ccu_mux_helper_determine_rate(&cm->common, &cm->mux,
79 req, ccu_mult_round_rate, cm);
80}
81
82static int ccu_mult_set_rate(struct clk_hw *hw, unsigned long rate,
83 unsigned long parent_rate)
84{
85 struct ccu_mult *cm = hw_to_ccu_mult(hw);
86 unsigned long flags;
87 unsigned int n;
88 u32 reg;
89
90 ccu_mux_helper_adjust_parent_for_prediv(&cm->common, &cm->mux, -1,
91 &parent_rate);
92
93 ccu_mult_find_best(parent_rate, rate, 1 << cm->mult.width, &n);
94
95 spin_lock_irqsave(cm->common.lock, flags);
96
97 reg = readl(cm->common.base + cm->common.reg);
98 reg &= ~GENMASK(cm->mult.width + cm->mult.shift - 1, cm->mult.shift);
99
100 writel(reg | ((n - 1) << cm->mult.shift),
101 cm->common.base + cm->common.reg);
102
103 spin_unlock_irqrestore(cm->common.lock, flags);
104
105 return 0;
106}
107
108static u8 ccu_mult_get_parent(struct clk_hw *hw)
109{
110 struct ccu_mult *cm = hw_to_ccu_mult(hw);
111
112 return ccu_mux_helper_get_parent(&cm->common, &cm->mux);
113}
114
115static int ccu_mult_set_parent(struct clk_hw *hw, u8 index)
116{
117 struct ccu_mult *cm = hw_to_ccu_mult(hw);
118
119 return ccu_mux_helper_set_parent(&cm->common, &cm->mux, index);
120}
121
122const struct clk_ops ccu_mult_ops = {
123 .disable = ccu_mult_disable,
124 .enable = ccu_mult_enable,
125 .is_enabled = ccu_mult_is_enabled,
126
127 .get_parent = ccu_mult_get_parent,
128 .set_parent = ccu_mult_set_parent,
129
130 .determine_rate = ccu_mult_determine_rate,
131 .recalc_rate = ccu_mult_recalc_rate,
132 .set_rate = ccu_mult_set_rate,
133};
diff --git a/drivers/clk/sunxi-ng/ccu_mult.h b/drivers/clk/sunxi-ng/ccu_mult.h
index 609db6610880..5d2c8dc14073 100644
--- a/drivers/clk/sunxi-ng/ccu_mult.h
+++ b/drivers/clk/sunxi-ng/ccu_mult.h
@@ -1,6 +1,9 @@
1#ifndef _CCU_MULT_H_ 1#ifndef _CCU_MULT_H_
2#define _CCU_MULT_H_ 2#define _CCU_MULT_H_
3 3
4#include "ccu_common.h"
5#include "ccu_mux.h"
6
4struct _ccu_mult { 7struct _ccu_mult {
5 u8 shift; 8 u8 shift;
6 u8 width; 9 u8 width;
@@ -12,4 +15,36 @@ struct _ccu_mult {
12 .width = _width, \ 15 .width = _width, \
13 } 16 }
14 17
18struct ccu_mult {
19 u32 enable;
20
21 struct _ccu_mult mult;
22 struct ccu_mux_internal mux;
23 struct ccu_common common;
24};
25
26#define SUNXI_CCU_N_WITH_GATE_LOCK(_struct, _name, _parent, _reg, \
27 _mshift, _mwidth, _gate, _lock, \
28 _flags) \
29 struct ccu_mult _struct = { \
30 .enable = _gate, \
31 .mult = _SUNXI_CCU_MULT(_mshift, _mwidth), \
32 .common = { \
33 .reg = _reg, \
34 .hw.init = CLK_HW_INIT(_name, \
35 _parent, \
36 &ccu_mult_ops, \
37 _flags), \
38 }, \
39 }
40
41static inline struct ccu_mult *hw_to_ccu_mult(struct clk_hw *hw)
42{
43 struct ccu_common *common = hw_to_ccu_common(hw);
44
45 return container_of(common, struct ccu_mult, common);
46}
47
48extern const struct clk_ops ccu_mult_ops;
49
15#endif /* _CCU_MULT_H_ */ 50#endif /* _CCU_MULT_H_ */
diff --git a/drivers/clk/sunxi-ng/ccu_mux.c b/drivers/clk/sunxi-ng/ccu_mux.c
index 58fc36e7dcce..a43ad52a957d 100644
--- a/drivers/clk/sunxi-ng/ccu_mux.c
+++ b/drivers/clk/sunxi-ng/ccu_mux.c
@@ -8,7 +8,9 @@
8 * the License, or (at your option) any later version. 8 * the License, or (at your option) any later version.
9 */ 9 */
10 10
11#include <linux/clk.h>
11#include <linux/clk-provider.h> 12#include <linux/clk-provider.h>
13#include <linux/delay.h>
12 14
13#include "ccu_gate.h" 15#include "ccu_gate.h"
14#include "ccu_mux.h" 16#include "ccu_mux.h"
@@ -18,8 +20,9 @@ void ccu_mux_helper_adjust_parent_for_prediv(struct ccu_common *common,
18 int parent_index, 20 int parent_index,
19 unsigned long *parent_rate) 21 unsigned long *parent_rate)
20{ 22{
21 u8 prediv = 1; 23 u16 prediv = 1;
22 u32 reg; 24 u32 reg;
25 int i;
23 26
24 if (!((common->features & CCU_FEATURE_FIXED_PREDIV) || 27 if (!((common->features & CCU_FEATURE_FIXED_PREDIV) ||
25 (common->features & CCU_FEATURE_VARIABLE_PREDIV))) 28 (common->features & CCU_FEATURE_VARIABLE_PREDIV)))
@@ -32,8 +35,9 @@ void ccu_mux_helper_adjust_parent_for_prediv(struct ccu_common *common,
32 } 35 }
33 36
34 if (common->features & CCU_FEATURE_FIXED_PREDIV) 37 if (common->features & CCU_FEATURE_FIXED_PREDIV)
35 if (parent_index == cm->fixed_prediv.index) 38 for (i = 0; i < cm->n_predivs; i++)
36 prediv = cm->fixed_prediv.div; 39 if (parent_index == cm->fixed_predivs[i].index)
40 prediv = cm->fixed_predivs[i].div;
37 41
38 if (common->features & CCU_FEATURE_VARIABLE_PREDIV) 42 if (common->features & CCU_FEATURE_VARIABLE_PREDIV)
39 if (parent_index == cm->variable_prediv.index) { 43 if (parent_index == cm->variable_prediv.index) {
@@ -107,6 +111,15 @@ u8 ccu_mux_helper_get_parent(struct ccu_common *common,
107 parent = reg >> cm->shift; 111 parent = reg >> cm->shift;
108 parent &= (1 << cm->width) - 1; 112 parent &= (1 << cm->width) - 1;
109 113
114 if (cm->table) {
115 int num_parents = clk_hw_get_num_parents(&common->hw);
116 int i;
117
118 for (i = 0; i < num_parents; i++)
119 if (cm->table[i] == parent)
120 return i;
121 }
122
110 return parent; 123 return parent;
111} 124}
112 125
@@ -117,6 +130,9 @@ int ccu_mux_helper_set_parent(struct ccu_common *common,
117 unsigned long flags; 130 unsigned long flags;
118 u32 reg; 131 u32 reg;
119 132
133 if (cm->table)
134 index = cm->table[index];
135
120 spin_lock_irqsave(common->lock, flags); 136 spin_lock_irqsave(common->lock, flags);
121 137
122 reg = readl(common->base + common->reg); 138 reg = readl(common->base + common->reg);
@@ -185,3 +201,37 @@ const struct clk_ops ccu_mux_ops = {
185 .determine_rate = __clk_mux_determine_rate, 201 .determine_rate = __clk_mux_determine_rate,
186 .recalc_rate = ccu_mux_recalc_rate, 202 .recalc_rate = ccu_mux_recalc_rate,
187}; 203};
204
205/*
206 * This clock notifier is called when the frequency of the of the parent
207 * PLL clock is to be changed. The idea is to switch the parent to a
208 * stable clock, such as the main oscillator, while the PLL frequency
209 * stabilizes.
210 */
211static int ccu_mux_notifier_cb(struct notifier_block *nb,
212 unsigned long event, void *data)
213{
214 struct ccu_mux_nb *mux = to_ccu_mux_nb(nb);
215 int ret = 0;
216
217 if (event == PRE_RATE_CHANGE) {
218 mux->original_index = ccu_mux_helper_get_parent(mux->common,
219 mux->cm);
220 ret = ccu_mux_helper_set_parent(mux->common, mux->cm,
221 mux->bypass_index);
222 } else if (event == POST_RATE_CHANGE) {
223 ret = ccu_mux_helper_set_parent(mux->common, mux->cm,
224 mux->original_index);
225 }
226
227 udelay(mux->delay_us);
228
229 return notifier_from_errno(ret);
230}
231
232int ccu_mux_notifier_register(struct clk *clk, struct ccu_mux_nb *mux_nb)
233{
234 mux_nb->clk_nb.notifier_call = ccu_mux_notifier_cb;
235
236 return clk_notifier_register(clk, &mux_nb->clk_nb);
237}
diff --git a/drivers/clk/sunxi-ng/ccu_mux.h b/drivers/clk/sunxi-ng/ccu_mux.h
index 945082631e7d..47aba3a48245 100644
--- a/drivers/clk/sunxi-ng/ccu_mux.h
+++ b/drivers/clk/sunxi-ng/ccu_mux.h
@@ -5,14 +5,18 @@
5 5
6#include "ccu_common.h" 6#include "ccu_common.h"
7 7
8struct ccu_mux_fixed_prediv {
9 u8 index;
10 u16 div;
11};
12
8struct ccu_mux_internal { 13struct ccu_mux_internal {
9 u8 shift; 14 u8 shift;
10 u8 width; 15 u8 width;
16 const u8 *table;
11 17
12 struct { 18 const struct ccu_mux_fixed_prediv *fixed_predivs;
13 u8 index; 19 u8 n_predivs;
14 u8 div;
15 } fixed_prediv;
16 20
17 struct { 21 struct {
18 u8 index; 22 u8 index;
@@ -21,12 +25,16 @@ struct ccu_mux_internal {
21 } variable_prediv; 25 } variable_prediv;
22}; 26};
23 27
24#define SUNXI_CLK_MUX(_shift, _width) \ 28#define _SUNXI_CCU_MUX_TABLE(_shift, _width, _table) \
25 { \ 29 { \
26 .shift = _shift, \ 30 .shift = _shift, \
27 .width = _width, \ 31 .width = _width, \
32 .table = _table, \
28 } 33 }
29 34
35#define _SUNXI_CCU_MUX(_shift, _width) \
36 _SUNXI_CCU_MUX_TABLE(_shift, _width, NULL)
37
30struct ccu_mux { 38struct ccu_mux {
31 u16 reg; 39 u16 reg;
32 u32 enable; 40 u32 enable;
@@ -35,9 +43,12 @@ struct ccu_mux {
35 struct ccu_common common; 43 struct ccu_common common;
36}; 44};
37 45
38#define SUNXI_CCU_MUX(_struct, _name, _parents, _reg, _shift, _width, _flags) \ 46#define SUNXI_CCU_MUX_TABLE_WITH_GATE(_struct, _name, _parents, _table, \
47 _reg, _shift, _width, _gate, \
48 _flags) \
39 struct ccu_mux _struct = { \ 49 struct ccu_mux _struct = { \
40 .mux = SUNXI_CLK_MUX(_shift, _width), \ 50 .enable = _gate, \
51 .mux = _SUNXI_CCU_MUX_TABLE(_shift, _width, _table), \
41 .common = { \ 52 .common = { \
42 .reg = _reg, \ 53 .reg = _reg, \
43 .hw.init = CLK_HW_INIT_PARENTS(_name, \ 54 .hw.init = CLK_HW_INIT_PARENTS(_name, \
@@ -49,17 +60,14 @@ struct ccu_mux {
49 60
50#define SUNXI_CCU_MUX_WITH_GATE(_struct, _name, _parents, _reg, \ 61#define SUNXI_CCU_MUX_WITH_GATE(_struct, _name, _parents, _reg, \
51 _shift, _width, _gate, _flags) \ 62 _shift, _width, _gate, _flags) \
52 struct ccu_mux _struct = { \ 63 SUNXI_CCU_MUX_TABLE_WITH_GATE(_struct, _name, _parents, NULL, \
53 .enable = _gate, \ 64 _reg, _shift, _width, _gate, \
54 .mux = SUNXI_CLK_MUX(_shift, _width), \ 65 _flags)
55 .common = { \ 66
56 .reg = _reg, \ 67#define SUNXI_CCU_MUX(_struct, _name, _parents, _reg, _shift, _width, \
57 .hw.init = CLK_HW_INIT_PARENTS(_name, \ 68 _flags) \
58 _parents, \ 69 SUNXI_CCU_MUX_TABLE_WITH_GATE(_struct, _name, _parents, NULL, \
59 &ccu_mux_ops, \ 70 _reg, _shift, _width, 0, _flags)
60 _flags), \
61 } \
62 }
63 71
64static inline struct ccu_mux *hw_to_ccu_mux(struct clk_hw *hw) 72static inline struct ccu_mux *hw_to_ccu_mux(struct clk_hw *hw)
65{ 73{
@@ -88,4 +96,18 @@ int ccu_mux_helper_set_parent(struct ccu_common *common,
88 struct ccu_mux_internal *cm, 96 struct ccu_mux_internal *cm,
89 u8 index); 97 u8 index);
90 98
99struct ccu_mux_nb {
100 struct notifier_block clk_nb;
101 struct ccu_common *common;
102 struct ccu_mux_internal *cm;
103
104 u32 delay_us; /* How many us to wait after reparenting */
105 u8 bypass_index; /* Which parent to temporarily use */
106 u8 original_index; /* This is set by the notifier callback */
107};
108
109#define to_ccu_mux_nb(_nb) container_of(_nb, struct ccu_mux_nb, clk_nb)
110
111int ccu_mux_notifier_register(struct clk *clk, struct ccu_mux_nb *mux_nb);
112
91#endif /* _CCU_MUX_H_ */ 113#endif /* _CCU_MUX_H_ */
diff --git a/drivers/clk/sunxi-ng/ccu_nkm.c b/drivers/clk/sunxi-ng/ccu_nkm.c
index 2071822b1e9c..059fdc3b4f96 100644
--- a/drivers/clk/sunxi-ng/ccu_nkm.c
+++ b/drivers/clk/sunxi-ng/ccu_nkm.c
@@ -93,19 +93,30 @@ static unsigned long ccu_nkm_recalc_rate(struct clk_hw *hw,
93 return parent_rate * (n + 1) * (k + 1) / (m + 1); 93 return parent_rate * (n + 1) * (k + 1) / (m + 1);
94} 94}
95 95
96static long ccu_nkm_round_rate(struct clk_hw *hw, unsigned long rate, 96static unsigned long ccu_nkm_round_rate(struct ccu_mux_internal *mux,
97 unsigned long *parent_rate) 97 unsigned long parent_rate,
98 unsigned long rate,
99 void *data)
98{ 100{
99 struct ccu_nkm *nkm = hw_to_ccu_nkm(hw); 101 struct ccu_nkm *nkm = data;
100 struct _ccu_nkm _nkm; 102 struct _ccu_nkm _nkm;
101 103
102 _nkm.max_n = 1 << nkm->n.width; 104 _nkm.max_n = 1 << nkm->n.width;
103 _nkm.max_k = 1 << nkm->k.width; 105 _nkm.max_k = 1 << nkm->k.width;
104 _nkm.max_m = 1 << nkm->m.width; 106 _nkm.max_m = nkm->m.max ?: 1 << nkm->m.width;
105 107
106 ccu_nkm_find_best(*parent_rate, rate, &_nkm); 108 ccu_nkm_find_best(parent_rate, rate, &_nkm);
107 109
108 return *parent_rate * _nkm.n * _nkm.k / _nkm.m; 110 return parent_rate * _nkm.n * _nkm.k / _nkm.m;
111}
112
113static int ccu_nkm_determine_rate(struct clk_hw *hw,
114 struct clk_rate_request *req)
115{
116 struct ccu_nkm *nkm = hw_to_ccu_nkm(hw);
117
118 return ccu_mux_helper_determine_rate(&nkm->common, &nkm->mux,
119 req, ccu_nkm_round_rate, nkm);
109} 120}
110 121
111static int ccu_nkm_set_rate(struct clk_hw *hw, unsigned long rate, 122static int ccu_nkm_set_rate(struct clk_hw *hw, unsigned long rate,
@@ -118,7 +129,7 @@ static int ccu_nkm_set_rate(struct clk_hw *hw, unsigned long rate,
118 129
119 _nkm.max_n = 1 << nkm->n.width; 130 _nkm.max_n = 1 << nkm->n.width;
120 _nkm.max_k = 1 << nkm->k.width; 131 _nkm.max_k = 1 << nkm->k.width;
121 _nkm.max_m = 1 << nkm->m.width; 132 _nkm.max_m = nkm->m.max ?: 1 << nkm->m.width;
122 133
123 ccu_nkm_find_best(parent_rate, rate, &_nkm); 134 ccu_nkm_find_best(parent_rate, rate, &_nkm);
124 135
@@ -142,12 +153,29 @@ static int ccu_nkm_set_rate(struct clk_hw *hw, unsigned long rate,
142 return 0; 153 return 0;
143} 154}
144 155
156static u8 ccu_nkm_get_parent(struct clk_hw *hw)
157{
158 struct ccu_nkm *nkm = hw_to_ccu_nkm(hw);
159
160 return ccu_mux_helper_get_parent(&nkm->common, &nkm->mux);
161}
162
163static int ccu_nkm_set_parent(struct clk_hw *hw, u8 index)
164{
165 struct ccu_nkm *nkm = hw_to_ccu_nkm(hw);
166
167 return ccu_mux_helper_set_parent(&nkm->common, &nkm->mux, index);
168}
169
145const struct clk_ops ccu_nkm_ops = { 170const struct clk_ops ccu_nkm_ops = {
146 .disable = ccu_nkm_disable, 171 .disable = ccu_nkm_disable,
147 .enable = ccu_nkm_enable, 172 .enable = ccu_nkm_enable,
148 .is_enabled = ccu_nkm_is_enabled, 173 .is_enabled = ccu_nkm_is_enabled,
149 174
175 .get_parent = ccu_nkm_get_parent,
176 .set_parent = ccu_nkm_set_parent,
177
178 .determine_rate = ccu_nkm_determine_rate,
150 .recalc_rate = ccu_nkm_recalc_rate, 179 .recalc_rate = ccu_nkm_recalc_rate,
151 .round_rate = ccu_nkm_round_rate,
152 .set_rate = ccu_nkm_set_rate, 180 .set_rate = ccu_nkm_set_rate,
153}; 181};
diff --git a/drivers/clk/sunxi-ng/ccu_nkm.h b/drivers/clk/sunxi-ng/ccu_nkm.h
index 1936ac1c6b37..35493fddd8ab 100644
--- a/drivers/clk/sunxi-ng/ccu_nkm.h
+++ b/drivers/clk/sunxi-ng/ccu_nkm.h
@@ -32,10 +32,33 @@ struct ccu_nkm {
32 struct _ccu_mult n; 32 struct _ccu_mult n;
33 struct _ccu_mult k; 33 struct _ccu_mult k;
34 struct _ccu_div m; 34 struct _ccu_div m;
35 struct ccu_mux_internal mux;
35 36
36 struct ccu_common common; 37 struct ccu_common common;
37}; 38};
38 39
40#define SUNXI_CCU_NKM_WITH_MUX_GATE_LOCK(_struct, _name, _parents, _reg, \
41 _nshift, _nwidth, \
42 _kshift, _kwidth, \
43 _mshift, _mwidth, \
44 _muxshift, _muxwidth, \
45 _gate, _lock, _flags) \
46 struct ccu_nkm _struct = { \
47 .enable = _gate, \
48 .lock = _lock, \
49 .k = _SUNXI_CCU_MULT(_kshift, _kwidth), \
50 .n = _SUNXI_CCU_MULT(_nshift, _nwidth), \
51 .m = _SUNXI_CCU_DIV(_mshift, _mwidth), \
52 .mux = _SUNXI_CCU_MUX(_muxshift, _muxwidth), \
53 .common = { \
54 .reg = _reg, \
55 .hw.init = CLK_HW_INIT_PARENTS(_name, \
56 _parents, \
57 &ccu_nkm_ops, \
58 _flags), \
59 }, \
60 }
61
39#define SUNXI_CCU_NKM_WITH_GATE_LOCK(_struct, _name, _parent, _reg, \ 62#define SUNXI_CCU_NKM_WITH_GATE_LOCK(_struct, _name, _parent, _reg, \
40 _nshift, _nwidth, \ 63 _nshift, _nwidth, \
41 _kshift, _kwidth, \ 64 _kshift, _kwidth, \
diff --git a/drivers/clk/sunxi-ng/ccu_nkmp.c b/drivers/clk/sunxi-ng/ccu_nkmp.c
index 9f2b98e19dc9..9769dee99511 100644
--- a/drivers/clk/sunxi-ng/ccu_nkmp.c
+++ b/drivers/clk/sunxi-ng/ccu_nkmp.c
@@ -29,14 +29,14 @@ static void ccu_nkmp_find_best(unsigned long parent, unsigned long rate,
29 unsigned long _n, _k, _m, _p; 29 unsigned long _n, _k, _m, _p;
30 30
31 for (_k = 1; _k <= nkmp->max_k; _k++) { 31 for (_k = 1; _k <= nkmp->max_k; _k++) {
32 for (_p = 0; _p <= nkmp->max_p; _p++) { 32 for (_p = 1; _p <= nkmp->max_p; _p <<= 1) {
33 unsigned long tmp_rate; 33 unsigned long tmp_rate;
34 34
35 rational_best_approximation(rate / _k, parent >> _p, 35 rational_best_approximation(rate / _k, parent / _p,
36 nkmp->max_n, nkmp->max_m, 36 nkmp->max_n, nkmp->max_m,
37 &_n, &_m); 37 &_n, &_m);
38 38
39 tmp_rate = (parent * _n * _k >> _p) / _m; 39 tmp_rate = parent * _n * _k / (_m * _p);
40 40
41 if (tmp_rate > rate) 41 if (tmp_rate > rate)
42 continue; 42 continue;
@@ -110,13 +110,12 @@ static long ccu_nkmp_round_rate(struct clk_hw *hw, unsigned long rate,
110 110
111 _nkmp.max_n = 1 << nkmp->n.width; 111 _nkmp.max_n = 1 << nkmp->n.width;
112 _nkmp.max_k = 1 << nkmp->k.width; 112 _nkmp.max_k = 1 << nkmp->k.width;
113 _nkmp.max_m = 1 << nkmp->m.width; 113 _nkmp.max_m = nkmp->m.max ?: 1 << nkmp->m.width;
114 _nkmp.max_p = (1 << nkmp->p.width) - 1; 114 _nkmp.max_p = nkmp->p.max ?: 1 << ((1 << nkmp->p.width) - 1);
115 115
116 ccu_nkmp_find_best(*parent_rate, rate, 116 ccu_nkmp_find_best(*parent_rate, rate, &_nkmp);
117 &_nkmp);
118 117
119 return (*parent_rate * _nkmp.n * _nkmp.k >> _nkmp.p) / _nkmp.m; 118 return *parent_rate * _nkmp.n * _nkmp.k / (_nkmp.m * _nkmp.p);
120} 119}
121 120
122static int ccu_nkmp_set_rate(struct clk_hw *hw, unsigned long rate, 121static int ccu_nkmp_set_rate(struct clk_hw *hw, unsigned long rate,
@@ -129,8 +128,8 @@ static int ccu_nkmp_set_rate(struct clk_hw *hw, unsigned long rate,
129 128
130 _nkmp.max_n = 1 << nkmp->n.width; 129 _nkmp.max_n = 1 << nkmp->n.width;
131 _nkmp.max_k = 1 << nkmp->k.width; 130 _nkmp.max_k = 1 << nkmp->k.width;
132 _nkmp.max_m = 1 << nkmp->m.width; 131 _nkmp.max_m = nkmp->m.max ?: 1 << nkmp->m.width;
133 _nkmp.max_p = (1 << nkmp->p.width) - 1; 132 _nkmp.max_p = nkmp->p.max ?: 1 << ((1 << nkmp->p.width) - 1);
134 133
135 ccu_nkmp_find_best(parent_rate, rate, &_nkmp); 134 ccu_nkmp_find_best(parent_rate, rate, &_nkmp);
136 135
@@ -145,7 +144,7 @@ static int ccu_nkmp_set_rate(struct clk_hw *hw, unsigned long rate,
145 reg |= (_nkmp.n - 1) << nkmp->n.shift; 144 reg |= (_nkmp.n - 1) << nkmp->n.shift;
146 reg |= (_nkmp.k - 1) << nkmp->k.shift; 145 reg |= (_nkmp.k - 1) << nkmp->k.shift;
147 reg |= (_nkmp.m - 1) << nkmp->m.shift; 146 reg |= (_nkmp.m - 1) << nkmp->m.shift;
148 reg |= _nkmp.p << nkmp->p.shift; 147 reg |= ilog2(_nkmp.p) << nkmp->p.shift;
149 148
150 writel(reg, nkmp->common.base + nkmp->common.reg); 149 writel(reg, nkmp->common.base + nkmp->common.reg);
151 150
diff --git a/drivers/clk/sunxi-ng/ccu_nm.c b/drivers/clk/sunxi-ng/ccu_nm.c
index e35ddd8eec8b..b61bdd8c7a7f 100644
--- a/drivers/clk/sunxi-ng/ccu_nm.c
+++ b/drivers/clk/sunxi-ng/ccu_nm.c
@@ -61,11 +61,13 @@ static long ccu_nm_round_rate(struct clk_hw *hw, unsigned long rate,
61 unsigned long *parent_rate) 61 unsigned long *parent_rate)
62{ 62{
63 struct ccu_nm *nm = hw_to_ccu_nm(hw); 63 struct ccu_nm *nm = hw_to_ccu_nm(hw);
64 unsigned long max_n, max_m;
64 unsigned long n, m; 65 unsigned long n, m;
65 66
66 rational_best_approximation(rate, *parent_rate, 67 max_n = 1 << nm->n.width;
67 1 << nm->n.width, 1 << nm->m.width, 68 max_m = nm->m.max ?: 1 << nm->m.width;
68 &n, &m); 69
70 rational_best_approximation(rate, *parent_rate, max_n, max_m, &n, &m);
69 71
70 return *parent_rate * n / m; 72 return *parent_rate * n / m;
71} 73}
@@ -75,6 +77,7 @@ static int ccu_nm_set_rate(struct clk_hw *hw, unsigned long rate,
75{ 77{
76 struct ccu_nm *nm = hw_to_ccu_nm(hw); 78 struct ccu_nm *nm = hw_to_ccu_nm(hw);
77 unsigned long flags; 79 unsigned long flags;
80 unsigned long max_n, max_m;
78 unsigned long n, m; 81 unsigned long n, m;
79 u32 reg; 82 u32 reg;
80 83
@@ -83,9 +86,10 @@ static int ccu_nm_set_rate(struct clk_hw *hw, unsigned long rate,
83 else 86 else
84 ccu_frac_helper_disable(&nm->common, &nm->frac); 87 ccu_frac_helper_disable(&nm->common, &nm->frac);
85 88
86 rational_best_approximation(rate, parent_rate, 89 max_n = 1 << nm->n.width;
87 1 << nm->n.width, 1 << nm->m.width, 90 max_m = nm->m.max ?: 1 << nm->m.width;
88 &n, &m); 91
92 rational_best_approximation(rate, parent_rate, max_n, max_m, &n, &m);
89 93
90 spin_lock_irqsave(nm->common.lock, flags); 94 spin_lock_irqsave(nm->common.lock, flags);
91 95
diff --git a/include/dt-bindings/clock/sun6i-a31-ccu.h b/include/dt-bindings/clock/sun6i-a31-ccu.h
new file mode 100644
index 000000000000..4482530fb6f5
--- /dev/null
+++ b/include/dt-bindings/clock/sun6i-a31-ccu.h
@@ -0,0 +1,187 @@
1/*
2 * Copyright (C) 2016 Chen-Yu Tsai <wens@csie.org>
3 *
4 * This file is dual-licensed: you can use it either under the terms
5 * of the GPL or the X11 license, at your option. Note that this dual
6 * licensing only applies to this file, and not this project as a
7 * whole.
8 *
9 * a) This file is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU General Public License as
11 * published by the Free Software Foundation; either version 2 of the
12 * License, or (at your option) any later version.
13 *
14 * This file is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * Or, alternatively,
20 *
21 * b) Permission is hereby granted, free of charge, to any person
22 * obtaining a copy of this software and associated documentation
23 * files (the "Software"), to deal in the Software without
24 * restriction, including without limitation the rights to use,
25 * copy, modify, merge, publish, distribute, sublicense, and/or
26 * sell copies of the Software, and to permit persons to whom the
27 * Software is furnished to do so, subject to the following
28 * conditions:
29 *
30 * The above copyright notice and this permission notice shall be
31 * included in all copies or substantial portions of the Software.
32 *
33 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
34 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
35 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
36 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
37 * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
38 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
39 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
40 * OTHER DEALINGS IN THE SOFTWARE.
41 */
42
43#ifndef _DT_BINDINGS_CLK_SUN6I_A31_H_
44#define _DT_BINDINGS_CLK_SUN6I_A31_H_
45
46#define CLK_PLL_PERIPH 10
47
48#define CLK_CPU 18
49
50#define CLK_AHB1_MIPIDSI 23
51#define CLK_AHB1_SS 24
52#define CLK_AHB1_DMA 25
53#define CLK_AHB1_MMC0 26
54#define CLK_AHB1_MMC1 27
55#define CLK_AHB1_MMC2 28
56#define CLK_AHB1_MMC3 29
57#define CLK_AHB1_NAND1 30
58#define CLK_AHB1_NAND0 31
59#define CLK_AHB1_SDRAM 32
60#define CLK_AHB1_EMAC 33
61#define CLK_AHB1_TS 34
62#define CLK_AHB1_HSTIMER 35
63#define CLK_AHB1_SPI0 36
64#define CLK_AHB1_SPI1 37
65#define CLK_AHB1_SPI2 38
66#define CLK_AHB1_SPI3 39
67#define CLK_AHB1_OTG 40
68#define CLK_AHB1_EHCI0 41
69#define CLK_AHB1_EHCI1 42
70#define CLK_AHB1_OHCI0 43
71#define CLK_AHB1_OHCI1 44
72#define CLK_AHB1_OHCI2 45
73#define CLK_AHB1_VE 46
74#define CLK_AHB1_LCD0 47
75#define CLK_AHB1_LCD1 48
76#define CLK_AHB1_CSI 49
77#define CLK_AHB1_HDMI 50
78#define CLK_AHB1_BE0 51
79#define CLK_AHB1_BE1 52
80#define CLK_AHB1_FE0 53
81#define CLK_AHB1_FE1 54
82#define CLK_AHB1_MP 55
83#define CLK_AHB1_GPU 56
84#define CLK_AHB1_DEU0 57
85#define CLK_AHB1_DEU1 58
86#define CLK_AHB1_DRC0 59
87#define CLK_AHB1_DRC1 60
88
89#define CLK_APB1_CODEC 61
90#define CLK_APB1_SPDIF 62
91#define CLK_APB1_DIGITAL_MIC 63
92#define CLK_APB1_PIO 64
93#define CLK_APB1_DAUDIO0 65
94#define CLK_APB1_DAUDIO1 66
95
96#define CLK_APB2_I2C0 67
97#define CLK_APB2_I2C1 68
98#define CLK_APB2_I2C2 69
99#define CLK_APB2_I2C3 70
100#define CLK_APB2_UART0 71
101#define CLK_APB2_UART1 72
102#define CLK_APB2_UART2 73
103#define CLK_APB2_UART3 74
104#define CLK_APB2_UART4 75
105#define CLK_APB2_UART5 76
106
107#define CLK_NAND0 77
108#define CLK_NAND1 78
109#define CLK_MMC0 79
110#define CLK_MMC0_SAMPLE 80
111#define CLK_MMC0_OUTPUT 81
112#define CLK_MMC1 82
113#define CLK_MMC1_SAMPLE 83
114#define CLK_MMC1_OUTPUT 84
115#define CLK_MMC2 85
116#define CLK_MMC2_SAMPLE 86
117#define CLK_MMC2_OUTPUT 87
118#define CLK_MMC3 88
119#define CLK_MMC3_SAMPLE 89
120#define CLK_MMC3_OUTPUT 90
121#define CLK_TS 91
122#define CLK_SS 92
123#define CLK_SPI0 93
124#define CLK_SPI1 94
125#define CLK_SPI2 95
126#define CLK_SPI3 96
127#define CLK_DAUDIO0 97
128#define CLK_DAUDIO1 98
129#define CLK_SPDIF 99
130#define CLK_USB_PHY0 100
131#define CLK_USB_PHY1 101
132#define CLK_USB_PHY2 102
133#define CLK_USB_OHCI0 103
134#define CLK_USB_OHCI1 104
135#define CLK_USB_OHCI2 105
136
137#define CLK_DRAM_VE 110
138#define CLK_DRAM_CSI_ISP 111
139#define CLK_DRAM_TS 112
140#define CLK_DRAM_DRC0 113
141#define CLK_DRAM_DRC1 114
142#define CLK_DRAM_DEU0 115
143#define CLK_DRAM_DEU1 116
144#define CLK_DRAM_FE0 117
145#define CLK_DRAM_FE1 118
146#define CLK_DRAM_BE0 119
147#define CLK_DRAM_BE1 120
148#define CLK_DRAM_MP 121
149
150#define CLK_BE0 122
151#define CLK_BE1 123
152#define CLK_FE0 124
153#define CLK_FE1 125
154#define CLK_MP 126
155#define CLK_LCD0_CH0 127
156#define CLK_LCD1_CH0 128
157#define CLK_LCD0_CH1 129
158#define CLK_LCD1_CH1 130
159#define CLK_CSI0_SCLK 131
160#define CLK_CSI0_MCLK 132
161#define CLK_CSI1_MCLK 133
162#define CLK_VE 134
163#define CLK_CODEC 135
164#define CLK_AVS 136
165#define CLK_DIGITAL_MIC 137
166#define CLK_HDMI 138
167#define CLK_HDMI_DDC 139
168#define CLK_PS 140
169
170#define CLK_MIPI_DSI 143
171#define CLK_MIPI_DSI_DPHY 144
172#define CLK_MIPI_CSI_DPHY 145
173#define CLK_IEP_DRC0 146
174#define CLK_IEP_DRC1 147
175#define CLK_IEP_DEU0 148
176#define CLK_IEP_DEU1 149
177#define CLK_GPU_CORE 150
178#define CLK_GPU_MEMORY 151
179#define CLK_GPU_HYD 152
180#define CLK_ATS 153
181#define CLK_TRACE 154
182
183#define CLK_OUT_A 155
184#define CLK_OUT_B 156
185#define CLK_OUT_C 157
186
187#endif /* _DT_BINDINGS_CLK_SUN6I_A31_H_ */
diff --git a/include/dt-bindings/clock/sun8i-a23-a33-ccu.h b/include/dt-bindings/clock/sun8i-a23-a33-ccu.h
new file mode 100644
index 000000000000..f8222b6b2cc3
--- /dev/null
+++ b/include/dt-bindings/clock/sun8i-a23-a33-ccu.h
@@ -0,0 +1,127 @@
1/*
2 * Copyright (C) 2016 Maxime Ripard <maxime.ripard@free-electrons.com>
3 *
4 * This file is dual-licensed: you can use it either under the terms
5 * of the GPL or the X11 license, at your option. Note that this dual
6 * licensing only applies to this file, and not this project as a
7 * whole.
8 *
9 * a) This file is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU General Public License as
11 * published by the Free Software Foundation; either version 2 of the
12 * License, or (at your option) any later version.
13 *
14 * This file is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * Or, alternatively,
20 *
21 * b) Permission is hereby granted, free of charge, to any person
22 * obtaining a copy of this software and associated documentation
23 * files (the "Software"), to deal in the Software without
24 * restriction, including without limitation the rights to use,
25 * copy, modify, merge, publish, distribute, sublicense, and/or
26 * sell copies of the Software, and to permit persons to whom the
27 * Software is furnished to do so, subject to the following
28 * conditions:
29 *
30 * The above copyright notice and this permission notice shall be
31 * included in all copies or substantial portions of the Software.
32 *
33 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
34 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
35 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
36 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
37 * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
38 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
39 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
40 * OTHER DEALINGS IN THE SOFTWARE.
41 */
42
43#ifndef _DT_BINDINGS_CLK_SUN8I_A23_A33_H_
44#define _DT_BINDINGS_CLK_SUN8I_A23_A33_H_
45
46#define CLK_CPUX 18
47
48#define CLK_BUS_MIPI_DSI 23
49#define CLK_BUS_SS 24
50#define CLK_BUS_DMA 25
51#define CLK_BUS_MMC0 26
52#define CLK_BUS_MMC1 27
53#define CLK_BUS_MMC2 28
54#define CLK_BUS_NAND 29
55#define CLK_BUS_DRAM 30
56#define CLK_BUS_HSTIMER 31
57#define CLK_BUS_SPI0 32
58#define CLK_BUS_SPI1 33
59#define CLK_BUS_OTG 34
60#define CLK_BUS_EHCI 35
61#define CLK_BUS_OHCI 36
62#define CLK_BUS_VE 37
63#define CLK_BUS_LCD 38
64#define CLK_BUS_CSI 39
65#define CLK_BUS_DE_BE 40
66#define CLK_BUS_DE_FE 41
67#define CLK_BUS_GPU 42
68#define CLK_BUS_MSGBOX 43
69#define CLK_BUS_SPINLOCK 44
70#define CLK_BUS_DRC 45
71#define CLK_BUS_SAT 46
72#define CLK_BUS_CODEC 47
73#define CLK_BUS_PIO 48
74#define CLK_BUS_I2S0 49
75#define CLK_BUS_I2S1 50
76#define CLK_BUS_I2C0 51
77#define CLK_BUS_I2C1 52
78#define CLK_BUS_I2C2 53
79#define CLK_BUS_UART0 54
80#define CLK_BUS_UART1 55
81#define CLK_BUS_UART2 56
82#define CLK_BUS_UART3 57
83#define CLK_BUS_UART4 58
84#define CLK_NAND 59
85#define CLK_MMC0 60
86#define CLK_MMC0_SAMPLE 61
87#define CLK_MMC0_OUTPUT 62
88#define CLK_MMC1 63
89#define CLK_MMC1_SAMPLE 64
90#define CLK_MMC1_OUTPUT 65
91#define CLK_MMC2 66
92#define CLK_MMC2_SAMPLE 67
93#define CLK_MMC2_OUTPUT 68
94#define CLK_SS 69
95#define CLK_SPI0 70
96#define CLK_SPI1 71
97#define CLK_I2S0 72
98#define CLK_I2S1 73
99#define CLK_USB_PHY0 74
100#define CLK_USB_PHY1 75
101#define CLK_USB_HSIC 76
102#define CLK_USB_HSIC_12M 77
103#define CLK_USB_OHCI 78
104
105#define CLK_DRAM_VE 80
106#define CLK_DRAM_CSI 81
107#define CLK_DRAM_DRC 82
108#define CLK_DRAM_DE_FE 83
109#define CLK_DRAM_DE_BE 84
110#define CLK_DE_BE 85
111#define CLK_DE_FE 86
112#define CLK_LCD_CH0 87
113#define CLK_LCD_CH1 88
114#define CLK_CSI_SCLK 89
115#define CLK_CSI_MCLK 90
116#define CLK_VE 91
117#define CLK_AC_DIG 92
118#define CLK_AC_DIG_4X 93
119#define CLK_AVS 94
120
121#define CLK_DSI_SCLK 96
122#define CLK_DSI_DPHY 97
123#define CLK_DRC 98
124#define CLK_GPU 99
125#define CLK_ATS 100
126
127#endif /* _DT_BINDINGS_CLK_SUN8I_A23_A33_H_ */
diff --git a/include/dt-bindings/reset/sun6i-a31-ccu.h b/include/dt-bindings/reset/sun6i-a31-ccu.h
new file mode 100644
index 000000000000..fbff365ed6e1
--- /dev/null
+++ b/include/dt-bindings/reset/sun6i-a31-ccu.h
@@ -0,0 +1,106 @@
1/*
2 * Copyright (C) 2016 Chen-Yu Tsai <wens@csie.org>
3 *
4 * This file is dual-licensed: you can use it either under the terms
5 * of the GPL or the X11 license, at your option. Note that this dual
6 * licensing only applies to this file, and not this project as a
7 * whole.
8 *
9 * a) This file is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU General Public License as
11 * published by the Free Software Foundation; either version 2 of the
12 * License, or (at your option) any later version.
13 *
14 * This file is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * Or, alternatively,
20 *
21 * b) Permission is hereby granted, free of charge, to any person
22 * obtaining a copy of this software and associated documentation
23 * files (the "Software"), to deal in the Software without
24 * restriction, including without limitation the rights to use,
25 * copy, modify, merge, publish, distribute, sublicense, and/or
26 * sell copies of the Software, and to permit persons to whom the
27 * Software is furnished to do so, subject to the following
28 * conditions:
29 *
30 * The above copyright notice and this permission notice shall be
31 * included in all copies or substantial portions of the Software.
32 *
33 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
34 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
35 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
36 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
37 * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
38 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
39 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
40 * OTHER DEALINGS IN THE SOFTWARE.
41 */
42
43#ifndef _DT_BINDINGS_RST_SUN6I_A31_H_
44#define _DT_BINDINGS_RST_SUN6I_A31_H_
45
46#define RST_USB_PHY0 0
47#define RST_USB_PHY1 1
48#define RST_USB_PHY2 2
49
50#define RST_AHB1_MIPI_DSI 3
51#define RST_AHB1_SS 4
52#define RST_AHB1_DMA 5
53#define RST_AHB1_MMC0 6
54#define RST_AHB1_MMC1 7
55#define RST_AHB1_MMC2 8
56#define RST_AHB1_MMC3 9
57#define RST_AHB1_NAND1 10
58#define RST_AHB1_NAND0 11
59#define RST_AHB1_SDRAM 12
60#define RST_AHB1_EMAC 13
61#define RST_AHB1_TS 14
62#define RST_AHB1_HSTIMER 15
63#define RST_AHB1_SPI0 16
64#define RST_AHB1_SPI1 17
65#define RST_AHB1_SPI2 18
66#define RST_AHB1_SPI3 19
67#define RST_AHB1_OTG 20
68#define RST_AHB1_EHCI0 21
69#define RST_AHB1_EHCI1 22
70#define RST_AHB1_OHCI0 23
71#define RST_AHB1_OHCI1 24
72#define RST_AHB1_OHCI2 25
73#define RST_AHB1_VE 26
74#define RST_AHB1_LCD0 27
75#define RST_AHB1_LCD1 28
76#define RST_AHB1_CSI 29
77#define RST_AHB1_HDMI 30
78#define RST_AHB1_BE0 31
79#define RST_AHB1_BE1 32
80#define RST_AHB1_FE0 33
81#define RST_AHB1_FE1 34
82#define RST_AHB1_MP 35
83#define RST_AHB1_GPU 36
84#define RST_AHB1_DEU0 37
85#define RST_AHB1_DEU1 38
86#define RST_AHB1_DRC0 39
87#define RST_AHB1_DRC1 40
88#define RST_AHB1_LVDS 41
89
90#define RST_APB1_CODEC 42
91#define RST_APB1_SPDIF 43
92#define RST_APB1_DIGITAL_MIC 44
93#define RST_APB1_DAUDIO0 45
94#define RST_APB1_DAUDIO1 46
95#define RST_APB2_I2C0 47
96#define RST_APB2_I2C1 48
97#define RST_APB2_I2C2 49
98#define RST_APB2_I2C3 50
99#define RST_APB2_UART0 51
100#define RST_APB2_UART1 52
101#define RST_APB2_UART2 53
102#define RST_APB2_UART3 54
103#define RST_APB2_UART4 55
104#define RST_APB2_UART5 56
105
106#endif /* _DT_BINDINGS_RST_SUN6I_A31_H_ */
diff --git a/include/dt-bindings/reset/sun8i-a23-a33-ccu.h b/include/dt-bindings/reset/sun8i-a23-a33-ccu.h
new file mode 100644
index 000000000000..6121f2b0cd0a
--- /dev/null
+++ b/include/dt-bindings/reset/sun8i-a23-a33-ccu.h
@@ -0,0 +1,87 @@
1/*
2 * Copyright (C) 2016 Maxime Ripard <maxime.ripard@free-electrons.com>
3 *
4 * This file is dual-licensed: you can use it either under the terms
5 * of the GPL or the X11 license, at your option. Note that this dual
6 * licensing only applies to this file, and not this project as a
7 * whole.
8 *
9 * a) This file is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU General Public License as
11 * published by the Free Software Foundation; either version 2 of the
12 * License, or (at your option) any later version.
13 *
14 * This file is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * Or, alternatively,
20 *
21 * b) Permission is hereby granted, free of charge, to any person
22 * obtaining a copy of this software and associated documentation
23 * files (the "Software"), to deal in the Software without
24 * restriction, including without limitation the rights to use,
25 * copy, modify, merge, publish, distribute, sublicense, and/or
26 * sell copies of the Software, and to permit persons to whom the
27 * Software is furnished to do so, subject to the following
28 * conditions:
29 *
30 * The above copyright notice and this permission notice shall be
31 * included in all copies or substantial portions of the Software.
32 *
33 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
34 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
35 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
36 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
37 * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
38 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
39 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
40 * OTHER DEALINGS IN THE SOFTWARE.
41 */
42
43#ifndef _DT_BINDINGS_RST_SUN8I_A23_A33_H_
44#define _DT_BINDINGS_RST_SUN8I_A23_A33_H_
45
46#define RST_USB_PHY0 0
47#define RST_USB_PHY1 1
48#define RST_USB_HSIC 2
49#define RST_MBUS 3
50#define RST_BUS_MIPI_DSI 4
51#define RST_BUS_SS 5
52#define RST_BUS_DMA 6
53#define RST_BUS_MMC0 7
54#define RST_BUS_MMC1 8
55#define RST_BUS_MMC2 9
56#define RST_BUS_NAND 10
57#define RST_BUS_DRAM 11
58#define RST_BUS_HSTIMER 12
59#define RST_BUS_SPI0 13
60#define RST_BUS_SPI1 14
61#define RST_BUS_OTG 15
62#define RST_BUS_EHCI 16
63#define RST_BUS_OHCI 17
64#define RST_BUS_VE 18
65#define RST_BUS_LCD 19
66#define RST_BUS_CSI 20
67#define RST_BUS_DE_BE 21
68#define RST_BUS_DE_FE 22
69#define RST_BUS_GPU 23
70#define RST_BUS_MSGBOX 24
71#define RST_BUS_SPINLOCK 25
72#define RST_BUS_DRC 26
73#define RST_BUS_SAT 27
74#define RST_BUS_LVDS 28
75#define RST_BUS_CODEC 29
76#define RST_BUS_I2S0 30
77#define RST_BUS_I2S1 31
78#define RST_BUS_I2C0 32
79#define RST_BUS_I2C1 33
80#define RST_BUS_I2C2 34
81#define RST_BUS_UART0 35
82#define RST_BUS_UART1 36
83#define RST_BUS_UART2 37
84#define RST_BUS_UART3 38
85#define RST_BUS_UART4 39
86
87#endif /* _DT_BINDINGS_RST_SUN8I_A23_A33_H_ */