1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3 * Copyright (C) 2021 Linaro Ltd.
4 * Author: Sam Protsenko <semen.protsenko@linaro.org>
5 *
6 * Common Clock Framework support for Exynos850 SoC.
7 */
8
9 #include <linux/clk.h>
10 #include <linux/clk-provider.h>
11 #include <linux/of.h>
12 #include <linux/of_address.h>
13 #include <linux/of_device.h>
14 #include <linux/platform_device.h>
15
16 #include <dt-bindings/clock/exynos850.h>
17
18 #include "clk.h"
19
20 /* Gate register bits */
21 #define GATE_MANUAL BIT(20)
22 #define GATE_ENABLE_HWACG BIT(28)
23
24 /* Gate register offsets range */
25 #define GATE_OFF_START 0x2000
26 #define GATE_OFF_END 0x2fff
27
28 /**
29 * exynos850_init_clocks - Set clocks initial configuration
30 * @np: CMU device tree node with "reg" property (CMU addr)
31 * @reg_offs: Register offsets array for clocks to init
32 * @reg_offs_len: Number of register offsets in reg_offs array
33 *
34 * Set manual control mode for all gate clocks.
35 */
exynos850_init_clocks(struct device_node * np,const unsigned long * reg_offs,size_t reg_offs_len)36 static void __init exynos850_init_clocks(struct device_node *np,
37 const unsigned long *reg_offs, size_t reg_offs_len)
38 {
39 void __iomem *reg_base;
40 size_t i;
41
42 reg_base = of_iomap(np, 0);
43 if (!reg_base)
44 panic("%s: failed to map registers\n", __func__);
45
46 for (i = 0; i < reg_offs_len; ++i) {
47 void __iomem *reg = reg_base + reg_offs[i];
48 u32 val;
49
50 /* Modify only gate clock registers */
51 if (reg_offs[i] < GATE_OFF_START || reg_offs[i] > GATE_OFF_END)
52 continue;
53
54 val = readl(reg);
55 val |= GATE_MANUAL;
56 val &= ~GATE_ENABLE_HWACG;
57 writel(val, reg);
58 }
59
60 iounmap(reg_base);
61 }
62
63 /* ---- CMU_TOP ------------------------------------------------------------- */
64
65 /* Register Offset definitions for CMU_TOP (0x120e0000) */
66 #define PLL_LOCKTIME_PLL_MMC 0x0000
67 #define PLL_LOCKTIME_PLL_SHARED0 0x0004
68 #define PLL_LOCKTIME_PLL_SHARED1 0x0008
69 #define PLL_CON0_PLL_MMC 0x0100
70 #define PLL_CON3_PLL_MMC 0x010c
71 #define PLL_CON0_PLL_SHARED0 0x0140
72 #define PLL_CON3_PLL_SHARED0 0x014c
73 #define PLL_CON0_PLL_SHARED1 0x0180
74 #define PLL_CON3_PLL_SHARED1 0x018c
75 #define CLK_CON_MUX_MUX_CLKCMU_CORE_BUS 0x1014
76 #define CLK_CON_MUX_MUX_CLKCMU_CORE_CCI 0x1018
77 #define CLK_CON_MUX_MUX_CLKCMU_CORE_MMC_EMBD 0x101c
78 #define CLK_CON_MUX_MUX_CLKCMU_CORE_SSS 0x1020
79 #define CLK_CON_MUX_MUX_CLKCMU_DPU 0x1034
80 #define CLK_CON_MUX_MUX_CLKCMU_HSI_BUS 0x103c
81 #define CLK_CON_MUX_MUX_CLKCMU_HSI_MMC_CARD 0x1040
82 #define CLK_CON_MUX_MUX_CLKCMU_HSI_USB20DRD 0x1044
83 #define CLK_CON_MUX_MUX_CLKCMU_PERI_BUS 0x1070
84 #define CLK_CON_MUX_MUX_CLKCMU_PERI_IP 0x1074
85 #define CLK_CON_MUX_MUX_CLKCMU_PERI_UART 0x1078
86 #define CLK_CON_DIV_CLKCMU_CORE_BUS 0x1820
87 #define CLK_CON_DIV_CLKCMU_CORE_CCI 0x1824
88 #define CLK_CON_DIV_CLKCMU_CORE_MMC_EMBD 0x1828
89 #define CLK_CON_DIV_CLKCMU_CORE_SSS 0x182c
90 #define CLK_CON_DIV_CLKCMU_DPU 0x1840
91 #define CLK_CON_DIV_CLKCMU_HSI_BUS 0x1848
92 #define CLK_CON_DIV_CLKCMU_HSI_MMC_CARD 0x184c
93 #define CLK_CON_DIV_CLKCMU_HSI_USB20DRD 0x1850
94 #define CLK_CON_DIV_CLKCMU_PERI_BUS 0x187c
95 #define CLK_CON_DIV_CLKCMU_PERI_IP 0x1880
96 #define CLK_CON_DIV_CLKCMU_PERI_UART 0x1884
97 #define CLK_CON_DIV_PLL_SHARED0_DIV2 0x188c
98 #define CLK_CON_DIV_PLL_SHARED0_DIV3 0x1890
99 #define CLK_CON_DIV_PLL_SHARED0_DIV4 0x1894
100 #define CLK_CON_DIV_PLL_SHARED1_DIV2 0x1898
101 #define CLK_CON_DIV_PLL_SHARED1_DIV3 0x189c
102 #define CLK_CON_DIV_PLL_SHARED1_DIV4 0x18a0
103 #define CLK_CON_GAT_GATE_CLKCMU_CORE_BUS 0x201c
104 #define CLK_CON_GAT_GATE_CLKCMU_CORE_CCI 0x2020
105 #define CLK_CON_GAT_GATE_CLKCMU_CORE_MMC_EMBD 0x2024
106 #define CLK_CON_GAT_GATE_CLKCMU_CORE_SSS 0x2028
107 #define CLK_CON_GAT_GATE_CLKCMU_DPU 0x203c
108 #define CLK_CON_GAT_GATE_CLKCMU_HSI_BUS 0x2044
109 #define CLK_CON_GAT_GATE_CLKCMU_HSI_MMC_CARD 0x2048
110 #define CLK_CON_GAT_GATE_CLKCMU_HSI_USB20DRD 0x204c
111 #define CLK_CON_GAT_GATE_CLKCMU_PERI_BUS 0x2080
112 #define CLK_CON_GAT_GATE_CLKCMU_PERI_IP 0x2084
113 #define CLK_CON_GAT_GATE_CLKCMU_PERI_UART 0x2088
114
115 static const unsigned long top_clk_regs[] __initconst = {
116 PLL_LOCKTIME_PLL_MMC,
117 PLL_LOCKTIME_PLL_SHARED0,
118 PLL_LOCKTIME_PLL_SHARED1,
119 PLL_CON0_PLL_MMC,
120 PLL_CON3_PLL_MMC,
121 PLL_CON0_PLL_SHARED0,
122 PLL_CON3_PLL_SHARED0,
123 PLL_CON0_PLL_SHARED1,
124 PLL_CON3_PLL_SHARED1,
125 CLK_CON_MUX_MUX_CLKCMU_CORE_BUS,
126 CLK_CON_MUX_MUX_CLKCMU_CORE_CCI,
127 CLK_CON_MUX_MUX_CLKCMU_CORE_MMC_EMBD,
128 CLK_CON_MUX_MUX_CLKCMU_CORE_SSS,
129 CLK_CON_MUX_MUX_CLKCMU_DPU,
130 CLK_CON_MUX_MUX_CLKCMU_HSI_BUS,
131 CLK_CON_MUX_MUX_CLKCMU_HSI_MMC_CARD,
132 CLK_CON_MUX_MUX_CLKCMU_HSI_USB20DRD,
133 CLK_CON_MUX_MUX_CLKCMU_PERI_BUS,
134 CLK_CON_MUX_MUX_CLKCMU_PERI_IP,
135 CLK_CON_MUX_MUX_CLKCMU_PERI_UART,
136 CLK_CON_DIV_CLKCMU_CORE_BUS,
137 CLK_CON_DIV_CLKCMU_CORE_CCI,
138 CLK_CON_DIV_CLKCMU_CORE_MMC_EMBD,
139 CLK_CON_DIV_CLKCMU_CORE_SSS,
140 CLK_CON_DIV_CLKCMU_DPU,
141 CLK_CON_DIV_CLKCMU_HSI_BUS,
142 CLK_CON_DIV_CLKCMU_HSI_MMC_CARD,
143 CLK_CON_DIV_CLKCMU_HSI_USB20DRD,
144 CLK_CON_DIV_CLKCMU_PERI_BUS,
145 CLK_CON_DIV_CLKCMU_PERI_IP,
146 CLK_CON_DIV_CLKCMU_PERI_UART,
147 CLK_CON_DIV_PLL_SHARED0_DIV2,
148 CLK_CON_DIV_PLL_SHARED0_DIV3,
149 CLK_CON_DIV_PLL_SHARED0_DIV4,
150 CLK_CON_DIV_PLL_SHARED1_DIV2,
151 CLK_CON_DIV_PLL_SHARED1_DIV3,
152 CLK_CON_DIV_PLL_SHARED1_DIV4,
153 CLK_CON_GAT_GATE_CLKCMU_CORE_BUS,
154 CLK_CON_GAT_GATE_CLKCMU_CORE_CCI,
155 CLK_CON_GAT_GATE_CLKCMU_CORE_MMC_EMBD,
156 CLK_CON_GAT_GATE_CLKCMU_CORE_SSS,
157 CLK_CON_GAT_GATE_CLKCMU_DPU,
158 CLK_CON_GAT_GATE_CLKCMU_HSI_BUS,
159 CLK_CON_GAT_GATE_CLKCMU_HSI_MMC_CARD,
160 CLK_CON_GAT_GATE_CLKCMU_HSI_USB20DRD,
161 CLK_CON_GAT_GATE_CLKCMU_PERI_BUS,
162 CLK_CON_GAT_GATE_CLKCMU_PERI_IP,
163 CLK_CON_GAT_GATE_CLKCMU_PERI_UART,
164 };
165
166 /*
167 * Do not provide PLL tables to core PLLs, as MANUAL_PLL_CTRL bit is not set
168 * for those PLLs by default, so set_rate operation would fail.
169 */
170 static const struct samsung_pll_clock top_pll_clks[] __initconst = {
171 /* CMU_TOP_PURECLKCOMP */
172 PLL(pll_0822x, CLK_FOUT_SHARED0_PLL, "fout_shared0_pll", "oscclk",
173 PLL_LOCKTIME_PLL_SHARED0, PLL_CON3_PLL_SHARED0,
174 NULL),
175 PLL(pll_0822x, CLK_FOUT_SHARED1_PLL, "fout_shared1_pll", "oscclk",
176 PLL_LOCKTIME_PLL_SHARED1, PLL_CON3_PLL_SHARED1,
177 NULL),
178 PLL(pll_0831x, CLK_FOUT_MMC_PLL, "fout_mmc_pll", "oscclk",
179 PLL_LOCKTIME_PLL_MMC, PLL_CON3_PLL_MMC, NULL),
180 };
181
182 /* List of parent clocks for Muxes in CMU_TOP */
183 PNAME(mout_shared0_pll_p) = { "oscclk", "fout_shared0_pll" };
184 PNAME(mout_shared1_pll_p) = { "oscclk", "fout_shared1_pll" };
185 PNAME(mout_mmc_pll_p) = { "oscclk", "fout_mmc_pll" };
186 /* List of parent clocks for Muxes in CMU_TOP: for CMU_CORE */
187 PNAME(mout_core_bus_p) = { "dout_shared1_div2", "dout_shared0_div3",
188 "dout_shared1_div3", "dout_shared0_div4" };
189 PNAME(mout_core_cci_p) = { "dout_shared0_div2", "dout_shared1_div2",
190 "dout_shared0_div3", "dout_shared1_div3" };
191 PNAME(mout_core_mmc_embd_p) = { "oscclk", "dout_shared0_div2",
192 "dout_shared1_div2", "dout_shared0_div3",
193 "dout_shared1_div3", "mout_mmc_pll",
194 "oscclk", "oscclk" };
195 PNAME(mout_core_sss_p) = { "dout_shared0_div3", "dout_shared1_div3",
196 "dout_shared0_div4", "dout_shared1_div4" };
197 /* List of parent clocks for Muxes in CMU_TOP: for CMU_HSI */
198 PNAME(mout_hsi_bus_p) = { "dout_shared0_div2", "dout_shared1_div2" };
199 PNAME(mout_hsi_mmc_card_p) = { "oscclk", "dout_shared0_div2",
200 "dout_shared1_div2", "dout_shared0_div3",
201 "dout_shared1_div3", "mout_mmc_pll",
202 "oscclk", "oscclk" };
203 PNAME(mout_hsi_usb20drd_p) = { "oscclk", "dout_shared0_div4",
204 "dout_shared1_div4", "oscclk" };
205 /* List of parent clocks for Muxes in CMU_TOP: for CMU_PERI */
206 PNAME(mout_peri_bus_p) = { "dout_shared0_div4", "dout_shared1_div4" };
207 PNAME(mout_peri_uart_p) = { "oscclk", "dout_shared0_div4",
208 "dout_shared1_div4", "oscclk" };
209 PNAME(mout_peri_ip_p) = { "oscclk", "dout_shared0_div4",
210 "dout_shared1_div4", "oscclk" };
211
212 /* List of parent clocks for Muxes in CMU_TOP: for CMU_DPU */
213 PNAME(mout_dpu_p) = { "dout_shared0_div3", "dout_shared1_div3",
214 "dout_shared0_div4", "dout_shared1_div4" };
215
216 static const struct samsung_mux_clock top_mux_clks[] __initconst = {
217 /* CMU_TOP_PURECLKCOMP */
218 MUX(CLK_MOUT_SHARED0_PLL, "mout_shared0_pll", mout_shared0_pll_p,
219 PLL_CON0_PLL_SHARED0, 4, 1),
220 MUX(CLK_MOUT_SHARED1_PLL, "mout_shared1_pll", mout_shared1_pll_p,
221 PLL_CON0_PLL_SHARED1, 4, 1),
222 MUX(CLK_MOUT_MMC_PLL, "mout_mmc_pll", mout_mmc_pll_p,
223 PLL_CON0_PLL_MMC, 4, 1),
224
225 /* CORE */
226 MUX(CLK_MOUT_CORE_BUS, "mout_core_bus", mout_core_bus_p,
227 CLK_CON_MUX_MUX_CLKCMU_CORE_BUS, 0, 2),
228 MUX(CLK_MOUT_CORE_CCI, "mout_core_cci", mout_core_cci_p,
229 CLK_CON_MUX_MUX_CLKCMU_CORE_CCI, 0, 2),
230 MUX(CLK_MOUT_CORE_MMC_EMBD, "mout_core_mmc_embd", mout_core_mmc_embd_p,
231 CLK_CON_MUX_MUX_CLKCMU_CORE_MMC_EMBD, 0, 3),
232 MUX(CLK_MOUT_CORE_SSS, "mout_core_sss", mout_core_sss_p,
233 CLK_CON_MUX_MUX_CLKCMU_CORE_SSS, 0, 2),
234
235 /* DPU */
236 MUX(CLK_MOUT_DPU, "mout_dpu", mout_dpu_p,
237 CLK_CON_MUX_MUX_CLKCMU_DPU, 0, 2),
238
239 /* HSI */
240 MUX(CLK_MOUT_HSI_BUS, "mout_hsi_bus", mout_hsi_bus_p,
241 CLK_CON_MUX_MUX_CLKCMU_HSI_BUS, 0, 1),
242 MUX(CLK_MOUT_HSI_MMC_CARD, "mout_hsi_mmc_card", mout_hsi_mmc_card_p,
243 CLK_CON_MUX_MUX_CLKCMU_HSI_MMC_CARD, 0, 3),
244 MUX(CLK_MOUT_HSI_USB20DRD, "mout_hsi_usb20drd", mout_hsi_usb20drd_p,
245 CLK_CON_MUX_MUX_CLKCMU_HSI_USB20DRD, 0, 2),
246
247 /* PERI */
248 MUX(CLK_MOUT_PERI_BUS, "mout_peri_bus", mout_peri_bus_p,
249 CLK_CON_MUX_MUX_CLKCMU_PERI_BUS, 0, 1),
250 MUX(CLK_MOUT_PERI_UART, "mout_peri_uart", mout_peri_uart_p,
251 CLK_CON_MUX_MUX_CLKCMU_PERI_UART, 0, 2),
252 MUX(CLK_MOUT_PERI_IP, "mout_peri_ip", mout_peri_ip_p,
253 CLK_CON_MUX_MUX_CLKCMU_PERI_IP, 0, 2),
254 };
255
256 static const struct samsung_div_clock top_div_clks[] __initconst = {
257 /* CMU_TOP_PURECLKCOMP */
258 DIV(CLK_DOUT_SHARED0_DIV3, "dout_shared0_div3", "mout_shared0_pll",
259 CLK_CON_DIV_PLL_SHARED0_DIV3, 0, 2),
260 DIV(CLK_DOUT_SHARED0_DIV2, "dout_shared0_div2", "mout_shared0_pll",
261 CLK_CON_DIV_PLL_SHARED0_DIV2, 0, 1),
262 DIV(CLK_DOUT_SHARED1_DIV3, "dout_shared1_div3", "mout_shared1_pll",
263 CLK_CON_DIV_PLL_SHARED1_DIV3, 0, 2),
264 DIV(CLK_DOUT_SHARED1_DIV2, "dout_shared1_div2", "mout_shared1_pll",
265 CLK_CON_DIV_PLL_SHARED1_DIV2, 0, 1),
266 DIV(CLK_DOUT_SHARED0_DIV4, "dout_shared0_div4", "dout_shared0_div2",
267 CLK_CON_DIV_PLL_SHARED0_DIV4, 0, 1),
268 DIV(CLK_DOUT_SHARED1_DIV4, "dout_shared1_div4", "dout_shared1_div2",
269 CLK_CON_DIV_PLL_SHARED1_DIV4, 0, 1),
270
271 /* CORE */
272 DIV(CLK_DOUT_CORE_BUS, "dout_core_bus", "gout_core_bus",
273 CLK_CON_DIV_CLKCMU_CORE_BUS, 0, 4),
274 DIV(CLK_DOUT_CORE_CCI, "dout_core_cci", "gout_core_cci",
275 CLK_CON_DIV_CLKCMU_CORE_CCI, 0, 4),
276 DIV(CLK_DOUT_CORE_MMC_EMBD, "dout_core_mmc_embd", "gout_core_mmc_embd",
277 CLK_CON_DIV_CLKCMU_CORE_MMC_EMBD, 0, 9),
278 DIV(CLK_DOUT_CORE_SSS, "dout_core_sss", "gout_core_sss",
279 CLK_CON_DIV_CLKCMU_CORE_SSS, 0, 4),
280
281 /* DPU */
282 DIV(CLK_DOUT_DPU, "dout_dpu", "gout_dpu",
283 CLK_CON_DIV_CLKCMU_DPU, 0, 4),
284
285 /* HSI */
286 DIV(CLK_DOUT_HSI_BUS, "dout_hsi_bus", "gout_hsi_bus",
287 CLK_CON_DIV_CLKCMU_HSI_BUS, 0, 4),
288 DIV(CLK_DOUT_HSI_MMC_CARD, "dout_hsi_mmc_card", "gout_hsi_mmc_card",
289 CLK_CON_DIV_CLKCMU_HSI_MMC_CARD, 0, 9),
290 DIV(CLK_DOUT_HSI_USB20DRD, "dout_hsi_usb20drd", "gout_hsi_usb20drd",
291 CLK_CON_DIV_CLKCMU_HSI_USB20DRD, 0, 4),
292
293 /* PERI */
294 DIV(CLK_DOUT_PERI_BUS, "dout_peri_bus", "gout_peri_bus",
295 CLK_CON_DIV_CLKCMU_PERI_BUS, 0, 4),
296 DIV(CLK_DOUT_PERI_UART, "dout_peri_uart", "gout_peri_uart",
297 CLK_CON_DIV_CLKCMU_PERI_UART, 0, 4),
298 DIV(CLK_DOUT_PERI_IP, "dout_peri_ip", "gout_peri_ip",
299 CLK_CON_DIV_CLKCMU_PERI_IP, 0, 4),
300 };
301
302 static const struct samsung_gate_clock top_gate_clks[] __initconst = {
303 /* CORE */
304 GATE(CLK_GOUT_CORE_BUS, "gout_core_bus", "mout_core_bus",
305 CLK_CON_GAT_GATE_CLKCMU_CORE_BUS, 21, 0, 0),
306 GATE(CLK_GOUT_CORE_CCI, "gout_core_cci", "mout_core_cci",
307 CLK_CON_GAT_GATE_CLKCMU_CORE_CCI, 21, 0, 0),
308 GATE(CLK_GOUT_CORE_MMC_EMBD, "gout_core_mmc_embd", "mout_core_mmc_embd",
309 CLK_CON_GAT_GATE_CLKCMU_CORE_MMC_EMBD, 21, 0, 0),
310 GATE(CLK_GOUT_CORE_SSS, "gout_core_sss", "mout_core_sss",
311 CLK_CON_GAT_GATE_CLKCMU_CORE_SSS, 21, 0, 0),
312
313 /* DPU */
314 GATE(CLK_GOUT_DPU, "gout_dpu", "mout_dpu",
315 CLK_CON_GAT_GATE_CLKCMU_DPU, 21, 0, 0),
316
317 /* HSI */
318 GATE(CLK_GOUT_HSI_BUS, "gout_hsi_bus", "mout_hsi_bus",
319 CLK_CON_GAT_GATE_CLKCMU_HSI_BUS, 21, 0, 0),
320 GATE(CLK_GOUT_HSI_MMC_CARD, "gout_hsi_mmc_card", "mout_hsi_mmc_card",
321 CLK_CON_GAT_GATE_CLKCMU_HSI_MMC_CARD, 21, 0, 0),
322 GATE(CLK_GOUT_HSI_USB20DRD, "gout_hsi_usb20drd", "mout_hsi_usb20drd",
323 CLK_CON_GAT_GATE_CLKCMU_HSI_USB20DRD, 21, 0, 0),
324
325 /* PERI */
326 GATE(CLK_GOUT_PERI_BUS, "gout_peri_bus", "mout_peri_bus",
327 CLK_CON_GAT_GATE_CLKCMU_PERI_BUS, 21, 0, 0),
328 GATE(CLK_GOUT_PERI_UART, "gout_peri_uart", "mout_peri_uart",
329 CLK_CON_GAT_GATE_CLKCMU_PERI_UART, 21, 0, 0),
330 GATE(CLK_GOUT_PERI_IP, "gout_peri_ip", "mout_peri_ip",
331 CLK_CON_GAT_GATE_CLKCMU_PERI_IP, 21, 0, 0),
332 };
333
334 static const struct samsung_cmu_info top_cmu_info __initconst = {
335 .pll_clks = top_pll_clks,
336 .nr_pll_clks = ARRAY_SIZE(top_pll_clks),
337 .mux_clks = top_mux_clks,
338 .nr_mux_clks = ARRAY_SIZE(top_mux_clks),
339 .div_clks = top_div_clks,
340 .nr_div_clks = ARRAY_SIZE(top_div_clks),
341 .gate_clks = top_gate_clks,
342 .nr_gate_clks = ARRAY_SIZE(top_gate_clks),
343 .nr_clk_ids = TOP_NR_CLK,
344 .clk_regs = top_clk_regs,
345 .nr_clk_regs = ARRAY_SIZE(top_clk_regs),
346 };
347
exynos850_cmu_top_init(struct device_node * np)348 static void __init exynos850_cmu_top_init(struct device_node *np)
349 {
350 exynos850_init_clocks(np, top_clk_regs, ARRAY_SIZE(top_clk_regs));
351 samsung_cmu_register_one(np, &top_cmu_info);
352 }
353
354 CLK_OF_DECLARE(exynos850_cmu_top, "samsung,exynos850-cmu-top",
355 exynos850_cmu_top_init);
356
357 /* ---- CMU_HSI ------------------------------------------------------------- */
358
359 /* Register Offset definitions for CMU_HSI (0x13400000) */
360 #define PLL_CON0_MUX_CLKCMU_HSI_BUS_USER 0x0600
361 #define PLL_CON0_MUX_CLKCMU_HSI_MMC_CARD_USER 0x0610
362 #define PLL_CON0_MUX_CLKCMU_HSI_USB20DRD_USER 0x0620
363 #define CLK_CON_MUX_MUX_CLK_HSI_RTC 0x1000
364 #define CLK_CON_GAT_HSI_USB20DRD_TOP_I_RTC_CLK__ALV 0x2008
365 #define CLK_CON_GAT_HSI_USB20DRD_TOP_I_REF_CLK_50 0x200c
366 #define CLK_CON_GAT_HSI_USB20DRD_TOP_I_PHY_REFCLK_26 0x2010
367 #define CLK_CON_GAT_GOUT_HSI_GPIO_HSI_PCLK 0x2018
368 #define CLK_CON_GAT_GOUT_HSI_MMC_CARD_I_ACLK 0x2024
369 #define CLK_CON_GAT_GOUT_HSI_MMC_CARD_SDCLKIN 0x2028
370 #define CLK_CON_GAT_GOUT_HSI_SYSREG_HSI_PCLK 0x2038
371 #define CLK_CON_GAT_GOUT_HSI_USB20DRD_TOP_ACLK_PHYCTRL_20 0x203c
372 #define CLK_CON_GAT_GOUT_HSI_USB20DRD_TOP_BUS_CLK_EARLY 0x2040
373
374 static const unsigned long hsi_clk_regs[] __initconst = {
375 PLL_CON0_MUX_CLKCMU_HSI_BUS_USER,
376 PLL_CON0_MUX_CLKCMU_HSI_MMC_CARD_USER,
377 PLL_CON0_MUX_CLKCMU_HSI_USB20DRD_USER,
378 CLK_CON_MUX_MUX_CLK_HSI_RTC,
379 CLK_CON_GAT_HSI_USB20DRD_TOP_I_RTC_CLK__ALV,
380 CLK_CON_GAT_HSI_USB20DRD_TOP_I_REF_CLK_50,
381 CLK_CON_GAT_HSI_USB20DRD_TOP_I_PHY_REFCLK_26,
382 CLK_CON_GAT_GOUT_HSI_GPIO_HSI_PCLK,
383 CLK_CON_GAT_GOUT_HSI_MMC_CARD_I_ACLK,
384 CLK_CON_GAT_GOUT_HSI_MMC_CARD_SDCLKIN,
385 CLK_CON_GAT_GOUT_HSI_SYSREG_HSI_PCLK,
386 CLK_CON_GAT_GOUT_HSI_USB20DRD_TOP_ACLK_PHYCTRL_20,
387 CLK_CON_GAT_GOUT_HSI_USB20DRD_TOP_BUS_CLK_EARLY,
388 };
389
390 /* List of parent clocks for Muxes in CMU_PERI */
391 PNAME(mout_hsi_bus_user_p) = { "oscclk", "dout_hsi_bus" };
392 PNAME(mout_hsi_mmc_card_user_p) = { "oscclk", "dout_hsi_mmc_card" };
393 PNAME(mout_hsi_usb20drd_user_p) = { "oscclk", "dout_hsi_usb20drd" };
394 PNAME(mout_hsi_rtc_p) = { "rtcclk", "oscclk" };
395
396 static const struct samsung_mux_clock hsi_mux_clks[] __initconst = {
397 MUX(CLK_MOUT_HSI_BUS_USER, "mout_hsi_bus_user", mout_hsi_bus_user_p,
398 PLL_CON0_MUX_CLKCMU_HSI_BUS_USER, 4, 1),
399 MUX_F(CLK_MOUT_HSI_MMC_CARD_USER, "mout_hsi_mmc_card_user",
400 mout_hsi_mmc_card_user_p, PLL_CON0_MUX_CLKCMU_HSI_MMC_CARD_USER,
401 4, 1, CLK_SET_RATE_PARENT, 0),
402 MUX(CLK_MOUT_HSI_USB20DRD_USER, "mout_hsi_usb20drd_user",
403 mout_hsi_usb20drd_user_p, PLL_CON0_MUX_CLKCMU_HSI_USB20DRD_USER,
404 4, 1),
405 MUX(CLK_MOUT_HSI_RTC, "mout_hsi_rtc", mout_hsi_rtc_p,
406 CLK_CON_MUX_MUX_CLK_HSI_RTC, 0, 1),
407 };
408
409 static const struct samsung_gate_clock hsi_gate_clks[] __initconst = {
410 GATE(CLK_GOUT_USB_RTC_CLK, "gout_usb_rtc", "mout_hsi_rtc",
411 CLK_CON_GAT_HSI_USB20DRD_TOP_I_RTC_CLK__ALV, 21, 0, 0),
412 GATE(CLK_GOUT_USB_REF_CLK, "gout_usb_ref", "mout_hsi_usb20drd_user",
413 CLK_CON_GAT_HSI_USB20DRD_TOP_I_REF_CLK_50, 21, 0, 0),
414 GATE(CLK_GOUT_USB_PHY_REF_CLK, "gout_usb_phy_ref", "oscclk",
415 CLK_CON_GAT_HSI_USB20DRD_TOP_I_PHY_REFCLK_26, 21, 0, 0),
416 GATE(CLK_GOUT_GPIO_HSI_PCLK, "gout_gpio_hsi_pclk", "mout_hsi_bus_user",
417 CLK_CON_GAT_GOUT_HSI_GPIO_HSI_PCLK, 21, 0, 0),
418 GATE(CLK_GOUT_MMC_CARD_ACLK, "gout_mmc_card_aclk", "mout_hsi_bus_user",
419 CLK_CON_GAT_GOUT_HSI_MMC_CARD_I_ACLK, 21, 0, 0),
420 GATE(CLK_GOUT_MMC_CARD_SDCLKIN, "gout_mmc_card_sdclkin",
421 "mout_hsi_mmc_card_user",
422 CLK_CON_GAT_GOUT_HSI_MMC_CARD_SDCLKIN, 21, CLK_SET_RATE_PARENT, 0),
423 GATE(CLK_GOUT_SYSREG_HSI_PCLK, "gout_sysreg_hsi_pclk",
424 "mout_hsi_bus_user",
425 CLK_CON_GAT_GOUT_HSI_SYSREG_HSI_PCLK, 21, 0, 0),
426 GATE(CLK_GOUT_USB_PHY_ACLK, "gout_usb_phy_aclk", "mout_hsi_bus_user",
427 CLK_CON_GAT_GOUT_HSI_USB20DRD_TOP_ACLK_PHYCTRL_20, 21, 0, 0),
428 GATE(CLK_GOUT_USB_BUS_EARLY_CLK, "gout_usb_bus_early",
429 "mout_hsi_bus_user",
430 CLK_CON_GAT_GOUT_HSI_USB20DRD_TOP_BUS_CLK_EARLY, 21, 0, 0),
431 };
432
433 static const struct samsung_cmu_info hsi_cmu_info __initconst = {
434 .mux_clks = hsi_mux_clks,
435 .nr_mux_clks = ARRAY_SIZE(hsi_mux_clks),
436 .gate_clks = hsi_gate_clks,
437 .nr_gate_clks = ARRAY_SIZE(hsi_gate_clks),
438 .nr_clk_ids = HSI_NR_CLK,
439 .clk_regs = hsi_clk_regs,
440 .nr_clk_regs = ARRAY_SIZE(hsi_clk_regs),
441 .clk_name = "dout_hsi_bus",
442 };
443
444 /* ---- CMU_PERI ------------------------------------------------------------ */
445
446 /* Register Offset definitions for CMU_PERI (0x10030000) */
447 #define PLL_CON0_MUX_CLKCMU_PERI_BUS_USER 0x0600
448 #define PLL_CON0_MUX_CLKCMU_PERI_HSI2C_USER 0x0610
449 #define PLL_CON0_MUX_CLKCMU_PERI_SPI_USER 0x0620
450 #define PLL_CON0_MUX_CLKCMU_PERI_UART_USER 0x0630
451 #define CLK_CON_DIV_DIV_CLK_PERI_HSI2C_0 0x1800
452 #define CLK_CON_DIV_DIV_CLK_PERI_HSI2C_1 0x1804
453 #define CLK_CON_DIV_DIV_CLK_PERI_HSI2C_2 0x1808
454 #define CLK_CON_DIV_DIV_CLK_PERI_SPI_0 0x180c
455 #define CLK_CON_GAT_GATE_CLK_PERI_HSI2C_0 0x200c
456 #define CLK_CON_GAT_GATE_CLK_PERI_HSI2C_1 0x2010
457 #define CLK_CON_GAT_GATE_CLK_PERI_HSI2C_2 0x2014
458 #define CLK_CON_GAT_GOUT_PERI_GPIO_PERI_PCLK 0x2020
459 #define CLK_CON_GAT_GOUT_PERI_HSI2C_0_IPCLK 0x2024
460 #define CLK_CON_GAT_GOUT_PERI_HSI2C_0_PCLK 0x2028
461 #define CLK_CON_GAT_GOUT_PERI_HSI2C_1_IPCLK 0x202c
462 #define CLK_CON_GAT_GOUT_PERI_HSI2C_1_PCLK 0x2030
463 #define CLK_CON_GAT_GOUT_PERI_HSI2C_2_IPCLK 0x2034
464 #define CLK_CON_GAT_GOUT_PERI_HSI2C_2_PCLK 0x2038
465 #define CLK_CON_GAT_GOUT_PERI_I2C_0_PCLK 0x203c
466 #define CLK_CON_GAT_GOUT_PERI_I2C_1_PCLK 0x2040
467 #define CLK_CON_GAT_GOUT_PERI_I2C_2_PCLK 0x2044
468 #define CLK_CON_GAT_GOUT_PERI_I2C_3_PCLK 0x2048
469 #define CLK_CON_GAT_GOUT_PERI_I2C_4_PCLK 0x204c
470 #define CLK_CON_GAT_GOUT_PERI_I2C_5_PCLK 0x2050
471 #define CLK_CON_GAT_GOUT_PERI_I2C_6_PCLK 0x2054
472 #define CLK_CON_GAT_GOUT_PERI_MCT_PCLK 0x205c
473 #define CLK_CON_GAT_GOUT_PERI_PWM_MOTOR_PCLK 0x2064
474 #define CLK_CON_GAT_GOUT_PERI_SPI_0_IPCLK 0x209c
475 #define CLK_CON_GAT_GOUT_PERI_SPI_0_PCLK 0x20a0
476 #define CLK_CON_GAT_GOUT_PERI_SYSREG_PERI_PCLK 0x20a4
477 #define CLK_CON_GAT_GOUT_PERI_UART_IPCLK 0x20a8
478 #define CLK_CON_GAT_GOUT_PERI_UART_PCLK 0x20ac
479 #define CLK_CON_GAT_GOUT_PERI_WDT_0_PCLK 0x20b0
480 #define CLK_CON_GAT_GOUT_PERI_WDT_1_PCLK 0x20b4
481
482 static const unsigned long peri_clk_regs[] __initconst = {
483 PLL_CON0_MUX_CLKCMU_PERI_BUS_USER,
484 PLL_CON0_MUX_CLKCMU_PERI_HSI2C_USER,
485 PLL_CON0_MUX_CLKCMU_PERI_SPI_USER,
486 PLL_CON0_MUX_CLKCMU_PERI_UART_USER,
487 CLK_CON_DIV_DIV_CLK_PERI_HSI2C_0,
488 CLK_CON_DIV_DIV_CLK_PERI_HSI2C_1,
489 CLK_CON_DIV_DIV_CLK_PERI_HSI2C_2,
490 CLK_CON_DIV_DIV_CLK_PERI_SPI_0,
491 CLK_CON_GAT_GATE_CLK_PERI_HSI2C_0,
492 CLK_CON_GAT_GATE_CLK_PERI_HSI2C_1,
493 CLK_CON_GAT_GATE_CLK_PERI_HSI2C_2,
494 CLK_CON_GAT_GOUT_PERI_GPIO_PERI_PCLK,
495 CLK_CON_GAT_GOUT_PERI_HSI2C_0_IPCLK,
496 CLK_CON_GAT_GOUT_PERI_HSI2C_0_PCLK,
497 CLK_CON_GAT_GOUT_PERI_HSI2C_1_IPCLK,
498 CLK_CON_GAT_GOUT_PERI_HSI2C_1_PCLK,
499 CLK_CON_GAT_GOUT_PERI_HSI2C_2_IPCLK,
500 CLK_CON_GAT_GOUT_PERI_HSI2C_2_PCLK,
501 CLK_CON_GAT_GOUT_PERI_I2C_0_PCLK,
502 CLK_CON_GAT_GOUT_PERI_I2C_1_PCLK,
503 CLK_CON_GAT_GOUT_PERI_I2C_2_PCLK,
504 CLK_CON_GAT_GOUT_PERI_I2C_3_PCLK,
505 CLK_CON_GAT_GOUT_PERI_I2C_4_PCLK,
506 CLK_CON_GAT_GOUT_PERI_I2C_5_PCLK,
507 CLK_CON_GAT_GOUT_PERI_I2C_6_PCLK,
508 CLK_CON_GAT_GOUT_PERI_MCT_PCLK,
509 CLK_CON_GAT_GOUT_PERI_PWM_MOTOR_PCLK,
510 CLK_CON_GAT_GOUT_PERI_SPI_0_IPCLK,
511 CLK_CON_GAT_GOUT_PERI_SPI_0_PCLK,
512 CLK_CON_GAT_GOUT_PERI_SYSREG_PERI_PCLK,
513 CLK_CON_GAT_GOUT_PERI_UART_IPCLK,
514 CLK_CON_GAT_GOUT_PERI_UART_PCLK,
515 CLK_CON_GAT_GOUT_PERI_WDT_0_PCLK,
516 CLK_CON_GAT_GOUT_PERI_WDT_1_PCLK,
517 };
518
519 /* List of parent clocks for Muxes in CMU_PERI */
520 PNAME(mout_peri_bus_user_p) = { "oscclk", "dout_peri_bus" };
521 PNAME(mout_peri_uart_user_p) = { "oscclk", "dout_peri_uart" };
522 PNAME(mout_peri_hsi2c_user_p) = { "oscclk", "dout_peri_ip" };
523 PNAME(mout_peri_spi_user_p) = { "oscclk", "dout_peri_ip" };
524
525 static const struct samsung_mux_clock peri_mux_clks[] __initconst = {
526 MUX(CLK_MOUT_PERI_BUS_USER, "mout_peri_bus_user", mout_peri_bus_user_p,
527 PLL_CON0_MUX_CLKCMU_PERI_BUS_USER, 4, 1),
528 MUX(CLK_MOUT_PERI_UART_USER, "mout_peri_uart_user",
529 mout_peri_uart_user_p, PLL_CON0_MUX_CLKCMU_PERI_UART_USER, 4, 1),
530 MUX(CLK_MOUT_PERI_HSI2C_USER, "mout_peri_hsi2c_user",
531 mout_peri_hsi2c_user_p, PLL_CON0_MUX_CLKCMU_PERI_HSI2C_USER, 4, 1),
532 MUX(CLK_MOUT_PERI_SPI_USER, "mout_peri_spi_user", mout_peri_spi_user_p,
533 PLL_CON0_MUX_CLKCMU_PERI_SPI_USER, 4, 1),
534 };
535
536 static const struct samsung_div_clock peri_div_clks[] __initconst = {
537 DIV(CLK_DOUT_PERI_HSI2C0, "dout_peri_hsi2c0", "gout_peri_hsi2c0",
538 CLK_CON_DIV_DIV_CLK_PERI_HSI2C_0, 0, 5),
539 DIV(CLK_DOUT_PERI_HSI2C1, "dout_peri_hsi2c1", "gout_peri_hsi2c1",
540 CLK_CON_DIV_DIV_CLK_PERI_HSI2C_1, 0, 5),
541 DIV(CLK_DOUT_PERI_HSI2C2, "dout_peri_hsi2c2", "gout_peri_hsi2c2",
542 CLK_CON_DIV_DIV_CLK_PERI_HSI2C_2, 0, 5),
543 DIV(CLK_DOUT_PERI_SPI0, "dout_peri_spi0", "mout_peri_spi_user",
544 CLK_CON_DIV_DIV_CLK_PERI_SPI_0, 0, 5),
545 };
546
547 static const struct samsung_gate_clock peri_gate_clks[] __initconst = {
548 GATE(CLK_GOUT_PERI_HSI2C0, "gout_peri_hsi2c0", "mout_peri_hsi2c_user",
549 CLK_CON_GAT_GATE_CLK_PERI_HSI2C_0, 21, 0, 0),
550 GATE(CLK_GOUT_PERI_HSI2C1, "gout_peri_hsi2c1", "mout_peri_hsi2c_user",
551 CLK_CON_GAT_GATE_CLK_PERI_HSI2C_1, 21, 0, 0),
552 GATE(CLK_GOUT_PERI_HSI2C2, "gout_peri_hsi2c2", "mout_peri_hsi2c_user",
553 CLK_CON_GAT_GATE_CLK_PERI_HSI2C_2, 21, 0, 0),
554 GATE(CLK_GOUT_HSI2C0_IPCLK, "gout_hsi2c0_ipclk", "dout_peri_hsi2c0",
555 CLK_CON_GAT_GOUT_PERI_HSI2C_0_IPCLK, 21, 0, 0),
556 GATE(CLK_GOUT_HSI2C0_PCLK, "gout_hsi2c0_pclk", "mout_peri_bus_user",
557 CLK_CON_GAT_GOUT_PERI_HSI2C_0_PCLK, 21, 0, 0),
558 GATE(CLK_GOUT_HSI2C1_IPCLK, "gout_hsi2c1_ipclk", "dout_peri_hsi2c1",
559 CLK_CON_GAT_GOUT_PERI_HSI2C_1_IPCLK, 21, 0, 0),
560 GATE(CLK_GOUT_HSI2C1_PCLK, "gout_hsi2c1_pclk", "mout_peri_bus_user",
561 CLK_CON_GAT_GOUT_PERI_HSI2C_1_PCLK, 21, 0, 0),
562 GATE(CLK_GOUT_HSI2C2_IPCLK, "gout_hsi2c2_ipclk", "dout_peri_hsi2c2",
563 CLK_CON_GAT_GOUT_PERI_HSI2C_2_IPCLK, 21, 0, 0),
564 GATE(CLK_GOUT_HSI2C2_PCLK, "gout_hsi2c2_pclk", "mout_peri_bus_user",
565 CLK_CON_GAT_GOUT_PERI_HSI2C_2_PCLK, 21, 0, 0),
566 GATE(CLK_GOUT_I2C0_PCLK, "gout_i2c0_pclk", "mout_peri_bus_user",
567 CLK_CON_GAT_GOUT_PERI_I2C_0_PCLK, 21, 0, 0),
568 GATE(CLK_GOUT_I2C1_PCLK, "gout_i2c1_pclk", "mout_peri_bus_user",
569 CLK_CON_GAT_GOUT_PERI_I2C_1_PCLK, 21, 0, 0),
570 GATE(CLK_GOUT_I2C2_PCLK, "gout_i2c2_pclk", "mout_peri_bus_user",
571 CLK_CON_GAT_GOUT_PERI_I2C_2_PCLK, 21, 0, 0),
572 GATE(CLK_GOUT_I2C3_PCLK, "gout_i2c3_pclk", "mout_peri_bus_user",
573 CLK_CON_GAT_GOUT_PERI_I2C_3_PCLK, 21, 0, 0),
574 GATE(CLK_GOUT_I2C4_PCLK, "gout_i2c4_pclk", "mout_peri_bus_user",
575 CLK_CON_GAT_GOUT_PERI_I2C_4_PCLK, 21, 0, 0),
576 GATE(CLK_GOUT_I2C5_PCLK, "gout_i2c5_pclk", "mout_peri_bus_user",
577 CLK_CON_GAT_GOUT_PERI_I2C_5_PCLK, 21, 0, 0),
578 GATE(CLK_GOUT_I2C6_PCLK, "gout_i2c6_pclk", "mout_peri_bus_user",
579 CLK_CON_GAT_GOUT_PERI_I2C_6_PCLK, 21, 0, 0),
580 GATE(CLK_GOUT_MCT_PCLK, "gout_mct_pclk", "mout_peri_bus_user",
581 CLK_CON_GAT_GOUT_PERI_MCT_PCLK, 21, 0, 0),
582 GATE(CLK_GOUT_PWM_MOTOR_PCLK, "gout_pwm_motor_pclk",
583 "mout_peri_bus_user",
584 CLK_CON_GAT_GOUT_PERI_PWM_MOTOR_PCLK, 21, 0, 0),
585 GATE(CLK_GOUT_SPI0_IPCLK, "gout_spi0_ipclk", "dout_peri_spi0",
586 CLK_CON_GAT_GOUT_PERI_SPI_0_IPCLK, 21, 0, 0),
587 GATE(CLK_GOUT_SPI0_PCLK, "gout_spi0_pclk", "mout_peri_bus_user",
588 CLK_CON_GAT_GOUT_PERI_SPI_0_PCLK, 21, 0, 0),
589 GATE(CLK_GOUT_SYSREG_PERI_PCLK, "gout_sysreg_peri_pclk",
590 "mout_peri_bus_user",
591 CLK_CON_GAT_GOUT_PERI_SYSREG_PERI_PCLK, 21, 0, 0),
592 GATE(CLK_GOUT_UART_IPCLK, "gout_uart_ipclk", "mout_peri_uart_user",
593 CLK_CON_GAT_GOUT_PERI_UART_IPCLK, 21, 0, 0),
594 GATE(CLK_GOUT_UART_PCLK, "gout_uart_pclk", "mout_peri_bus_user",
595 CLK_CON_GAT_GOUT_PERI_UART_PCLK, 21, 0, 0),
596 GATE(CLK_GOUT_WDT0_PCLK, "gout_wdt0_pclk", "mout_peri_bus_user",
597 CLK_CON_GAT_GOUT_PERI_WDT_0_PCLK, 21, 0, 0),
598 GATE(CLK_GOUT_WDT1_PCLK, "gout_wdt1_pclk", "mout_peri_bus_user",
599 CLK_CON_GAT_GOUT_PERI_WDT_1_PCLK, 21, 0, 0),
600 GATE(CLK_GOUT_GPIO_PERI_PCLK, "gout_gpio_peri_pclk",
601 "mout_peri_bus_user",
602 CLK_CON_GAT_GOUT_PERI_GPIO_PERI_PCLK, 21, 0, 0),
603 };
604
605 static const struct samsung_cmu_info peri_cmu_info __initconst = {
606 .mux_clks = peri_mux_clks,
607 .nr_mux_clks = ARRAY_SIZE(peri_mux_clks),
608 .div_clks = peri_div_clks,
609 .nr_div_clks = ARRAY_SIZE(peri_div_clks),
610 .gate_clks = peri_gate_clks,
611 .nr_gate_clks = ARRAY_SIZE(peri_gate_clks),
612 .nr_clk_ids = PERI_NR_CLK,
613 .clk_regs = peri_clk_regs,
614 .nr_clk_regs = ARRAY_SIZE(peri_clk_regs),
615 .clk_name = "dout_peri_bus",
616 };
617
618 /* ---- CMU_CORE ------------------------------------------------------------ */
619
620 /* Register Offset definitions for CMU_CORE (0x12000000) */
621 #define PLL_CON0_MUX_CLKCMU_CORE_BUS_USER 0x0600
622 #define PLL_CON0_MUX_CLKCMU_CORE_CCI_USER 0x0610
623 #define PLL_CON0_MUX_CLKCMU_CORE_MMC_EMBD_USER 0x0620
624 #define PLL_CON0_MUX_CLKCMU_CORE_SSS_USER 0x0630
625 #define CLK_CON_MUX_MUX_CLK_CORE_GIC 0x1000
626 #define CLK_CON_DIV_DIV_CLK_CORE_BUSP 0x1800
627 #define CLK_CON_GAT_GOUT_CORE_CCI_550_ACLK 0x2038
628 #define CLK_CON_GAT_GOUT_CORE_GIC_CLK 0x2040
629 #define CLK_CON_GAT_GOUT_CORE_MMC_EMBD_I_ACLK 0x20e8
630 #define CLK_CON_GAT_GOUT_CORE_MMC_EMBD_SDCLKIN 0x20ec
631 #define CLK_CON_GAT_GOUT_CORE_SSS_I_ACLK 0x2128
632 #define CLK_CON_GAT_GOUT_CORE_SSS_I_PCLK 0x212c
633
634 static const unsigned long core_clk_regs[] __initconst = {
635 PLL_CON0_MUX_CLKCMU_CORE_BUS_USER,
636 PLL_CON0_MUX_CLKCMU_CORE_CCI_USER,
637 PLL_CON0_MUX_CLKCMU_CORE_MMC_EMBD_USER,
638 PLL_CON0_MUX_CLKCMU_CORE_SSS_USER,
639 CLK_CON_MUX_MUX_CLK_CORE_GIC,
640 CLK_CON_DIV_DIV_CLK_CORE_BUSP,
641 CLK_CON_GAT_GOUT_CORE_CCI_550_ACLK,
642 CLK_CON_GAT_GOUT_CORE_GIC_CLK,
643 CLK_CON_GAT_GOUT_CORE_MMC_EMBD_I_ACLK,
644 CLK_CON_GAT_GOUT_CORE_MMC_EMBD_SDCLKIN,
645 CLK_CON_GAT_GOUT_CORE_SSS_I_ACLK,
646 CLK_CON_GAT_GOUT_CORE_SSS_I_PCLK,
647 };
648
649 /* List of parent clocks for Muxes in CMU_CORE */
650 PNAME(mout_core_bus_user_p) = { "oscclk", "dout_core_bus" };
651 PNAME(mout_core_cci_user_p) = { "oscclk", "dout_core_cci" };
652 PNAME(mout_core_mmc_embd_user_p) = { "oscclk", "dout_core_mmc_embd" };
653 PNAME(mout_core_sss_user_p) = { "oscclk", "dout_core_sss" };
654 PNAME(mout_core_gic_p) = { "dout_core_busp", "oscclk" };
655
656 static const struct samsung_mux_clock core_mux_clks[] __initconst = {
657 MUX(CLK_MOUT_CORE_BUS_USER, "mout_core_bus_user", mout_core_bus_user_p,
658 PLL_CON0_MUX_CLKCMU_CORE_BUS_USER, 4, 1),
659 MUX(CLK_MOUT_CORE_CCI_USER, "mout_core_cci_user", mout_core_cci_user_p,
660 PLL_CON0_MUX_CLKCMU_CORE_CCI_USER, 4, 1),
661 MUX_F(CLK_MOUT_CORE_MMC_EMBD_USER, "mout_core_mmc_embd_user",
662 mout_core_mmc_embd_user_p, PLL_CON0_MUX_CLKCMU_CORE_MMC_EMBD_USER,
663 4, 1, CLK_SET_RATE_PARENT, 0),
664 MUX(CLK_MOUT_CORE_SSS_USER, "mout_core_sss_user", mout_core_sss_user_p,
665 PLL_CON0_MUX_CLKCMU_CORE_SSS_USER, 4, 1),
666 MUX(CLK_MOUT_CORE_GIC, "mout_core_gic", mout_core_gic_p,
667 CLK_CON_MUX_MUX_CLK_CORE_GIC, 0, 1),
668 };
669
670 static const struct samsung_div_clock core_div_clks[] __initconst = {
671 DIV(CLK_DOUT_CORE_BUSP, "dout_core_busp", "mout_core_bus_user",
672 CLK_CON_DIV_DIV_CLK_CORE_BUSP, 0, 2),
673 };
674
675 static const struct samsung_gate_clock core_gate_clks[] __initconst = {
676 GATE(CLK_GOUT_CCI_ACLK, "gout_cci_aclk", "mout_core_cci_user",
677 CLK_CON_GAT_GOUT_CORE_CCI_550_ACLK, 21, 0, 0),
678 GATE(CLK_GOUT_GIC_CLK, "gout_gic_clk", "mout_core_gic",
679 CLK_CON_GAT_GOUT_CORE_GIC_CLK, 21, 0, 0),
680 GATE(CLK_GOUT_MMC_EMBD_ACLK, "gout_mmc_embd_aclk", "dout_core_busp",
681 CLK_CON_GAT_GOUT_CORE_MMC_EMBD_I_ACLK, 21, 0, 0),
682 GATE(CLK_GOUT_MMC_EMBD_SDCLKIN, "gout_mmc_embd_sdclkin",
683 "mout_core_mmc_embd_user", CLK_CON_GAT_GOUT_CORE_MMC_EMBD_SDCLKIN,
684 21, CLK_SET_RATE_PARENT, 0),
685 GATE(CLK_GOUT_SSS_ACLK, "gout_sss_aclk", "mout_core_sss_user",
686 CLK_CON_GAT_GOUT_CORE_SSS_I_ACLK, 21, 0, 0),
687 GATE(CLK_GOUT_SSS_PCLK, "gout_sss_pclk", "dout_core_busp",
688 CLK_CON_GAT_GOUT_CORE_SSS_I_PCLK, 21, 0, 0),
689 };
690
691 static const struct samsung_cmu_info core_cmu_info __initconst = {
692 .mux_clks = core_mux_clks,
693 .nr_mux_clks = ARRAY_SIZE(core_mux_clks),
694 .div_clks = core_div_clks,
695 .nr_div_clks = ARRAY_SIZE(core_div_clks),
696 .gate_clks = core_gate_clks,
697 .nr_gate_clks = ARRAY_SIZE(core_gate_clks),
698 .nr_clk_ids = CORE_NR_CLK,
699 .clk_regs = core_clk_regs,
700 .nr_clk_regs = ARRAY_SIZE(core_clk_regs),
701 .clk_name = "dout_core_bus",
702 };
703
704 /* ---- CMU_DPU ------------------------------------------------------------- */
705
706 /* Register Offset definitions for CMU_DPU (0x13000000) */
707 #define PLL_CON0_MUX_CLKCMU_DPU_USER 0x0600
708 #define CLK_CON_DIV_DIV_CLK_DPU_BUSP 0x1800
709 #define CLK_CON_GAT_CLK_DPU_CMU_DPU_PCLK 0x2004
710 #define CLK_CON_GAT_GOUT_DPU_ACLK_DECON0 0x2010
711 #define CLK_CON_GAT_GOUT_DPU_ACLK_DMA 0x2014
712 #define CLK_CON_GAT_GOUT_DPU_ACLK_DPP 0x2018
713 #define CLK_CON_GAT_GOUT_DPU_PPMU_ACLK 0x2028
714 #define CLK_CON_GAT_GOUT_DPU_PPMU_PCLK 0x202c
715 #define CLK_CON_GAT_GOUT_DPU_SMMU_CLK 0x2038
716 #define CLK_CON_GAT_GOUT_DPU_SYSREG_PCLK 0x203c
717
718 static const unsigned long dpu_clk_regs[] __initconst = {
719 PLL_CON0_MUX_CLKCMU_DPU_USER,
720 CLK_CON_DIV_DIV_CLK_DPU_BUSP,
721 CLK_CON_GAT_CLK_DPU_CMU_DPU_PCLK,
722 CLK_CON_GAT_GOUT_DPU_ACLK_DECON0,
723 CLK_CON_GAT_GOUT_DPU_ACLK_DMA,
724 CLK_CON_GAT_GOUT_DPU_ACLK_DPP,
725 CLK_CON_GAT_GOUT_DPU_PPMU_ACLK,
726 CLK_CON_GAT_GOUT_DPU_PPMU_PCLK,
727 CLK_CON_GAT_GOUT_DPU_SMMU_CLK,
728 CLK_CON_GAT_GOUT_DPU_SYSREG_PCLK,
729 };
730
731 /* List of parent clocks for Muxes in CMU_CORE */
732 PNAME(mout_dpu_user_p) = { "oscclk", "dout_dpu" };
733
734 static const struct samsung_mux_clock dpu_mux_clks[] __initconst = {
735 MUX(CLK_MOUT_DPU_USER, "mout_dpu_user", mout_dpu_user_p,
736 PLL_CON0_MUX_CLKCMU_DPU_USER, 4, 1),
737 };
738
739 static const struct samsung_div_clock dpu_div_clks[] __initconst = {
740 DIV(CLK_DOUT_DPU_BUSP, "dout_dpu_busp", "mout_dpu_user",
741 CLK_CON_DIV_DIV_CLK_DPU_BUSP, 0, 3),
742 };
743
744 static const struct samsung_gate_clock dpu_gate_clks[] __initconst = {
745 GATE(CLK_GOUT_DPU_CMU_DPU_PCLK, "gout_dpu_cmu_dpu_pclk",
746 "dout_dpu_busp", CLK_CON_GAT_CLK_DPU_CMU_DPU_PCLK, 21, 0, 0),
747 GATE(CLK_GOUT_DPU_DECON0_ACLK, "gout_dpu_decon0_aclk", "mout_dpu_user",
748 CLK_CON_GAT_GOUT_DPU_ACLK_DECON0, 21, 0, 0),
749 GATE(CLK_GOUT_DPU_DMA_ACLK, "gout_dpu_dma_aclk", "mout_dpu_user",
750 CLK_CON_GAT_GOUT_DPU_ACLK_DMA, 21, 0, 0),
751 GATE(CLK_GOUT_DPU_DPP_ACLK, "gout_dpu_dpp_aclk", "mout_dpu_user",
752 CLK_CON_GAT_GOUT_DPU_ACLK_DPP, 21, 0, 0),
753 GATE(CLK_GOUT_DPU_PPMU_ACLK, "gout_dpu_ppmu_aclk", "mout_dpu_user",
754 CLK_CON_GAT_GOUT_DPU_PPMU_ACLK, 21, 0, 0),
755 GATE(CLK_GOUT_DPU_PPMU_PCLK, "gout_dpu_ppmu_pclk", "dout_dpu_busp",
756 CLK_CON_GAT_GOUT_DPU_PPMU_PCLK, 21, 0, 0),
757 GATE(CLK_GOUT_DPU_SMMU_CLK, "gout_dpu_smmu_clk", "mout_dpu_user",
758 CLK_CON_GAT_GOUT_DPU_SMMU_CLK, 21, 0, 0),
759 GATE(CLK_GOUT_DPU_SYSREG_PCLK, "gout_dpu_sysreg_pclk", "dout_dpu_busp",
760 CLK_CON_GAT_GOUT_DPU_SYSREG_PCLK, 21, 0, 0),
761 };
762
763 static const struct samsung_cmu_info dpu_cmu_info __initconst = {
764 .mux_clks = dpu_mux_clks,
765 .nr_mux_clks = ARRAY_SIZE(dpu_mux_clks),
766 .div_clks = dpu_div_clks,
767 .nr_div_clks = ARRAY_SIZE(dpu_div_clks),
768 .gate_clks = dpu_gate_clks,
769 .nr_gate_clks = ARRAY_SIZE(dpu_gate_clks),
770 .nr_clk_ids = DPU_NR_CLK,
771 .clk_regs = dpu_clk_regs,
772 .nr_clk_regs = ARRAY_SIZE(dpu_clk_regs),
773 .clk_name = "dout_dpu",
774 };
775
776 /* ---- platform_driver ----------------------------------------------------- */
777
exynos850_cmu_probe(struct platform_device * pdev)778 static int __init exynos850_cmu_probe(struct platform_device *pdev)
779 {
780 const struct samsung_cmu_info *info;
781 struct device *dev = &pdev->dev;
782 struct device_node *np = dev->of_node;
783
784 info = of_device_get_match_data(dev);
785 exynos850_init_clocks(np, info->clk_regs, info->nr_clk_regs);
786 samsung_cmu_register_one(np, info);
787
788 /* Keep bus clock running, so it's possible to access CMU registers */
789 if (info->clk_name) {
790 struct clk *bus_clk;
791
792 bus_clk = clk_get(dev, info->clk_name);
793 if (IS_ERR(bus_clk)) {
794 pr_err("%s: could not find bus clock %s; err = %ld\n",
795 __func__, info->clk_name, PTR_ERR(bus_clk));
796 } else {
797 clk_prepare_enable(bus_clk);
798 }
799 }
800
801 return 0;
802 }
803
804 /* CMUs which belong to Power Domains and need runtime PM to be implemented */
805 static const struct of_device_id exynos850_cmu_of_match[] = {
806 {
807 .compatible = "samsung,exynos850-cmu-hsi",
808 .data = &hsi_cmu_info,
809 }, {
810 .compatible = "samsung,exynos850-cmu-peri",
811 .data = &peri_cmu_info,
812 }, {
813 .compatible = "samsung,exynos850-cmu-core",
814 .data = &core_cmu_info,
815 }, {
816 .compatible = "samsung,exynos850-cmu-dpu",
817 .data = &dpu_cmu_info,
818 }, {
819 },
820 };
821
822 static struct platform_driver exynos850_cmu_driver __refdata = {
823 .driver = {
824 .name = "exynos850-cmu",
825 .of_match_table = exynos850_cmu_of_match,
826 .suppress_bind_attrs = true,
827 },
828 .probe = exynos850_cmu_probe,
829 };
830
exynos850_cmu_init(void)831 static int __init exynos850_cmu_init(void)
832 {
833 return platform_driver_register(&exynos850_cmu_driver);
834 }
835 core_initcall(exynos850_cmu_init);
836