Merge tag 'asm-generic-fixes-5.19' of git://git.kernel.org/pub/scm/linux/kernel/git...
[linux-2.6-microblaze.git] / drivers / clk / samsung / clk-exynos7885.c
1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3  * Copyright (C) 2021 Dávid Virág <virag.david003@gmail.com>
4  * Author: Dávid Virág <virag.david003@gmail.com>
5  *
6  * Common Clock Framework support for Exynos7885 SoC.
7  */
8
9 #include <linux/clk.h>
10 #include <linux/clk-provider.h>
11 #include <linux/of.h>
12 #include <linux/of_device.h>
13 #include <linux/platform_device.h>
14
15 #include <dt-bindings/clock/exynos7885.h>
16
17 #include "clk.h"
18 #include "clk-exynos-arm64.h"
19
20 /* ---- CMU_TOP ------------------------------------------------------------- */
21
22 /* Register Offset definitions for CMU_TOP (0x12060000) */
23 #define PLL_LOCKTIME_PLL_SHARED0                0x0000
24 #define PLL_LOCKTIME_PLL_SHARED1                0x0004
25 #define PLL_CON0_PLL_SHARED0                    0x0100
26 #define PLL_CON0_PLL_SHARED1                    0x0120
27 #define CLK_CON_MUX_MUX_CLKCMU_CORE_BUS         0x1014
28 #define CLK_CON_MUX_MUX_CLKCMU_CORE_CCI         0x1018
29 #define CLK_CON_MUX_MUX_CLKCMU_CORE_G3D         0x101c
30 #define CLK_CON_MUX_MUX_CLKCMU_PERI_BUS         0x1058
31 #define CLK_CON_MUX_MUX_CLKCMU_PERI_SPI0        0x105c
32 #define CLK_CON_MUX_MUX_CLKCMU_PERI_SPI1        0x1060
33 #define CLK_CON_MUX_MUX_CLKCMU_PERI_UART0       0x1064
34 #define CLK_CON_MUX_MUX_CLKCMU_PERI_UART1       0x1068
35 #define CLK_CON_MUX_MUX_CLKCMU_PERI_UART2       0x106c
36 #define CLK_CON_MUX_MUX_CLKCMU_PERI_USI0        0x1070
37 #define CLK_CON_MUX_MUX_CLKCMU_PERI_USI1        0x1074
38 #define CLK_CON_MUX_MUX_CLKCMU_PERI_USI2        0x1078
39 #define CLK_CON_DIV_CLKCMU_CORE_BUS             0x181c
40 #define CLK_CON_DIV_CLKCMU_CORE_CCI             0x1820
41 #define CLK_CON_DIV_CLKCMU_CORE_G3D             0x1824
42 #define CLK_CON_DIV_CLKCMU_PERI_BUS             0x1874
43 #define CLK_CON_DIV_CLKCMU_PERI_SPI0            0x1878
44 #define CLK_CON_DIV_CLKCMU_PERI_SPI1            0x187c
45 #define CLK_CON_DIV_CLKCMU_PERI_UART0           0x1880
46 #define CLK_CON_DIV_CLKCMU_PERI_UART1           0x1884
47 #define CLK_CON_DIV_CLKCMU_PERI_UART2           0x1888
48 #define CLK_CON_DIV_CLKCMU_PERI_USI0            0x188c
49 #define CLK_CON_DIV_CLKCMU_PERI_USI1            0x1890
50 #define CLK_CON_DIV_CLKCMU_PERI_USI2            0x1894
51 #define CLK_CON_DIV_PLL_SHARED0_DIV2            0x189c
52 #define CLK_CON_DIV_PLL_SHARED0_DIV3            0x18a0
53 #define CLK_CON_DIV_PLL_SHARED0_DIV4            0x18a4
54 #define CLK_CON_DIV_PLL_SHARED0_DIV5            0x18a8
55 #define CLK_CON_DIV_PLL_SHARED1_DIV2            0x18ac
56 #define CLK_CON_DIV_PLL_SHARED1_DIV3            0x18b0
57 #define CLK_CON_DIV_PLL_SHARED1_DIV4            0x18b4
58 #define CLK_CON_GAT_GATE_CLKCMUC_PERI_UART1     0x2004
59 #define CLK_CON_GAT_GATE_CLKCMU_CORE_BUS        0x201c
60 #define CLK_CON_GAT_GATE_CLKCMU_CORE_CCI        0x2020
61 #define CLK_CON_GAT_GATE_CLKCMU_CORE_G3D        0x2024
62 #define CLK_CON_GAT_GATE_CLKCMU_PERI_BUS        0x207c
63 #define CLK_CON_GAT_GATE_CLKCMU_PERI_SPI0       0x2080
64 #define CLK_CON_GAT_GATE_CLKCMU_PERI_SPI1       0x2084
65 #define CLK_CON_GAT_GATE_CLKCMU_PERI_UART0      0x2088
66 #define CLK_CON_GAT_GATE_CLKCMU_PERI_UART2      0x208c
67 #define CLK_CON_GAT_GATE_CLKCMU_PERI_USI0       0x2090
68 #define CLK_CON_GAT_GATE_CLKCMU_PERI_USI1       0x2094
69 #define CLK_CON_GAT_GATE_CLKCMU_PERI_USI2       0x2098
70
71 static const unsigned long top_clk_regs[] __initconst = {
72         PLL_LOCKTIME_PLL_SHARED0,
73         PLL_LOCKTIME_PLL_SHARED1,
74         PLL_CON0_PLL_SHARED0,
75         PLL_CON0_PLL_SHARED1,
76         CLK_CON_MUX_MUX_CLKCMU_CORE_BUS,
77         CLK_CON_MUX_MUX_CLKCMU_CORE_CCI,
78         CLK_CON_MUX_MUX_CLKCMU_CORE_G3D,
79         CLK_CON_MUX_MUX_CLKCMU_PERI_BUS,
80         CLK_CON_MUX_MUX_CLKCMU_PERI_SPI0,
81         CLK_CON_MUX_MUX_CLKCMU_PERI_SPI1,
82         CLK_CON_MUX_MUX_CLKCMU_PERI_UART0,
83         CLK_CON_MUX_MUX_CLKCMU_PERI_UART1,
84         CLK_CON_MUX_MUX_CLKCMU_PERI_UART2,
85         CLK_CON_MUX_MUX_CLKCMU_PERI_USI0,
86         CLK_CON_MUX_MUX_CLKCMU_PERI_USI1,
87         CLK_CON_MUX_MUX_CLKCMU_PERI_USI2,
88         CLK_CON_DIV_CLKCMU_CORE_BUS,
89         CLK_CON_DIV_CLKCMU_CORE_CCI,
90         CLK_CON_DIV_CLKCMU_CORE_G3D,
91         CLK_CON_DIV_CLKCMU_PERI_BUS,
92         CLK_CON_DIV_CLKCMU_PERI_SPI0,
93         CLK_CON_DIV_CLKCMU_PERI_SPI1,
94         CLK_CON_DIV_CLKCMU_PERI_UART0,
95         CLK_CON_DIV_CLKCMU_PERI_UART1,
96         CLK_CON_DIV_CLKCMU_PERI_UART2,
97         CLK_CON_DIV_CLKCMU_PERI_USI0,
98         CLK_CON_DIV_CLKCMU_PERI_USI1,
99         CLK_CON_DIV_CLKCMU_PERI_USI2,
100         CLK_CON_DIV_PLL_SHARED0_DIV2,
101         CLK_CON_DIV_PLL_SHARED0_DIV3,
102         CLK_CON_DIV_PLL_SHARED0_DIV4,
103         CLK_CON_DIV_PLL_SHARED0_DIV5,
104         CLK_CON_DIV_PLL_SHARED1_DIV2,
105         CLK_CON_DIV_PLL_SHARED1_DIV3,
106         CLK_CON_DIV_PLL_SHARED1_DIV4,
107         CLK_CON_GAT_GATE_CLKCMUC_PERI_UART1,
108         CLK_CON_GAT_GATE_CLKCMU_CORE_BUS,
109         CLK_CON_GAT_GATE_CLKCMU_CORE_CCI,
110         CLK_CON_GAT_GATE_CLKCMU_CORE_G3D,
111         CLK_CON_GAT_GATE_CLKCMU_PERI_BUS,
112         CLK_CON_GAT_GATE_CLKCMU_PERI_SPI0,
113         CLK_CON_GAT_GATE_CLKCMU_PERI_SPI1,
114         CLK_CON_GAT_GATE_CLKCMU_PERI_UART0,
115         CLK_CON_GAT_GATE_CLKCMU_PERI_UART2,
116         CLK_CON_GAT_GATE_CLKCMU_PERI_USI0,
117         CLK_CON_GAT_GATE_CLKCMU_PERI_USI1,
118         CLK_CON_GAT_GATE_CLKCMU_PERI_USI2,
119 };
120
121 static const struct samsung_pll_clock top_pll_clks[] __initconst = {
122         PLL(pll_1417x, CLK_FOUT_SHARED0_PLL, "fout_shared0_pll", "oscclk",
123             PLL_LOCKTIME_PLL_SHARED0, PLL_CON0_PLL_SHARED0,
124             NULL),
125         PLL(pll_1417x, CLK_FOUT_SHARED1_PLL, "fout_shared1_pll", "oscclk",
126             PLL_LOCKTIME_PLL_SHARED1, PLL_CON0_PLL_SHARED1,
127             NULL),
128 };
129
130 /* List of parent clocks for Muxes in CMU_TOP: for CMU_CORE */
131 PNAME(mout_core_bus_p)          = { "dout_shared0_div2", "dout_shared1_div2",
132                                     "dout_shared0_div3", "dout_shared0_div3" };
133 PNAME(mout_core_cci_p)          = { "dout_shared0_div2", "dout_shared1_div2",
134                                     "dout_shared0_div3", "dout_shared0_div3" };
135 PNAME(mout_core_g3d_p)          = { "dout_shared0_div2", "dout_shared1_div2",
136                                     "dout_shared0_div3", "dout_shared0_div3" };
137
138 /* List of parent clocks for Muxes in CMU_TOP: for CMU_PERI */
139 PNAME(mout_peri_bus_p)          = { "dout_shared0_div4", "dout_shared1_div4" };
140 PNAME(mout_peri_spi0_p)         = { "oscclk", "dout_shared0_div4" };
141 PNAME(mout_peri_spi1_p)         = { "oscclk", "dout_shared0_div4" };
142 PNAME(mout_peri_uart0_p)        = { "oscclk", "dout_shared0_div4" };
143 PNAME(mout_peri_uart1_p)        = { "oscclk", "dout_shared0_div4" };
144 PNAME(mout_peri_uart2_p)        = { "oscclk", "dout_shared0_div4" };
145 PNAME(mout_peri_usi0_p)         = { "oscclk", "dout_shared0_div4" };
146 PNAME(mout_peri_usi1_p)         = { "oscclk", "dout_shared0_div4" };
147 PNAME(mout_peri_usi2_p)         = { "oscclk", "dout_shared0_div4" };
148
149 static const struct samsung_mux_clock top_mux_clks[] __initconst = {
150         /* CORE */
151         MUX(CLK_MOUT_CORE_BUS, "mout_core_bus", mout_core_bus_p,
152             CLK_CON_MUX_MUX_CLKCMU_CORE_BUS, 0, 2),
153         MUX(CLK_MOUT_CORE_CCI, "mout_core_cci", mout_core_cci_p,
154             CLK_CON_MUX_MUX_CLKCMU_CORE_CCI, 0, 2),
155         MUX(CLK_MOUT_CORE_G3D, "mout_core_g3d", mout_core_g3d_p,
156             CLK_CON_MUX_MUX_CLKCMU_CORE_G3D, 0, 2),
157
158         /* PERI */
159         MUX(CLK_MOUT_PERI_BUS, "mout_peri_bus", mout_peri_bus_p,
160             CLK_CON_MUX_MUX_CLKCMU_PERI_BUS, 0, 1),
161         MUX(CLK_MOUT_PERI_SPI0, "mout_peri_spi0", mout_peri_spi0_p,
162             CLK_CON_MUX_MUX_CLKCMU_PERI_SPI0, 0, 1),
163         MUX(CLK_MOUT_PERI_SPI1, "mout_peri_spi1", mout_peri_spi1_p,
164             CLK_CON_MUX_MUX_CLKCMU_PERI_SPI1, 0, 1),
165         MUX(CLK_MOUT_PERI_UART0, "mout_peri_uart0", mout_peri_uart0_p,
166             CLK_CON_MUX_MUX_CLKCMU_PERI_UART0, 0, 1),
167         MUX(CLK_MOUT_PERI_UART1, "mout_peri_uart1", mout_peri_uart1_p,
168             CLK_CON_MUX_MUX_CLKCMU_PERI_UART1, 0, 1),
169         MUX(CLK_MOUT_PERI_UART2, "mout_peri_uart2", mout_peri_uart2_p,
170             CLK_CON_MUX_MUX_CLKCMU_PERI_UART2, 0, 1),
171         MUX(CLK_MOUT_PERI_USI0, "mout_peri_usi0", mout_peri_usi0_p,
172             CLK_CON_MUX_MUX_CLKCMU_PERI_USI0, 0, 1),
173         MUX(CLK_MOUT_PERI_USI1, "mout_peri_usi1", mout_peri_usi1_p,
174             CLK_CON_MUX_MUX_CLKCMU_PERI_USI1, 0, 1),
175         MUX(CLK_MOUT_PERI_USI2, "mout_peri_usi2", mout_peri_usi2_p,
176             CLK_CON_MUX_MUX_CLKCMU_PERI_USI2, 0, 1),
177 };
178
179 static const struct samsung_div_clock top_div_clks[] __initconst = {
180         /* TOP */
181         DIV(CLK_DOUT_SHARED0_DIV2, "dout_shared0_div2", "fout_shared0_pll",
182             CLK_CON_DIV_PLL_SHARED0_DIV2, 0, 1),
183         DIV(CLK_DOUT_SHARED0_DIV3, "dout_shared0_div3", "fout_shared0_pll",
184             CLK_CON_DIV_PLL_SHARED0_DIV3, 0, 2),
185         DIV(CLK_DOUT_SHARED0_DIV4, "dout_shared0_div4", "fout_shared0_pll",
186             CLK_CON_DIV_PLL_SHARED0_DIV4, 0, 1),
187         DIV(CLK_DOUT_SHARED0_DIV5, "dout_shared0_div5", "fout_shared0_pll",
188             CLK_CON_DIV_PLL_SHARED0_DIV5, 0, 3),
189         DIV(CLK_DOUT_SHARED1_DIV2, "dout_shared1_div2", "fout_shared1_pll",
190             CLK_CON_DIV_PLL_SHARED1_DIV2, 0, 1),
191         DIV(CLK_DOUT_SHARED1_DIV3, "dout_shared1_div3", "fout_shared1_pll",
192             CLK_CON_DIV_PLL_SHARED1_DIV3, 0, 2),
193         DIV(CLK_DOUT_SHARED1_DIV4, "dout_shared1_div4", "fout_shared1_pll",
194             CLK_CON_DIV_PLL_SHARED1_DIV4, 0, 1),
195
196         /* CORE */
197         DIV(CLK_DOUT_CORE_BUS, "dout_core_bus", "gout_core_bus",
198             CLK_CON_DIV_CLKCMU_CORE_BUS, 0, 3),
199         DIV(CLK_DOUT_CORE_CCI, "dout_core_cci", "gout_core_cci",
200             CLK_CON_DIV_CLKCMU_CORE_CCI, 0, 3),
201         DIV(CLK_DOUT_CORE_G3D, "dout_core_g3d", "gout_core_g3d",
202             CLK_CON_DIV_CLKCMU_CORE_G3D, 0, 3),
203
204         /* PERI */
205         DIV(CLK_DOUT_PERI_BUS, "dout_peri_bus", "gout_peri_bus",
206             CLK_CON_DIV_CLKCMU_PERI_BUS, 0, 4),
207         DIV(CLK_DOUT_PERI_SPI0, "dout_peri_spi0", "gout_peri_spi0",
208             CLK_CON_DIV_CLKCMU_PERI_SPI0, 0, 6),
209         DIV(CLK_DOUT_PERI_SPI1, "dout_peri_spi1", "gout_peri_spi1",
210             CLK_CON_DIV_CLKCMU_PERI_SPI1, 0, 6),
211         DIV(CLK_DOUT_PERI_UART0, "dout_peri_uart0", "gout_peri_uart0",
212             CLK_CON_DIV_CLKCMU_PERI_UART0, 0, 4),
213         DIV(CLK_DOUT_PERI_UART1, "dout_peri_uart1", "gout_peri_uart1",
214             CLK_CON_DIV_CLKCMU_PERI_UART1, 0, 4),
215         DIV(CLK_DOUT_PERI_UART2, "dout_peri_uart2", "gout_peri_uart2",
216             CLK_CON_DIV_CLKCMU_PERI_UART2, 0, 4),
217         DIV(CLK_DOUT_PERI_USI0, "dout_peri_usi0", "gout_peri_usi0",
218             CLK_CON_DIV_CLKCMU_PERI_USI0, 0, 4),
219         DIV(CLK_DOUT_PERI_USI1, "dout_peri_usi1", "gout_peri_usi1",
220             CLK_CON_DIV_CLKCMU_PERI_USI1, 0, 4),
221         DIV(CLK_DOUT_PERI_USI2, "dout_peri_usi2", "gout_peri_usi2",
222             CLK_CON_DIV_CLKCMU_PERI_USI2, 0, 4),
223 };
224
225 static const struct samsung_gate_clock top_gate_clks[] __initconst = {
226         /* CORE */
227         GATE(CLK_GOUT_CORE_BUS, "gout_core_bus", "mout_core_bus",
228              CLK_CON_GAT_GATE_CLKCMU_CORE_BUS, 21, 0, 0),
229         GATE(CLK_GOUT_CORE_CCI, "gout_core_cci", "mout_core_cci",
230              CLK_CON_GAT_GATE_CLKCMU_CORE_CCI, 21, 0, 0),
231         GATE(CLK_GOUT_CORE_G3D, "gout_core_g3d", "mout_core_g3d",
232              CLK_CON_GAT_GATE_CLKCMU_CORE_G3D, 21, 0, 0),
233
234         /* PERI */
235         GATE(CLK_GOUT_PERI_BUS, "gout_peri_bus", "mout_peri_bus",
236              CLK_CON_GAT_GATE_CLKCMU_PERI_BUS, 21, 0, 0),
237         GATE(CLK_GOUT_PERI_SPI0, "gout_peri_spi0", "mout_peri_spi0",
238              CLK_CON_GAT_GATE_CLKCMU_PERI_SPI0, 21, 0, 0),
239         GATE(CLK_GOUT_PERI_SPI1, "gout_peri_spi1", "mout_peri_spi1",
240              CLK_CON_GAT_GATE_CLKCMU_PERI_SPI1, 21, 0, 0),
241         GATE(CLK_GOUT_PERI_UART0, "gout_peri_uart0", "mout_peri_uart0",
242              CLK_CON_GAT_GATE_CLKCMU_PERI_UART0, 21, 0, 0),
243         GATE(CLK_GOUT_PERI_UART1, "gout_peri_uart1", "mout_peri_uart1",
244              CLK_CON_GAT_GATE_CLKCMUC_PERI_UART1, 21, 0, 0),
245         GATE(CLK_GOUT_PERI_UART2, "gout_peri_uart2", "mout_peri_uart2",
246              CLK_CON_GAT_GATE_CLKCMU_PERI_UART2, 21, 0, 0),
247         GATE(CLK_GOUT_PERI_USI0, "gout_peri_usi0", "mout_peri_usi0",
248              CLK_CON_GAT_GATE_CLKCMU_PERI_USI0, 21, 0, 0),
249         GATE(CLK_GOUT_PERI_USI1, "gout_peri_usi1", "mout_peri_usi1",
250              CLK_CON_GAT_GATE_CLKCMU_PERI_USI1, 21, 0, 0),
251         GATE(CLK_GOUT_PERI_USI2, "gout_peri_usi2", "mout_peri_usi2",
252              CLK_CON_GAT_GATE_CLKCMU_PERI_USI2, 21, 0, 0),
253 };
254
255 static const struct samsung_cmu_info top_cmu_info __initconst = {
256         .pll_clks               = top_pll_clks,
257         .nr_pll_clks            = ARRAY_SIZE(top_pll_clks),
258         .mux_clks               = top_mux_clks,
259         .nr_mux_clks            = ARRAY_SIZE(top_mux_clks),
260         .div_clks               = top_div_clks,
261         .nr_div_clks            = ARRAY_SIZE(top_div_clks),
262         .gate_clks              = top_gate_clks,
263         .nr_gate_clks           = ARRAY_SIZE(top_gate_clks),
264         .nr_clk_ids             = TOP_NR_CLK,
265         .clk_regs               = top_clk_regs,
266         .nr_clk_regs            = ARRAY_SIZE(top_clk_regs),
267 };
268
269 static void __init exynos7885_cmu_top_init(struct device_node *np)
270 {
271         exynos_arm64_register_cmu(NULL, np, &top_cmu_info);
272 }
273
274 /* Register CMU_TOP early, as it's a dependency for other early domains */
275 CLK_OF_DECLARE(exynos7885_cmu_top, "samsung,exynos7885-cmu-top",
276                exynos7885_cmu_top_init);
277
278 /* ---- CMU_PERI ------------------------------------------------------------ */
279
280 /* Register Offset definitions for CMU_PERI (0x10010000) */
281 #define PLL_CON0_MUX_CLKCMU_PERI_BUS_USER       0x0100
282 #define PLL_CON0_MUX_CLKCMU_PERI_SPI0_USER      0x0120
283 #define PLL_CON0_MUX_CLKCMU_PERI_SPI1_USER      0x0140
284 #define PLL_CON0_MUX_CLKCMU_PERI_UART0_USER     0x0160
285 #define PLL_CON0_MUX_CLKCMU_PERI_UART1_USER     0x0180
286 #define PLL_CON0_MUX_CLKCMU_PERI_UART2_USER     0x01a0
287 #define PLL_CON0_MUX_CLKCMU_PERI_USI0_USER      0x01c0
288 #define PLL_CON0_MUX_CLKCMU_PERI_USI1_USER      0x01e0
289 #define PLL_CON0_MUX_CLKCMU_PERI_USI2_USER      0x0200
290 #define CLK_CON_GAT_GOUT_PERI_GPIO_TOP_PCLK     0x2024
291 #define CLK_CON_GAT_GOUT_PERI_HSI2C_0_PCLK      0x2028
292 #define CLK_CON_GAT_GOUT_PERI_HSI2C_1_PCLK      0x202c
293 #define CLK_CON_GAT_GOUT_PERI_HSI2C_2_PCLK      0x2030
294 #define CLK_CON_GAT_GOUT_PERI_HSI2C_3_PCLK      0x2034
295 #define CLK_CON_GAT_GOUT_PERI_I2C_0_PCLK        0x2038
296 #define CLK_CON_GAT_GOUT_PERI_I2C_1_PCLK        0x203c
297 #define CLK_CON_GAT_GOUT_PERI_I2C_2_PCLK        0x2040
298 #define CLK_CON_GAT_GOUT_PERI_I2C_3_PCLK        0x2044
299 #define CLK_CON_GAT_GOUT_PERI_I2C_4_PCLK        0x2048
300 #define CLK_CON_GAT_GOUT_PERI_I2C_5_PCLK        0x204c
301 #define CLK_CON_GAT_GOUT_PERI_I2C_6_PCLK        0x2050
302 #define CLK_CON_GAT_GOUT_PERI_I2C_7_PCLK        0x2054
303 #define CLK_CON_GAT_GOUT_PERI_PWM_MOTOR_PCLK    0x2058
304 #define CLK_CON_GAT_GOUT_PERI_SPI_0_PCLK        0x205c
305 #define CLK_CON_GAT_GOUT_PERI_SPI_0_EXT_CLK     0x2060
306 #define CLK_CON_GAT_GOUT_PERI_SPI_1_PCLK        0x2064
307 #define CLK_CON_GAT_GOUT_PERI_SPI_1_EXT_CLK     0x2068
308 #define CLK_CON_GAT_GOUT_PERI_UART_0_EXT_UCLK   0x206c
309 #define CLK_CON_GAT_GOUT_PERI_UART_0_PCLK       0x2070
310 #define CLK_CON_GAT_GOUT_PERI_UART_1_EXT_UCLK   0x2074
311 #define CLK_CON_GAT_GOUT_PERI_UART_1_PCLK       0x2078
312 #define CLK_CON_GAT_GOUT_PERI_UART_2_EXT_UCLK   0x207c
313 #define CLK_CON_GAT_GOUT_PERI_UART_2_PCLK       0x2080
314 #define CLK_CON_GAT_GOUT_PERI_USI0_PCLK         0x2084
315 #define CLK_CON_GAT_GOUT_PERI_USI0_SCLK         0x2088
316 #define CLK_CON_GAT_GOUT_PERI_USI1_PCLK         0x208c
317 #define CLK_CON_GAT_GOUT_PERI_USI1_SCLK         0x2090
318 #define CLK_CON_GAT_GOUT_PERI_USI2_PCLK         0x2094
319 #define CLK_CON_GAT_GOUT_PERI_USI2_SCLK         0x2098
320 #define CLK_CON_GAT_GOUT_PERI_MCT_PCLK          0x20a0
321 #define CLK_CON_GAT_GOUT_PERI_SYSREG_PERI_PCLK  0x20b0
322 #define CLK_CON_GAT_GOUT_PERI_WDT_CLUSTER0_PCLK 0x20b4
323 #define CLK_CON_GAT_GOUT_PERI_WDT_CLUSTER1_PCLK 0x20b8
324
325 static const unsigned long peri_clk_regs[] __initconst = {
326         PLL_CON0_MUX_CLKCMU_PERI_BUS_USER,
327         PLL_CON0_MUX_CLKCMU_PERI_SPI0_USER,
328         PLL_CON0_MUX_CLKCMU_PERI_SPI1_USER,
329         PLL_CON0_MUX_CLKCMU_PERI_UART0_USER,
330         PLL_CON0_MUX_CLKCMU_PERI_UART1_USER,
331         PLL_CON0_MUX_CLKCMU_PERI_UART2_USER,
332         PLL_CON0_MUX_CLKCMU_PERI_USI0_USER,
333         PLL_CON0_MUX_CLKCMU_PERI_USI1_USER,
334         PLL_CON0_MUX_CLKCMU_PERI_USI2_USER,
335         CLK_CON_GAT_GOUT_PERI_GPIO_TOP_PCLK,
336         CLK_CON_GAT_GOUT_PERI_HSI2C_0_PCLK,
337         CLK_CON_GAT_GOUT_PERI_HSI2C_1_PCLK,
338         CLK_CON_GAT_GOUT_PERI_HSI2C_2_PCLK,
339         CLK_CON_GAT_GOUT_PERI_HSI2C_3_PCLK,
340         CLK_CON_GAT_GOUT_PERI_I2C_0_PCLK,
341         CLK_CON_GAT_GOUT_PERI_I2C_1_PCLK,
342         CLK_CON_GAT_GOUT_PERI_I2C_2_PCLK,
343         CLK_CON_GAT_GOUT_PERI_I2C_3_PCLK,
344         CLK_CON_GAT_GOUT_PERI_I2C_4_PCLK,
345         CLK_CON_GAT_GOUT_PERI_I2C_5_PCLK,
346         CLK_CON_GAT_GOUT_PERI_I2C_6_PCLK,
347         CLK_CON_GAT_GOUT_PERI_I2C_7_PCLK,
348         CLK_CON_GAT_GOUT_PERI_PWM_MOTOR_PCLK,
349         CLK_CON_GAT_GOUT_PERI_SPI_0_PCLK,
350         CLK_CON_GAT_GOUT_PERI_SPI_0_EXT_CLK,
351         CLK_CON_GAT_GOUT_PERI_SPI_1_PCLK,
352         CLK_CON_GAT_GOUT_PERI_SPI_1_EXT_CLK,
353         CLK_CON_GAT_GOUT_PERI_UART_0_EXT_UCLK,
354         CLK_CON_GAT_GOUT_PERI_UART_0_PCLK,
355         CLK_CON_GAT_GOUT_PERI_UART_1_EXT_UCLK,
356         CLK_CON_GAT_GOUT_PERI_UART_1_PCLK,
357         CLK_CON_GAT_GOUT_PERI_UART_2_EXT_UCLK,
358         CLK_CON_GAT_GOUT_PERI_UART_2_PCLK,
359         CLK_CON_GAT_GOUT_PERI_USI0_PCLK,
360         CLK_CON_GAT_GOUT_PERI_USI0_SCLK,
361         CLK_CON_GAT_GOUT_PERI_USI1_PCLK,
362         CLK_CON_GAT_GOUT_PERI_USI1_SCLK,
363         CLK_CON_GAT_GOUT_PERI_USI2_PCLK,
364         CLK_CON_GAT_GOUT_PERI_USI2_SCLK,
365         CLK_CON_GAT_GOUT_PERI_MCT_PCLK,
366         CLK_CON_GAT_GOUT_PERI_SYSREG_PERI_PCLK,
367         CLK_CON_GAT_GOUT_PERI_WDT_CLUSTER0_PCLK,
368         CLK_CON_GAT_GOUT_PERI_WDT_CLUSTER1_PCLK,
369 };
370
371 /* List of parent clocks for Muxes in CMU_PERI */
372 PNAME(mout_peri_bus_user_p)     = { "oscclk", "dout_peri_bus" };
373 PNAME(mout_peri_spi0_user_p)    = { "oscclk", "dout_peri_spi0" };
374 PNAME(mout_peri_spi1_user_p)    = { "oscclk", "dout_peri_spi1" };
375 PNAME(mout_peri_uart0_user_p)   = { "oscclk", "dout_peri_uart0" };
376 PNAME(mout_peri_uart1_user_p)   = { "oscclk", "dout_peri_uart1" };
377 PNAME(mout_peri_uart2_user_p)   = { "oscclk", "dout_peri_uart2" };
378 PNAME(mout_peri_usi0_user_p)    = { "oscclk", "dout_peri_usi0" };
379 PNAME(mout_peri_usi1_user_p)    = { "oscclk", "dout_peri_usi1" };
380 PNAME(mout_peri_usi2_user_p)    = { "oscclk", "dout_peri_usi2" };
381
382 static const struct samsung_mux_clock peri_mux_clks[] __initconst = {
383         MUX(CLK_MOUT_PERI_BUS_USER, "mout_peri_bus_user", mout_peri_bus_user_p,
384             PLL_CON0_MUX_CLKCMU_PERI_BUS_USER, 4, 1),
385         MUX(CLK_MOUT_PERI_SPI0_USER, "mout_peri_spi0_user", mout_peri_spi0_user_p,
386             PLL_CON0_MUX_CLKCMU_PERI_SPI0_USER, 4, 1),
387         MUX(CLK_MOUT_PERI_SPI1_USER, "mout_peri_spi1_user", mout_peri_spi1_user_p,
388             PLL_CON0_MUX_CLKCMU_PERI_SPI1_USER, 4, 1),
389         MUX(CLK_MOUT_PERI_UART0_USER, "mout_peri_uart0_user",
390             mout_peri_uart0_user_p, PLL_CON0_MUX_CLKCMU_PERI_UART0_USER, 4, 1),
391         MUX(CLK_MOUT_PERI_UART1_USER, "mout_peri_uart1_user",
392             mout_peri_uart1_user_p, PLL_CON0_MUX_CLKCMU_PERI_UART1_USER, 4, 1),
393         MUX(CLK_MOUT_PERI_UART2_USER, "mout_peri_uart2_user",
394             mout_peri_uart2_user_p, PLL_CON0_MUX_CLKCMU_PERI_UART2_USER, 4, 1),
395         MUX(CLK_MOUT_PERI_USI0_USER, "mout_peri_usi0_user",
396             mout_peri_usi0_user_p, PLL_CON0_MUX_CLKCMU_PERI_USI0_USER, 4, 1),
397         MUX(CLK_MOUT_PERI_USI1_USER, "mout_peri_usi1_user",
398             mout_peri_usi1_user_p, PLL_CON0_MUX_CLKCMU_PERI_USI1_USER, 4, 1),
399         MUX(CLK_MOUT_PERI_USI2_USER, "mout_peri_usi2_user",
400             mout_peri_usi2_user_p, PLL_CON0_MUX_CLKCMU_PERI_USI2_USER, 4, 1),
401 };
402
403 static const struct samsung_gate_clock peri_gate_clks[] __initconst = {
404         /* TODO: Should be enabled in GPIO driver (or made CLK_IS_CRITICAL) */
405         GATE(CLK_GOUT_GPIO_TOP_PCLK, "gout_gpio_top_pclk",
406              "mout_peri_bus_user",
407              CLK_CON_GAT_GOUT_PERI_GPIO_TOP_PCLK, 21, CLK_IGNORE_UNUSED, 0),
408         GATE(CLK_GOUT_HSI2C0_PCLK, "gout_hsi2c0_pclk", "mout_peri_bus_user",
409              CLK_CON_GAT_GOUT_PERI_HSI2C_0_PCLK, 21, 0, 0),
410         GATE(CLK_GOUT_HSI2C1_PCLK, "gout_hsi2c1_pclk", "mout_peri_bus_user",
411              CLK_CON_GAT_GOUT_PERI_HSI2C_1_PCLK, 21, 0, 0),
412         GATE(CLK_GOUT_HSI2C2_PCLK, "gout_hsi2c2_pclk", "mout_peri_bus_user",
413              CLK_CON_GAT_GOUT_PERI_HSI2C_2_PCLK, 21, 0, 0),
414         GATE(CLK_GOUT_HSI2C3_PCLK, "gout_hsi2c3_pclk", "mout_peri_bus_user",
415              CLK_CON_GAT_GOUT_PERI_HSI2C_3_PCLK, 21, 0, 0),
416         GATE(CLK_GOUT_I2C0_PCLK, "gout_i2c0_pclk", "mout_peri_bus_user",
417              CLK_CON_GAT_GOUT_PERI_I2C_0_PCLK, 21, 0, 0),
418         GATE(CLK_GOUT_I2C1_PCLK, "gout_i2c1_pclk", "mout_peri_bus_user",
419              CLK_CON_GAT_GOUT_PERI_I2C_1_PCLK, 21, 0, 0),
420         GATE(CLK_GOUT_I2C2_PCLK, "gout_i2c2_pclk", "mout_peri_bus_user",
421              CLK_CON_GAT_GOUT_PERI_I2C_2_PCLK, 21, 0, 0),
422         GATE(CLK_GOUT_I2C3_PCLK, "gout_i2c3_pclk", "mout_peri_bus_user",
423              CLK_CON_GAT_GOUT_PERI_I2C_3_PCLK, 21, 0, 0),
424         GATE(CLK_GOUT_I2C4_PCLK, "gout_i2c4_pclk", "mout_peri_bus_user",
425              CLK_CON_GAT_GOUT_PERI_I2C_4_PCLK, 21, 0, 0),
426         GATE(CLK_GOUT_I2C5_PCLK, "gout_i2c5_pclk", "mout_peri_bus_user",
427              CLK_CON_GAT_GOUT_PERI_I2C_5_PCLK, 21, 0, 0),
428         GATE(CLK_GOUT_I2C6_PCLK, "gout_i2c6_pclk", "mout_peri_bus_user",
429              CLK_CON_GAT_GOUT_PERI_I2C_6_PCLK, 21, 0, 0),
430         GATE(CLK_GOUT_I2C7_PCLK, "gout_i2c7_pclk", "mout_peri_bus_user",
431              CLK_CON_GAT_GOUT_PERI_I2C_7_PCLK, 21, 0, 0),
432         GATE(CLK_GOUT_PWM_MOTOR_PCLK, "gout_pwm_motor_pclk",
433              "mout_peri_bus_user",
434              CLK_CON_GAT_GOUT_PERI_PWM_MOTOR_PCLK, 21, 0, 0),
435         GATE(CLK_GOUT_SPI0_PCLK, "gout_spi0_pclk", "mout_peri_bus_user",
436              CLK_CON_GAT_GOUT_PERI_SPI_0_PCLK, 21, 0, 0),
437         GATE(CLK_GOUT_SPI0_EXT_CLK, "gout_spi0_ipclk", "mout_peri_spi0_user",
438              CLK_CON_GAT_GOUT_PERI_SPI_0_EXT_CLK, 21, 0, 0),
439         GATE(CLK_GOUT_SPI1_PCLK, "gout_spi1_pclk", "mout_peri_bus_user",
440              CLK_CON_GAT_GOUT_PERI_SPI_1_PCLK, 21, 0, 0),
441         GATE(CLK_GOUT_SPI1_EXT_CLK, "gout_spi1_ipclk", "mout_peri_spi1_user",
442              CLK_CON_GAT_GOUT_PERI_SPI_1_EXT_CLK, 21, 0, 0),
443         GATE(CLK_GOUT_UART0_EXT_UCLK, "gout_uart0_ext_uclk", "mout_peri_uart0_user",
444              CLK_CON_GAT_GOUT_PERI_UART_0_EXT_UCLK, 21, 0, 0),
445         GATE(CLK_GOUT_UART0_PCLK, "gout_uart0_pclk", "mout_peri_bus_user",
446              CLK_CON_GAT_GOUT_PERI_UART_0_PCLK, 21, 0, 0),
447         GATE(CLK_GOUT_UART1_EXT_UCLK, "gout_uart1_ext_uclk", "mout_peri_uart1_user",
448              CLK_CON_GAT_GOUT_PERI_UART_1_EXT_UCLK, 21, 0, 0),
449         GATE(CLK_GOUT_UART1_PCLK, "gout_uart1_pclk", "mout_peri_bus_user",
450              CLK_CON_GAT_GOUT_PERI_UART_1_PCLK, 21, 0, 0),
451         GATE(CLK_GOUT_UART2_EXT_UCLK, "gout_uart2_ext_uclk", "mout_peri_uart2_user",
452              CLK_CON_GAT_GOUT_PERI_UART_2_EXT_UCLK, 21, 0, 0),
453         GATE(CLK_GOUT_UART2_PCLK, "gout_uart2_pclk", "mout_peri_bus_user",
454              CLK_CON_GAT_GOUT_PERI_UART_2_PCLK, 21, 0, 0),
455         GATE(CLK_GOUT_USI0_PCLK, "gout_usi0_pclk", "mout_peri_bus_user",
456              CLK_CON_GAT_GOUT_PERI_USI0_PCLK, 21, 0, 0),
457         GATE(CLK_GOUT_USI0_SCLK, "gout_usi0_sclk", "mout_peri_usi0_user",
458              CLK_CON_GAT_GOUT_PERI_USI0_SCLK, 21, 0, 0),
459         GATE(CLK_GOUT_USI1_PCLK, "gout_usi1_pclk", "mout_peri_bus_user",
460              CLK_CON_GAT_GOUT_PERI_USI1_PCLK, 21, 0, 0),
461         GATE(CLK_GOUT_USI1_SCLK, "gout_usi1_sclk", "mout_peri_usi1_user",
462              CLK_CON_GAT_GOUT_PERI_USI1_SCLK, 21, 0, 0),
463         GATE(CLK_GOUT_USI2_PCLK, "gout_usi2_pclk", "mout_peri_bus_user",
464              CLK_CON_GAT_GOUT_PERI_USI2_PCLK, 21, 0, 0),
465         GATE(CLK_GOUT_USI2_SCLK, "gout_usi2_sclk", "mout_peri_usi2_user",
466              CLK_CON_GAT_GOUT_PERI_USI2_SCLK, 21, 0, 0),
467         GATE(CLK_GOUT_MCT_PCLK, "gout_mct_pclk", "mout_peri_bus_user",
468              CLK_CON_GAT_GOUT_PERI_MCT_PCLK, 21, 0, 0),
469         GATE(CLK_GOUT_SYSREG_PERI_PCLK, "gout_sysreg_peri_pclk",
470              "mout_peri_bus_user",
471              CLK_CON_GAT_GOUT_PERI_SYSREG_PERI_PCLK, 21, 0, 0),
472         GATE(CLK_GOUT_WDT0_PCLK, "gout_wdt0_pclk", "mout_peri_bus_user",
473              CLK_CON_GAT_GOUT_PERI_WDT_CLUSTER0_PCLK, 21, 0, 0),
474         GATE(CLK_GOUT_WDT1_PCLK, "gout_wdt1_pclk", "mout_peri_bus_user",
475              CLK_CON_GAT_GOUT_PERI_WDT_CLUSTER1_PCLK, 21, 0, 0),
476 };
477
478 static const struct samsung_cmu_info peri_cmu_info __initconst = {
479         .mux_clks               = peri_mux_clks,
480         .nr_mux_clks            = ARRAY_SIZE(peri_mux_clks),
481         .gate_clks              = peri_gate_clks,
482         .nr_gate_clks           = ARRAY_SIZE(peri_gate_clks),
483         .nr_clk_ids             = PERI_NR_CLK,
484         .clk_regs               = peri_clk_regs,
485         .nr_clk_regs            = ARRAY_SIZE(peri_clk_regs),
486         .clk_name               = "dout_peri_bus",
487 };
488
489 static void __init exynos7885_cmu_peri_init(struct device_node *np)
490 {
491         exynos_arm64_register_cmu(NULL, np, &peri_cmu_info);
492 }
493
494 /* Register CMU_PERI early, as it's needed for MCT timer */
495 CLK_OF_DECLARE(exynos7885_cmu_peri, "samsung,exynos7885-cmu-peri",
496                exynos7885_cmu_peri_init);
497
498 /* ---- CMU_CORE ------------------------------------------------------------ */
499
500 /* Register Offset definitions for CMU_CORE (0x12000000) */
501 #define PLL_CON0_MUX_CLKCMU_CORE_BUS_USER       0x0100
502 #define PLL_CON0_MUX_CLKCMU_CORE_CCI_USER       0x0120
503 #define PLL_CON0_MUX_CLKCMU_CORE_G3D_USER       0x0140
504 #define CLK_CON_MUX_MUX_CLK_CORE_GIC            0x1000
505 #define CLK_CON_DIV_DIV_CLK_CORE_BUSP           0x1800
506 #define CLK_CON_GAT_GOUT_CORE_CCI_550_ACLK      0x2054
507 #define CLK_CON_GAT_GOUT_CORE_GIC400_CLK        0x2058
508
509 static const unsigned long core_clk_regs[] __initconst = {
510         PLL_CON0_MUX_CLKCMU_CORE_BUS_USER,
511         PLL_CON0_MUX_CLKCMU_CORE_CCI_USER,
512         PLL_CON0_MUX_CLKCMU_CORE_G3D_USER,
513         CLK_CON_MUX_MUX_CLK_CORE_GIC,
514         CLK_CON_DIV_DIV_CLK_CORE_BUSP,
515         CLK_CON_GAT_GOUT_CORE_CCI_550_ACLK,
516         CLK_CON_GAT_GOUT_CORE_GIC400_CLK,
517 };
518
519 /* List of parent clocks for Muxes in CMU_CORE */
520 PNAME(mout_core_bus_user_p)             = { "oscclk", "dout_core_bus" };
521 PNAME(mout_core_cci_user_p)             = { "oscclk", "dout_core_cci" };
522 PNAME(mout_core_g3d_user_p)             = { "oscclk", "dout_core_g3d" };
523 PNAME(mout_core_gic_p)                  = { "dout_core_busp", "oscclk" };
524
525 static const struct samsung_mux_clock core_mux_clks[] __initconst = {
526         MUX(CLK_MOUT_CORE_BUS_USER, "mout_core_bus_user", mout_core_bus_user_p,
527             PLL_CON0_MUX_CLKCMU_CORE_BUS_USER, 4, 1),
528         MUX(CLK_MOUT_CORE_CCI_USER, "mout_core_cci_user", mout_core_cci_user_p,
529             PLL_CON0_MUX_CLKCMU_CORE_CCI_USER, 4, 1),
530         MUX(CLK_MOUT_CORE_G3D_USER, "mout_core_g3d_user", mout_core_g3d_user_p,
531             PLL_CON0_MUX_CLKCMU_CORE_G3D_USER, 4, 1),
532         MUX(CLK_MOUT_CORE_GIC, "mout_core_gic", mout_core_gic_p,
533             CLK_CON_MUX_MUX_CLK_CORE_GIC, 0, 1),
534 };
535
536 static const struct samsung_div_clock core_div_clks[] __initconst = {
537         DIV(CLK_DOUT_CORE_BUSP, "dout_core_busp", "mout_core_bus_user",
538             CLK_CON_DIV_DIV_CLK_CORE_BUSP, 0, 2),
539 };
540
541 static const struct samsung_gate_clock core_gate_clks[] __initconst = {
542         /* CCI (interconnect) clock must be always running */
543         GATE(CLK_GOUT_CCI_ACLK, "gout_cci_aclk", "mout_core_cci_user",
544              CLK_CON_GAT_GOUT_CORE_CCI_550_ACLK, 21, CLK_IS_CRITICAL, 0),
545         /* GIC (interrupt controller) clock must be always running */
546         GATE(CLK_GOUT_GIC400_CLK, "gout_gic400_clk", "mout_core_gic",
547              CLK_CON_GAT_GOUT_CORE_GIC400_CLK, 21, CLK_IS_CRITICAL, 0),
548 };
549
550 static const struct samsung_cmu_info core_cmu_info __initconst = {
551         .mux_clks               = core_mux_clks,
552         .nr_mux_clks            = ARRAY_SIZE(core_mux_clks),
553         .div_clks               = core_div_clks,
554         .nr_div_clks            = ARRAY_SIZE(core_div_clks),
555         .gate_clks              = core_gate_clks,
556         .nr_gate_clks           = ARRAY_SIZE(core_gate_clks),
557         .nr_clk_ids             = CORE_NR_CLK,
558         .clk_regs               = core_clk_regs,
559         .nr_clk_regs            = ARRAY_SIZE(core_clk_regs),
560         .clk_name               = "dout_core_bus",
561 };
562
563 /* ---- platform_driver ----------------------------------------------------- */
564
565 static int __init exynos7885_cmu_probe(struct platform_device *pdev)
566 {
567         const struct samsung_cmu_info *info;
568         struct device *dev = &pdev->dev;
569
570         info = of_device_get_match_data(dev);
571         exynos_arm64_register_cmu(dev, dev->of_node, info);
572
573         return 0;
574 }
575
576 static const struct of_device_id exynos7885_cmu_of_match[] = {
577         {
578                 .compatible = "samsung,exynos7885-cmu-core",
579                 .data = &core_cmu_info,
580         }, {
581         },
582 };
583
584 static struct platform_driver exynos7885_cmu_driver __refdata = {
585         .driver = {
586                 .name = "exynos7885-cmu",
587                 .of_match_table = exynos7885_cmu_of_match,
588                 .suppress_bind_attrs = true,
589         },
590         .probe = exynos7885_cmu_probe,
591 };
592
593 static int __init exynos7885_cmu_init(void)
594 {
595         return platform_driver_register(&exynos7885_cmu_driver);
596 }
597 core_initcall(exynos7885_cmu_init);