1 | // SPDX-License-Identifier: GPL-2.0-only |
2 | /* |
3 | * Copyright (c) 2013 Samsung Electronics Co., Ltd. |
4 | * Copyright (c) 2013 Linaro Ltd. |
5 | * Author: Thomas Abraham <thomas.ab@samsung.com> |
6 | * |
7 | * Common Clock Framework support for Exynos5250 SoC. |
8 | */ |
9 | |
10 | #include <dt-bindings/clock/exynos5250.h> |
11 | #include <linux/clk-provider.h> |
12 | #include <linux/io.h> |
13 | #include <linux/of.h> |
14 | #include <linux/of_address.h> |
15 | |
16 | #include "clk.h" |
17 | #include "clk-cpu.h" |
18 | #include "clk-exynos5-subcmu.h" |
19 | |
20 | #define APLL_LOCK 0x0 |
21 | #define APLL_CON0 0x100 |
22 | #define SRC_CPU 0x200 |
23 | #define DIV_CPU0 0x500 |
24 | #define PWR_CTRL1 0x1020 |
25 | #define PWR_CTRL2 0x1024 |
26 | #define MPLL_LOCK 0x4000 |
27 | #define MPLL_CON0 0x4100 |
28 | #define SRC_CORE1 0x4204 |
29 | #define GATE_IP_ACP 0x8800 |
30 | #define GATE_IP_ISP0 0xc800 |
31 | #define GATE_IP_ISP1 0xc804 |
32 | #define CPLL_LOCK 0x10020 |
33 | #define EPLL_LOCK 0x10030 |
34 | #define VPLL_LOCK 0x10040 |
35 | #define GPLL_LOCK 0x10050 |
36 | #define CPLL_CON0 0x10120 |
37 | #define EPLL_CON0 0x10130 |
38 | #define VPLL_CON0 0x10140 |
39 | #define GPLL_CON0 0x10150 |
40 | #define SRC_TOP0 0x10210 |
41 | #define SRC_TOP1 0x10214 |
42 | #define SRC_TOP2 0x10218 |
43 | #define SRC_TOP3 0x1021c |
44 | #define SRC_GSCL 0x10220 |
45 | #define SRC_DISP1_0 0x1022c |
46 | #define SRC_MAU 0x10240 |
47 | #define SRC_FSYS 0x10244 |
48 | #define SRC_GEN 0x10248 |
49 | #define SRC_PERIC0 0x10250 |
50 | #define SRC_PERIC1 0x10254 |
51 | #define SRC_MASK_GSCL 0x10320 |
52 | #define SRC_MASK_DISP1_0 0x1032c |
53 | #define SRC_MASK_MAU 0x10334 |
54 | #define SRC_MASK_FSYS 0x10340 |
55 | #define SRC_MASK_GEN 0x10344 |
56 | #define SRC_MASK_PERIC0 0x10350 |
57 | #define SRC_MASK_PERIC1 0x10354 |
58 | #define DIV_TOP0 0x10510 |
59 | #define DIV_TOP1 0x10514 |
60 | #define DIV_GSCL 0x10520 |
61 | #define DIV_DISP1_0 0x1052c |
62 | #define DIV_GEN 0x1053c |
63 | #define DIV_MAU 0x10544 |
64 | #define DIV_FSYS0 0x10548 |
65 | #define DIV_FSYS1 0x1054c |
66 | #define DIV_FSYS2 0x10550 |
67 | #define DIV_PERIC0 0x10558 |
68 | #define DIV_PERIC1 0x1055c |
69 | #define DIV_PERIC2 0x10560 |
70 | #define DIV_PERIC3 0x10564 |
71 | #define DIV_PERIC4 0x10568 |
72 | #define DIV_PERIC5 0x1056c |
73 | #define GATE_IP_GSCL 0x10920 |
74 | #define GATE_IP_DISP1 0x10928 |
75 | #define GATE_IP_MFC 0x1092c |
76 | #define GATE_IP_G3D 0x10930 |
77 | #define GATE_IP_GEN 0x10934 |
78 | #define GATE_IP_FSYS 0x10944 |
79 | #define GATE_IP_PERIC 0x10950 |
80 | #define GATE_IP_PERIS 0x10960 |
81 | #define BPLL_LOCK 0x20010 |
82 | #define BPLL_CON0 0x20110 |
83 | #define SRC_CDREX 0x20200 |
84 | #define PLL_DIV2_SEL 0x20a24 |
85 | |
86 | /*Below definitions are used for PWR_CTRL settings*/ |
87 | #define PWR_CTRL1_CORE2_DOWN_RATIO (7 << 28) |
88 | #define PWR_CTRL1_CORE1_DOWN_RATIO (7 << 16) |
89 | #define PWR_CTRL1_DIV2_DOWN_EN (1 << 9) |
90 | #define PWR_CTRL1_DIV1_DOWN_EN (1 << 8) |
91 | #define PWR_CTRL1_USE_CORE1_WFE (1 << 5) |
92 | #define PWR_CTRL1_USE_CORE0_WFE (1 << 4) |
93 | #define PWR_CTRL1_USE_CORE1_WFI (1 << 1) |
94 | #define PWR_CTRL1_USE_CORE0_WFI (1 << 0) |
95 | |
96 | #define PWR_CTRL2_DIV2_UP_EN (1 << 25) |
97 | #define PWR_CTRL2_DIV1_UP_EN (1 << 24) |
98 | #define PWR_CTRL2_DUR_STANDBY2_VAL (1 << 16) |
99 | #define PWR_CTRL2_DUR_STANDBY1_VAL (1 << 8) |
100 | #define PWR_CTRL2_CORE2_UP_RATIO (1 << 4) |
101 | #define PWR_CTRL2_CORE1_UP_RATIO (1 << 0) |
102 | |
103 | /* NOTE: Must be equal to the last clock ID increased by one */ |
104 | #define CLKS_NR (CLK_MOUT_VPLLSRC + 1) |
105 | |
106 | /* list of PLLs to be registered */ |
107 | enum exynos5250_plls { |
108 | apll, mpll, cpll, epll, vpll, gpll, bpll, |
109 | nr_plls /* number of PLLs */ |
110 | }; |
111 | |
112 | static void __iomem *reg_base; |
113 | |
114 | /* |
115 | * list of controller registers to be saved and restored during a |
116 | * suspend/resume cycle. |
117 | */ |
118 | static const unsigned long exynos5250_clk_regs[] __initconst = { |
119 | SRC_CPU, |
120 | DIV_CPU0, |
121 | PWR_CTRL1, |
122 | PWR_CTRL2, |
123 | SRC_CORE1, |
124 | SRC_TOP0, |
125 | SRC_TOP1, |
126 | SRC_TOP2, |
127 | SRC_TOP3, |
128 | SRC_GSCL, |
129 | SRC_DISP1_0, |
130 | SRC_MAU, |
131 | SRC_FSYS, |
132 | SRC_GEN, |
133 | SRC_PERIC0, |
134 | SRC_PERIC1, |
135 | SRC_MASK_GSCL, |
136 | SRC_MASK_DISP1_0, |
137 | SRC_MASK_MAU, |
138 | SRC_MASK_FSYS, |
139 | SRC_MASK_GEN, |
140 | SRC_MASK_PERIC0, |
141 | SRC_MASK_PERIC1, |
142 | DIV_TOP0, |
143 | DIV_TOP1, |
144 | DIV_GSCL, |
145 | DIV_DISP1_0, |
146 | DIV_GEN, |
147 | DIV_MAU, |
148 | DIV_FSYS0, |
149 | DIV_FSYS1, |
150 | DIV_FSYS2, |
151 | DIV_PERIC0, |
152 | DIV_PERIC1, |
153 | DIV_PERIC2, |
154 | DIV_PERIC3, |
155 | DIV_PERIC4, |
156 | DIV_PERIC5, |
157 | GATE_IP_GSCL, |
158 | GATE_IP_MFC, |
159 | GATE_IP_G3D, |
160 | GATE_IP_GEN, |
161 | GATE_IP_FSYS, |
162 | GATE_IP_PERIC, |
163 | GATE_IP_PERIS, |
164 | SRC_CDREX, |
165 | PLL_DIV2_SEL, |
166 | GATE_IP_DISP1, |
167 | GATE_IP_ACP, |
168 | GATE_IP_ISP0, |
169 | GATE_IP_ISP1, |
170 | }; |
171 | |
172 | /* list of all parent clock list */ |
173 | PNAME(mout_apll_p) = { "fin_pll" , "fout_apll" , }; |
174 | PNAME(mout_cpu_p) = { "mout_apll" , "mout_mpll" , }; |
175 | PNAME(mout_mpll_fout_p) = { "fout_mplldiv2" , "fout_mpll" }; |
176 | PNAME(mout_mpll_p) = { "fin_pll" , "mout_mpll_fout" }; |
177 | PNAME(mout_bpll_fout_p) = { "fout_bplldiv2" , "fout_bpll" }; |
178 | PNAME(mout_bpll_p) = { "fin_pll" , "mout_bpll_fout" }; |
179 | PNAME(mout_vpllsrc_p) = { "fin_pll" , "sclk_hdmi27m" }; |
180 | PNAME(mout_vpll_p) = { "mout_vpllsrc" , "fout_vpll" }; |
181 | PNAME(mout_cpll_p) = { "fin_pll" , "fout_cpll" }; |
182 | PNAME(mout_epll_p) = { "fin_pll" , "fout_epll" }; |
183 | PNAME(mout_gpll_p) = { "fin_pll" , "fout_gpll" }; |
184 | PNAME(mout_mpll_user_p) = { "fin_pll" , "mout_mpll" }; |
185 | PNAME(mout_bpll_user_p) = { "fin_pll" , "mout_bpll" }; |
186 | PNAME(mout_aclk166_p) = { "mout_cpll" , "mout_mpll_user" }; |
187 | PNAME(mout_aclk200_p) = { "mout_mpll_user" , "mout_bpll_user" }; |
188 | PNAME(mout_aclk300_p) = { "mout_aclk300_disp1_mid" , |
189 | "mout_aclk300_disp1_mid1" }; |
190 | PNAME(mout_aclk400_p) = { "mout_aclk400_g3d_mid" , "mout_gpll" }; |
191 | PNAME(mout_aclk200_sub_p) = { "fin_pll" , "div_aclk200" }; |
192 | PNAME(mout_aclk266_sub_p) = { "fin_pll" , "div_aclk266" }; |
193 | PNAME(mout_aclk300_sub_p) = { "fin_pll" , "div_aclk300_disp" }; |
194 | PNAME(mout_aclk300_disp1_mid1_p) = { "mout_vpll" , "mout_cpll" }; |
195 | PNAME(mout_aclk333_sub_p) = { "fin_pll" , "div_aclk333" }; |
196 | PNAME(mout_aclk400_isp_sub_p) = { "fin_pll" , "div_aclk400_isp" }; |
197 | PNAME(mout_hdmi_p) = { "div_hdmi_pixel" , "sclk_hdmiphy" }; |
198 | PNAME(mout_usb3_p) = { "mout_mpll_user" , "mout_cpll" }; |
199 | PNAME(mout_group1_p) = { "fin_pll" , "fin_pll" , "sclk_hdmi27m" , |
200 | "sclk_dptxphy" , "sclk_uhostphy" , "sclk_hdmiphy" , |
201 | "mout_mpll_user" , "mout_epll" , "mout_vpll" , |
202 | "mout_cpll" , "none" , "none" , |
203 | "none" , "none" , "none" , |
204 | "none" }; |
205 | PNAME(mout_audio0_p) = { "cdclk0" , "fin_pll" , "sclk_hdmi27m" , "sclk_dptxphy" , |
206 | "sclk_uhostphy" , "fin_pll" , |
207 | "mout_mpll_user" , "mout_epll" , "mout_vpll" , |
208 | "mout_cpll" , "none" , "none" , |
209 | "none" , "none" , "none" , |
210 | "none" }; |
211 | PNAME(mout_audio1_p) = { "cdclk1" , "fin_pll" , "sclk_hdmi27m" , "sclk_dptxphy" , |
212 | "sclk_uhostphy" , "fin_pll" , |
213 | "mout_mpll_user" , "mout_epll" , "mout_vpll" , |
214 | "mout_cpll" , "none" , "none" , |
215 | "none" , "none" , "none" , |
216 | "none" }; |
217 | PNAME(mout_audio2_p) = { "cdclk2" , "fin_pll" , "sclk_hdmi27m" , "sclk_dptxphy" , |
218 | "sclk_uhostphy" , "fin_pll" , |
219 | "mout_mpll_user" , "mout_epll" , "mout_vpll" , |
220 | "mout_cpll" , "none" , "none" , |
221 | "none" , "none" , "none" , |
222 | "none" }; |
223 | PNAME(mout_spdif_p) = { "sclk_audio0" , "sclk_audio1" , "sclk_audio2" , |
224 | "spdif_extclk" }; |
225 | |
226 | /* fixed rate clocks generated outside the soc */ |
227 | static struct samsung_fixed_rate_clock exynos5250_fixed_rate_ext_clks[] __initdata = { |
228 | FRATE(CLK_FIN_PLL, "fin_pll" , NULL, 0, 0), |
229 | }; |
230 | |
231 | /* fixed rate clocks generated inside the soc */ |
232 | static const struct samsung_fixed_rate_clock exynos5250_fixed_rate_clks[] __initconst = { |
233 | FRATE(CLK_SCLK_HDMIPHY, "sclk_hdmiphy" , NULL, 0, 24000000), |
234 | FRATE(0, "sclk_hdmi27m" , NULL, 0, 27000000), |
235 | FRATE(0, "sclk_dptxphy" , NULL, 0, 24000000), |
236 | FRATE(0, "sclk_uhostphy" , NULL, 0, 48000000), |
237 | }; |
238 | |
239 | static const struct samsung_fixed_factor_clock exynos5250_fixed_factor_clks[] __initconst = { |
240 | FFACTOR(0, "fout_mplldiv2" , "fout_mpll" , 1, 2, 0), |
241 | FFACTOR(0, "fout_bplldiv2" , "fout_bpll" , 1, 2, 0), |
242 | }; |
243 | |
244 | static const struct samsung_mux_clock exynos5250_pll_pmux_clks[] __initconst = { |
245 | MUX(CLK_MOUT_VPLLSRC, "mout_vpllsrc" , mout_vpllsrc_p, SRC_TOP2, 0, 1), |
246 | }; |
247 | |
248 | static const struct samsung_mux_clock exynos5250_mux_clks[] __initconst = { |
249 | /* |
250 | * NOTE: Following table is sorted by (clock domain, register address, |
251 | * bitfield shift) triplet in ascending order. When adding new entries, |
252 | * please make sure that the order is kept, to avoid merge conflicts |
253 | * and make further work with defined data easier. |
254 | */ |
255 | |
256 | /* |
257 | * CMU_CPU |
258 | */ |
259 | MUX_F(CLK_MOUT_APLL, "mout_apll" , mout_apll_p, SRC_CPU, 0, 1, |
260 | CLK_SET_RATE_PARENT, 0), |
261 | MUX(0, "mout_cpu" , mout_cpu_p, SRC_CPU, 16, 1), |
262 | |
263 | /* |
264 | * CMU_CORE |
265 | */ |
266 | MUX(CLK_MOUT_MPLL, "mout_mpll" , mout_mpll_p, SRC_CORE1, 8, 1), |
267 | |
268 | /* |
269 | * CMU_TOP |
270 | */ |
271 | MUX(0, "mout_aclk166" , mout_aclk166_p, SRC_TOP0, 8, 1), |
272 | MUX(0, "mout_aclk200" , mout_aclk200_p, SRC_TOP0, 12, 1), |
273 | MUX(0, "mout_aclk300_disp1_mid" , mout_aclk200_p, SRC_TOP0, 14, 1), |
274 | MUX(0, "mout_aclk300" , mout_aclk300_p, SRC_TOP0, 15, 1), |
275 | MUX(0, "mout_aclk333" , mout_aclk166_p, SRC_TOP0, 16, 1), |
276 | MUX(0, "mout_aclk400_g3d_mid" , mout_aclk200_p, SRC_TOP0, 20, 1), |
277 | |
278 | MUX(0, "mout_aclk300_disp1_mid1" , mout_aclk300_disp1_mid1_p, SRC_TOP1, |
279 | 8, 1), |
280 | MUX(0, "mout_aclk400_isp" , mout_aclk200_p, SRC_TOP1, 24, 1), |
281 | MUX(0, "mout_aclk400_g3d" , mout_aclk400_p, SRC_TOP1, 28, 1), |
282 | |
283 | MUX(0, "mout_cpll" , mout_cpll_p, SRC_TOP2, 8, 1), |
284 | MUX(0, "mout_epll" , mout_epll_p, SRC_TOP2, 12, 1), |
285 | MUX(0, "mout_vpll" , mout_vpll_p, SRC_TOP2, 16, 1), |
286 | MUX(0, "mout_mpll_user" , mout_mpll_user_p, SRC_TOP2, 20, 1), |
287 | MUX(0, "mout_bpll_user" , mout_bpll_user_p, SRC_TOP2, 24, 1), |
288 | MUX(CLK_MOUT_GPLL, "mout_gpll" , mout_gpll_p, SRC_TOP2, 28, 1), |
289 | |
290 | MUX(CLK_MOUT_ACLK200_DISP1_SUB, "mout_aclk200_disp1_sub" , |
291 | mout_aclk200_sub_p, SRC_TOP3, 4, 1), |
292 | MUX(CLK_MOUT_ACLK300_DISP1_SUB, "mout_aclk300_disp1_sub" , |
293 | mout_aclk300_sub_p, SRC_TOP3, 6, 1), |
294 | MUX(0, "mout_aclk266_gscl_sub" , mout_aclk266_sub_p, SRC_TOP3, 8, 1), |
295 | MUX(0, "mout_aclk_266_isp_sub" , mout_aclk266_sub_p, SRC_TOP3, 16, 1), |
296 | MUX(0, "mout_aclk_400_isp_sub" , mout_aclk400_isp_sub_p, |
297 | SRC_TOP3, 20, 1), |
298 | MUX(0, "mout_aclk333_sub" , mout_aclk333_sub_p, SRC_TOP3, 24, 1), |
299 | |
300 | MUX(0, "mout_cam_bayer" , mout_group1_p, SRC_GSCL, 12, 4), |
301 | MUX(0, "mout_cam0" , mout_group1_p, SRC_GSCL, 16, 4), |
302 | MUX(0, "mout_cam1" , mout_group1_p, SRC_GSCL, 20, 4), |
303 | MUX(0, "mout_gscl_wa" , mout_group1_p, SRC_GSCL, 24, 4), |
304 | MUX(0, "mout_gscl_wb" , mout_group1_p, SRC_GSCL, 28, 4), |
305 | |
306 | MUX(0, "mout_fimd1" , mout_group1_p, SRC_DISP1_0, 0, 4), |
307 | MUX(0, "mout_mipi1" , mout_group1_p, SRC_DISP1_0, 12, 4), |
308 | MUX(0, "mout_dp" , mout_group1_p, SRC_DISP1_0, 16, 4), |
309 | MUX(CLK_MOUT_HDMI, "mout_hdmi" , mout_hdmi_p, SRC_DISP1_0, 20, 1), |
310 | |
311 | MUX(0, "mout_audio0" , mout_audio0_p, SRC_MAU, 0, 4), |
312 | |
313 | MUX(0, "mout_mmc0" , mout_group1_p, SRC_FSYS, 0, 4), |
314 | MUX(0, "mout_mmc1" , mout_group1_p, SRC_FSYS, 4, 4), |
315 | MUX(0, "mout_mmc2" , mout_group1_p, SRC_FSYS, 8, 4), |
316 | MUX(0, "mout_mmc3" , mout_group1_p, SRC_FSYS, 12, 4), |
317 | MUX(0, "mout_sata" , mout_aclk200_p, SRC_FSYS, 24, 1), |
318 | MUX(0, "mout_usb3" , mout_usb3_p, SRC_FSYS, 28, 1), |
319 | |
320 | MUX(0, "mout_jpeg" , mout_group1_p, SRC_GEN, 0, 4), |
321 | |
322 | MUX(0, "mout_uart0" , mout_group1_p, SRC_PERIC0, 0, 4), |
323 | MUX(0, "mout_uart1" , mout_group1_p, SRC_PERIC0, 4, 4), |
324 | MUX(0, "mout_uart2" , mout_group1_p, SRC_PERIC0, 8, 4), |
325 | MUX(0, "mout_uart3" , mout_group1_p, SRC_PERIC0, 12, 4), |
326 | MUX(0, "mout_pwm" , mout_group1_p, SRC_PERIC0, 24, 4), |
327 | |
328 | MUX(0, "mout_audio1" , mout_audio1_p, SRC_PERIC1, 0, 4), |
329 | MUX(0, "mout_audio2" , mout_audio2_p, SRC_PERIC1, 4, 4), |
330 | MUX(0, "mout_spdif" , mout_spdif_p, SRC_PERIC1, 8, 2), |
331 | MUX(0, "mout_spi0" , mout_group1_p, SRC_PERIC1, 16, 4), |
332 | MUX(0, "mout_spi1" , mout_group1_p, SRC_PERIC1, 20, 4), |
333 | MUX(0, "mout_spi2" , mout_group1_p, SRC_PERIC1, 24, 4), |
334 | |
335 | /* |
336 | * CMU_CDREX |
337 | */ |
338 | MUX(0, "mout_bpll" , mout_bpll_p, SRC_CDREX, 0, 1), |
339 | |
340 | MUX(0, "mout_mpll_fout" , mout_mpll_fout_p, PLL_DIV2_SEL, 4, 1), |
341 | MUX(0, "mout_bpll_fout" , mout_bpll_fout_p, PLL_DIV2_SEL, 0, 1), |
342 | }; |
343 | |
344 | static const struct samsung_div_clock exynos5250_div_clks[] __initconst = { |
345 | /* |
346 | * NOTE: Following table is sorted by (clock domain, register address, |
347 | * bitfield shift) triplet in ascending order. When adding new entries, |
348 | * please make sure that the order is kept, to avoid merge conflicts |
349 | * and make further work with defined data easier. |
350 | */ |
351 | |
352 | /* |
353 | * CMU_CPU |
354 | */ |
355 | DIV(0, "div_arm" , "mout_cpu" , DIV_CPU0, 0, 3), |
356 | DIV(0, "div_apll" , "mout_apll" , DIV_CPU0, 24, 3), |
357 | DIV(CLK_DIV_ARM2, "div_arm2" , "div_arm" , DIV_CPU0, 28, 3), |
358 | |
359 | /* |
360 | * CMU_TOP |
361 | */ |
362 | DIV(0, "div_aclk66" , "div_aclk66_pre" , DIV_TOP0, 0, 3), |
363 | DIV(0, "div_aclk166" , "mout_aclk166" , DIV_TOP0, 8, 3), |
364 | DIV(0, "div_aclk200" , "mout_aclk200" , DIV_TOP0, 12, 3), |
365 | DIV(0, "div_aclk266" , "mout_mpll_user" , DIV_TOP0, 16, 3), |
366 | DIV(0, "div_aclk333" , "mout_aclk333" , DIV_TOP0, 20, 3), |
367 | DIV(0, "div_aclk400_g3d" , "mout_aclk400_g3d" , DIV_TOP0, |
368 | 24, 3), |
369 | DIV(0, "div_aclk300_disp" , "mout_aclk300" , DIV_TOP0, 28, 3), |
370 | |
371 | DIV(0, "div_aclk400_isp" , "mout_aclk400_isp" , DIV_TOP1, 20, 3), |
372 | DIV(0, "div_aclk66_pre" , "mout_mpll_user" , DIV_TOP1, 24, 3), |
373 | |
374 | DIV(0, "div_cam_bayer" , "mout_cam_bayer" , DIV_GSCL, 12, 4), |
375 | DIV(0, "div_cam0" , "mout_cam0" , DIV_GSCL, 16, 4), |
376 | DIV(0, "div_cam1" , "mout_cam1" , DIV_GSCL, 20, 4), |
377 | DIV(0, "div_gscl_wa" , "mout_gscl_wa" , DIV_GSCL, 24, 4), |
378 | DIV(0, "div_gscl_wb" , "mout_gscl_wb" , DIV_GSCL, 28, 4), |
379 | |
380 | DIV(0, "div_fimd1" , "mout_fimd1" , DIV_DISP1_0, 0, 4), |
381 | DIV(0, "div_mipi1" , "mout_mipi1" , DIV_DISP1_0, 16, 4), |
382 | DIV_F(0, "div_mipi1_pre" , "div_mipi1" , |
383 | DIV_DISP1_0, 20, 4, CLK_SET_RATE_PARENT, 0), |
384 | DIV(0, "div_dp" , "mout_dp" , DIV_DISP1_0, 24, 4), |
385 | DIV(CLK_SCLK_PIXEL, "div_hdmi_pixel" , "mout_vpll" , DIV_DISP1_0, 28, 4), |
386 | |
387 | DIV(0, "div_jpeg" , "mout_jpeg" , DIV_GEN, 4, 4), |
388 | |
389 | DIV(0, "div_audio0" , "mout_audio0" , DIV_MAU, 0, 4), |
390 | DIV(CLK_DIV_PCM0, "div_pcm0" , "sclk_audio0" , DIV_MAU, 4, 8), |
391 | |
392 | DIV(0, "div_sata" , "mout_sata" , DIV_FSYS0, 20, 4), |
393 | DIV(0, "div_usb3" , "mout_usb3" , DIV_FSYS0, 24, 4), |
394 | |
395 | DIV(0, "div_mmc0" , "mout_mmc0" , DIV_FSYS1, 0, 4), |
396 | DIV_F(0, "div_mmc_pre0" , "div_mmc0" , |
397 | DIV_FSYS1, 8, 8, CLK_SET_RATE_PARENT, 0), |
398 | DIV(0, "div_mmc1" , "mout_mmc1" , DIV_FSYS1, 16, 4), |
399 | DIV_F(0, "div_mmc_pre1" , "div_mmc1" , |
400 | DIV_FSYS1, 24, 8, CLK_SET_RATE_PARENT, 0), |
401 | |
402 | DIV(0, "div_mmc2" , "mout_mmc2" , DIV_FSYS2, 0, 4), |
403 | DIV_F(0, "div_mmc_pre2" , "div_mmc2" , |
404 | DIV_FSYS2, 8, 8, CLK_SET_RATE_PARENT, 0), |
405 | DIV(0, "div_mmc3" , "mout_mmc3" , DIV_FSYS2, 16, 4), |
406 | DIV_F(0, "div_mmc_pre3" , "div_mmc3" , |
407 | DIV_FSYS2, 24, 8, CLK_SET_RATE_PARENT, 0), |
408 | |
409 | DIV(0, "div_uart0" , "mout_uart0" , DIV_PERIC0, 0, 4), |
410 | DIV(0, "div_uart1" , "mout_uart1" , DIV_PERIC0, 4, 4), |
411 | DIV(0, "div_uart2" , "mout_uart2" , DIV_PERIC0, 8, 4), |
412 | DIV(0, "div_uart3" , "mout_uart3" , DIV_PERIC0, 12, 4), |
413 | |
414 | DIV(0, "div_spi0" , "mout_spi0" , DIV_PERIC1, 0, 4), |
415 | DIV_F(0, "div_spi_pre0" , "div_spi0" , |
416 | DIV_PERIC1, 8, 8, CLK_SET_RATE_PARENT, 0), |
417 | DIV(0, "div_spi1" , "mout_spi1" , DIV_PERIC1, 16, 4), |
418 | DIV_F(0, "div_spi_pre1" , "div_spi1" , |
419 | DIV_PERIC1, 24, 8, CLK_SET_RATE_PARENT, 0), |
420 | |
421 | DIV(0, "div_spi2" , "mout_spi2" , DIV_PERIC2, 0, 4), |
422 | DIV_F(0, "div_spi_pre2" , "div_spi2" , |
423 | DIV_PERIC2, 8, 8, CLK_SET_RATE_PARENT, 0), |
424 | |
425 | DIV(0, "div_pwm" , "mout_pwm" , DIV_PERIC3, 0, 4), |
426 | |
427 | DIV(0, "div_audio1" , "mout_audio1" , DIV_PERIC4, 0, 4), |
428 | DIV(0, "div_pcm1" , "sclk_audio1" , DIV_PERIC4, 4, 8), |
429 | DIV(0, "div_audio2" , "mout_audio2" , DIV_PERIC4, 16, 4), |
430 | DIV(0, "div_pcm2" , "sclk_audio2" , DIV_PERIC4, 20, 8), |
431 | |
432 | DIV(CLK_DIV_I2S1, "div_i2s1" , "sclk_audio1" , DIV_PERIC5, 0, 6), |
433 | DIV(CLK_DIV_I2S2, "div_i2s2" , "sclk_audio2" , DIV_PERIC5, 8, 6), |
434 | }; |
435 | |
436 | static const struct samsung_gate_clock exynos5250_gate_clks[] __initconst = { |
437 | /* |
438 | * NOTE: Following table is sorted by (clock domain, register address, |
439 | * bitfield shift) triplet in ascending order. When adding new entries, |
440 | * please make sure that the order is kept, to avoid merge conflicts |
441 | * and make further work with defined data easier. |
442 | */ |
443 | |
444 | /* |
445 | * CMU_ACP |
446 | */ |
447 | GATE(CLK_MDMA0, "mdma0" , "div_aclk266" , GATE_IP_ACP, 1, 0, 0), |
448 | GATE(CLK_SSS, "sss" , "div_aclk266" , GATE_IP_ACP, 2, 0, 0), |
449 | GATE(CLK_G2D, "g2d" , "div_aclk200" , GATE_IP_ACP, 3, 0, 0), |
450 | GATE(CLK_SMMU_MDMA0, "smmu_mdma0" , "div_aclk266" , GATE_IP_ACP, 5, 0, 0), |
451 | |
452 | /* |
453 | * CMU_TOP |
454 | */ |
455 | GATE(CLK_SCLK_CAM_BAYER, "sclk_cam_bayer" , "div_cam_bayer" , |
456 | SRC_MASK_GSCL, 12, CLK_SET_RATE_PARENT, 0), |
457 | GATE(CLK_SCLK_CAM0, "sclk_cam0" , "div_cam0" , |
458 | SRC_MASK_GSCL, 16, CLK_SET_RATE_PARENT, 0), |
459 | GATE(CLK_SCLK_CAM1, "sclk_cam1" , "div_cam1" , |
460 | SRC_MASK_GSCL, 20, CLK_SET_RATE_PARENT, 0), |
461 | GATE(CLK_SCLK_GSCL_WA, "sclk_gscl_wa" , "div_gscl_wa" , |
462 | SRC_MASK_GSCL, 24, CLK_SET_RATE_PARENT, 0), |
463 | GATE(CLK_SCLK_GSCL_WB, "sclk_gscl_wb" , "div_gscl_wb" , |
464 | SRC_MASK_GSCL, 28, CLK_SET_RATE_PARENT, 0), |
465 | |
466 | GATE(CLK_SCLK_FIMD1, "sclk_fimd1" , "div_fimd1" , |
467 | SRC_MASK_DISP1_0, 0, CLK_SET_RATE_PARENT, 0), |
468 | GATE(CLK_SCLK_MIPI1, "sclk_mipi1" , "div_mipi1" , |
469 | SRC_MASK_DISP1_0, 12, CLK_SET_RATE_PARENT, 0), |
470 | GATE(CLK_SCLK_DP, "sclk_dp" , "div_dp" , |
471 | SRC_MASK_DISP1_0, 16, CLK_SET_RATE_PARENT, 0), |
472 | GATE(CLK_SCLK_HDMI, "sclk_hdmi" , "mout_hdmi" , |
473 | SRC_MASK_DISP1_0, 20, 0, 0), |
474 | |
475 | GATE(CLK_SCLK_AUDIO0, "sclk_audio0" , "div_audio0" , |
476 | SRC_MASK_MAU, 0, CLK_SET_RATE_PARENT, 0), |
477 | |
478 | GATE(CLK_SCLK_MMC0, "sclk_mmc0" , "div_mmc_pre0" , |
479 | SRC_MASK_FSYS, 0, CLK_SET_RATE_PARENT, 0), |
480 | GATE(CLK_SCLK_MMC1, "sclk_mmc1" , "div_mmc_pre1" , |
481 | SRC_MASK_FSYS, 4, CLK_SET_RATE_PARENT, 0), |
482 | GATE(CLK_SCLK_MMC2, "sclk_mmc2" , "div_mmc_pre2" , |
483 | SRC_MASK_FSYS, 8, CLK_SET_RATE_PARENT, 0), |
484 | GATE(CLK_SCLK_MMC3, "sclk_mmc3" , "div_mmc_pre3" , |
485 | SRC_MASK_FSYS, 12, CLK_SET_RATE_PARENT, 0), |
486 | GATE(CLK_SCLK_SATA, "sclk_sata" , "div_sata" , |
487 | SRC_MASK_FSYS, 24, CLK_SET_RATE_PARENT, 0), |
488 | GATE(CLK_SCLK_USB3, "sclk_usb3" , "div_usb3" , |
489 | SRC_MASK_FSYS, 28, CLK_SET_RATE_PARENT, 0), |
490 | |
491 | GATE(CLK_SCLK_JPEG, "sclk_jpeg" , "div_jpeg" , |
492 | SRC_MASK_GEN, 0, CLK_SET_RATE_PARENT, 0), |
493 | |
494 | GATE(CLK_SCLK_UART0, "sclk_uart0" , "div_uart0" , |
495 | SRC_MASK_PERIC0, 0, CLK_SET_RATE_PARENT, 0), |
496 | GATE(CLK_SCLK_UART1, "sclk_uart1" , "div_uart1" , |
497 | SRC_MASK_PERIC0, 4, CLK_SET_RATE_PARENT, 0), |
498 | GATE(CLK_SCLK_UART2, "sclk_uart2" , "div_uart2" , |
499 | SRC_MASK_PERIC0, 8, CLK_SET_RATE_PARENT, 0), |
500 | GATE(CLK_SCLK_UART3, "sclk_uart3" , "div_uart3" , |
501 | SRC_MASK_PERIC0, 12, CLK_SET_RATE_PARENT, 0), |
502 | GATE(CLK_SCLK_PWM, "sclk_pwm" , "div_pwm" , |
503 | SRC_MASK_PERIC0, 24, CLK_SET_RATE_PARENT, 0), |
504 | |
505 | GATE(CLK_SCLK_AUDIO1, "sclk_audio1" , "div_audio1" , |
506 | SRC_MASK_PERIC1, 0, CLK_SET_RATE_PARENT, 0), |
507 | GATE(CLK_SCLK_AUDIO2, "sclk_audio2" , "div_audio2" , |
508 | SRC_MASK_PERIC1, 4, CLK_SET_RATE_PARENT, 0), |
509 | GATE(CLK_SCLK_SPDIF, "sclk_spdif" , "mout_spdif" , |
510 | SRC_MASK_PERIC1, 4, 0, 0), |
511 | GATE(CLK_SCLK_SPI0, "sclk_spi0" , "div_spi_pre0" , |
512 | SRC_MASK_PERIC1, 16, CLK_SET_RATE_PARENT, 0), |
513 | GATE(CLK_SCLK_SPI1, "sclk_spi1" , "div_spi_pre1" , |
514 | SRC_MASK_PERIC1, 20, CLK_SET_RATE_PARENT, 0), |
515 | GATE(CLK_SCLK_SPI2, "sclk_spi2" , "div_spi_pre2" , |
516 | SRC_MASK_PERIC1, 24, CLK_SET_RATE_PARENT, 0), |
517 | |
518 | GATE(CLK_GSCL0, "gscl0" , "mout_aclk266_gscl_sub" , GATE_IP_GSCL, 0, 0, |
519 | 0), |
520 | GATE(CLK_GSCL1, "gscl1" , "mout_aclk266_gscl_sub" , GATE_IP_GSCL, 1, 0, |
521 | 0), |
522 | GATE(CLK_GSCL2, "gscl2" , "mout_aclk266_gscl_sub" , GATE_IP_GSCL, 2, 0, |
523 | 0), |
524 | GATE(CLK_GSCL3, "gscl3" , "mout_aclk266_gscl_sub" , GATE_IP_GSCL, 3, 0, |
525 | 0), |
526 | GATE(CLK_CAMIF_TOP, "camif_top" , "mout_aclk266_gscl_sub" , |
527 | GATE_IP_GSCL, 4, 0, 0), |
528 | GATE(CLK_GSCL_WA, "gscl_wa" , "div_gscl_wa" , GATE_IP_GSCL, 5, 0, 0), |
529 | GATE(CLK_GSCL_WB, "gscl_wb" , "div_gscl_wb" , GATE_IP_GSCL, 6, 0, 0), |
530 | GATE(CLK_SMMU_GSCL0, "smmu_gscl0" , "mout_aclk266_gscl_sub" , |
531 | GATE_IP_GSCL, 7, 0, 0), |
532 | GATE(CLK_SMMU_GSCL1, "smmu_gscl1" , "mout_aclk266_gscl_sub" , |
533 | GATE_IP_GSCL, 8, 0, 0), |
534 | GATE(CLK_SMMU_GSCL2, "smmu_gscl2" , "mout_aclk266_gscl_sub" , |
535 | GATE_IP_GSCL, 9, 0, 0), |
536 | GATE(CLK_SMMU_GSCL3, "smmu_gscl3" , "mout_aclk266_gscl_sub" , |
537 | GATE_IP_GSCL, 10, 0, 0), |
538 | GATE(CLK_SMMU_FIMC_LITE0, "smmu_fimc_lite0" , "mout_aclk266_gscl_sub" , |
539 | GATE_IP_GSCL, 11, 0, 0), |
540 | GATE(CLK_SMMU_FIMC_LITE1, "smmu_fimc_lite1" , "mout_aclk266_gscl_sub" , |
541 | GATE_IP_GSCL, 12, 0, 0), |
542 | |
543 | |
544 | GATE(CLK_MFC, "mfc" , "mout_aclk333_sub" , GATE_IP_MFC, 0, 0, 0), |
545 | GATE(CLK_SMMU_MFCR, "smmu_mfcr" , "mout_aclk333_sub" , GATE_IP_MFC, 1, 0, |
546 | 0), |
547 | GATE(CLK_SMMU_MFCL, "smmu_mfcl" , "mout_aclk333_sub" , GATE_IP_MFC, 2, 0, |
548 | 0), |
549 | GATE(CLK_G3D, "g3d" , "div_aclk400_g3d" , GATE_IP_G3D, 0, |
550 | CLK_SET_RATE_PARENT, 0), |
551 | GATE(CLK_ROTATOR, "rotator" , "div_aclk266" , GATE_IP_GEN, 1, 0, 0), |
552 | GATE(CLK_JPEG, "jpeg" , "div_aclk166" , GATE_IP_GEN, 2, 0, 0), |
553 | GATE(CLK_MDMA1, "mdma1" , "div_aclk266" , GATE_IP_GEN, 4, 0, 0), |
554 | GATE(CLK_SMMU_ROTATOR, "smmu_rotator" , "div_aclk266" , GATE_IP_GEN, 6, 0, |
555 | 0), |
556 | GATE(CLK_SMMU_JPEG, "smmu_jpeg" , "div_aclk166" , GATE_IP_GEN, 7, 0, 0), |
557 | GATE(CLK_SMMU_MDMA1, "smmu_mdma1" , "div_aclk266" , GATE_IP_GEN, 9, 0, 0), |
558 | |
559 | GATE(CLK_PDMA0, "pdma0" , "div_aclk200" , GATE_IP_FSYS, 1, 0, 0), |
560 | GATE(CLK_PDMA1, "pdma1" , "div_aclk200" , GATE_IP_FSYS, 2, 0, 0), |
561 | GATE(CLK_SATA, "sata" , "div_aclk200" , GATE_IP_FSYS, 6, 0, 0), |
562 | GATE(CLK_USBOTG, "usbotg" , "div_aclk200" , GATE_IP_FSYS, 7, 0, 0), |
563 | GATE(CLK_MIPI_HSI, "mipi_hsi" , "div_aclk200" , GATE_IP_FSYS, 8, 0, 0), |
564 | GATE(CLK_SDMMC0, "sdmmc0" , "div_aclk200" , GATE_IP_FSYS, 12, 0, 0), |
565 | GATE(CLK_SDMMC1, "sdmmc1" , "div_aclk200" , GATE_IP_FSYS, 13, 0, 0), |
566 | GATE(CLK_SDMMC2, "sdmmc2" , "div_aclk200" , GATE_IP_FSYS, 14, 0, 0), |
567 | GATE(CLK_SDMMC3, "sdmmc3" , "div_aclk200" , GATE_IP_FSYS, 15, 0, 0), |
568 | GATE(CLK_SROMC, "sromc" , "div_aclk200" , GATE_IP_FSYS, 17, 0, 0), |
569 | GATE(CLK_USB2, "usb2" , "div_aclk200" , GATE_IP_FSYS, 18, 0, 0), |
570 | GATE(CLK_USB3, "usb3" , "div_aclk200" , GATE_IP_FSYS, 19, 0, 0), |
571 | GATE(CLK_SATA_PHYCTRL, "sata_phyctrl" , "div_aclk200" , |
572 | GATE_IP_FSYS, 24, 0, 0), |
573 | GATE(CLK_SATA_PHYI2C, "sata_phyi2c" , "div_aclk200" , GATE_IP_FSYS, 25, 0, |
574 | 0), |
575 | |
576 | GATE(CLK_UART0, "uart0" , "div_aclk66" , GATE_IP_PERIC, 0, 0, 0), |
577 | GATE(CLK_UART1, "uart1" , "div_aclk66" , GATE_IP_PERIC, 1, 0, 0), |
578 | GATE(CLK_UART2, "uart2" , "div_aclk66" , GATE_IP_PERIC, 2, 0, 0), |
579 | GATE(CLK_UART3, "uart3" , "div_aclk66" , GATE_IP_PERIC, 3, 0, 0), |
580 | GATE(CLK_UART4, "uart4" , "div_aclk66" , GATE_IP_PERIC, 4, 0, 0), |
581 | GATE(CLK_I2C0, "i2c0" , "div_aclk66" , GATE_IP_PERIC, 6, 0, 0), |
582 | GATE(CLK_I2C1, "i2c1" , "div_aclk66" , GATE_IP_PERIC, 7, 0, 0), |
583 | GATE(CLK_I2C2, "i2c2" , "div_aclk66" , GATE_IP_PERIC, 8, 0, 0), |
584 | GATE(CLK_I2C3, "i2c3" , "div_aclk66" , GATE_IP_PERIC, 9, 0, 0), |
585 | GATE(CLK_I2C4, "i2c4" , "div_aclk66" , GATE_IP_PERIC, 10, 0, 0), |
586 | GATE(CLK_I2C5, "i2c5" , "div_aclk66" , GATE_IP_PERIC, 11, 0, 0), |
587 | GATE(CLK_I2C6, "i2c6" , "div_aclk66" , GATE_IP_PERIC, 12, 0, 0), |
588 | GATE(CLK_I2C7, "i2c7" , "div_aclk66" , GATE_IP_PERIC, 13, 0, 0), |
589 | GATE(CLK_I2C_HDMI, "i2c_hdmi" , "div_aclk66" , GATE_IP_PERIC, 14, 0, 0), |
590 | GATE(CLK_ADC, "adc" , "div_aclk66" , GATE_IP_PERIC, 15, 0, 0), |
591 | GATE(CLK_SPI0, "spi0" , "div_aclk66" , GATE_IP_PERIC, 16, 0, 0), |
592 | GATE(CLK_SPI1, "spi1" , "div_aclk66" , GATE_IP_PERIC, 17, 0, 0), |
593 | GATE(CLK_SPI2, "spi2" , "div_aclk66" , GATE_IP_PERIC, 18, 0, 0), |
594 | GATE(CLK_I2S1, "i2s1" , "div_aclk66" , GATE_IP_PERIC, 20, 0, 0), |
595 | GATE(CLK_I2S2, "i2s2" , "div_aclk66" , GATE_IP_PERIC, 21, 0, 0), |
596 | GATE(CLK_PCM1, "pcm1" , "div_aclk66" , GATE_IP_PERIC, 22, 0, 0), |
597 | GATE(CLK_PCM2, "pcm2" , "div_aclk66" , GATE_IP_PERIC, 23, 0, 0), |
598 | GATE(CLK_PWM, "pwm" , "div_aclk66" , GATE_IP_PERIC, 24, 0, 0), |
599 | GATE(CLK_SPDIF, "spdif" , "div_aclk66" , GATE_IP_PERIC, 26, 0, 0), |
600 | GATE(CLK_AC97, "ac97" , "div_aclk66" , GATE_IP_PERIC, 27, 0, 0), |
601 | GATE(CLK_HSI2C0, "hsi2c0" , "div_aclk66" , GATE_IP_PERIC, 28, 0, 0), |
602 | GATE(CLK_HSI2C1, "hsi2c1" , "div_aclk66" , GATE_IP_PERIC, 29, 0, 0), |
603 | GATE(CLK_HSI2C2, "hsi2c2" , "div_aclk66" , GATE_IP_PERIC, 30, 0, 0), |
604 | GATE(CLK_HSI2C3, "hsi2c3" , "div_aclk66" , GATE_IP_PERIC, 31, 0, 0), |
605 | |
606 | GATE(CLK_CHIPID, "chipid" , "div_aclk66" , GATE_IP_PERIS, 0, 0, 0), |
607 | GATE(CLK_SYSREG, "sysreg" , "div_aclk66" , |
608 | GATE_IP_PERIS, 1, CLK_IGNORE_UNUSED, 0), |
609 | GATE(CLK_PMU, "pmu" , "div_aclk66" , GATE_IP_PERIS, 2, CLK_IGNORE_UNUSED, |
610 | 0), |
611 | GATE(CLK_CMU_TOP, "cmu_top" , "div_aclk66" , |
612 | GATE_IP_PERIS, 3, CLK_IGNORE_UNUSED, 0), |
613 | GATE(CLK_CMU_CORE, "cmu_core" , "div_aclk66" , |
614 | GATE_IP_PERIS, 4, CLK_IGNORE_UNUSED, 0), |
615 | GATE(CLK_CMU_MEM, "cmu_mem" , "div_aclk66" , |
616 | GATE_IP_PERIS, 5, CLK_IGNORE_UNUSED, 0), |
617 | GATE(CLK_TZPC0, "tzpc0" , "div_aclk66" , GATE_IP_PERIS, 6, 0, 0), |
618 | GATE(CLK_TZPC1, "tzpc1" , "div_aclk66" , GATE_IP_PERIS, 7, 0, 0), |
619 | GATE(CLK_TZPC2, "tzpc2" , "div_aclk66" , GATE_IP_PERIS, 8, 0, 0), |
620 | GATE(CLK_TZPC3, "tzpc3" , "div_aclk66" , GATE_IP_PERIS, 9, 0, 0), |
621 | GATE(CLK_TZPC4, "tzpc4" , "div_aclk66" , GATE_IP_PERIS, 10, 0, 0), |
622 | GATE(CLK_TZPC5, "tzpc5" , "div_aclk66" , GATE_IP_PERIS, 11, 0, 0), |
623 | GATE(CLK_TZPC6, "tzpc6" , "div_aclk66" , GATE_IP_PERIS, 12, 0, 0), |
624 | GATE(CLK_TZPC7, "tzpc7" , "div_aclk66" , GATE_IP_PERIS, 13, 0, 0), |
625 | GATE(CLK_TZPC8, "tzpc8" , "div_aclk66" , GATE_IP_PERIS, 14, 0, 0), |
626 | GATE(CLK_TZPC9, "tzpc9" , "div_aclk66" , GATE_IP_PERIS, 15, 0, 0), |
627 | GATE(CLK_HDMI_CEC, "hdmi_cec" , "div_aclk66" , GATE_IP_PERIS, 16, 0, 0), |
628 | GATE(CLK_MCT, "mct" , "div_aclk66" , GATE_IP_PERIS, 18, 0, 0), |
629 | GATE(CLK_WDT, "wdt" , "div_aclk66" , GATE_IP_PERIS, 19, 0, 0), |
630 | GATE(CLK_RTC, "rtc" , "div_aclk66" , GATE_IP_PERIS, 20, 0, 0), |
631 | GATE(CLK_TMU, "tmu" , "div_aclk66" , GATE_IP_PERIS, 21, 0, 0), |
632 | GATE(CLK_SMMU_2D, "smmu_2d" , "div_aclk200" , GATE_IP_ACP, 7, 0, 0), |
633 | GATE(CLK_SMMU_FIMC_ISP, "smmu_fimc_isp" , "mout_aclk_266_isp_sub" , |
634 | GATE_IP_ISP0, 8, 0, 0), |
635 | GATE(CLK_SMMU_FIMC_DRC, "smmu_fimc_drc" , "mout_aclk_266_isp_sub" , |
636 | GATE_IP_ISP0, 9, 0, 0), |
637 | GATE(CLK_SMMU_FIMC_FD, "smmu_fimc_fd" , "mout_aclk_266_isp_sub" , |
638 | GATE_IP_ISP0, 10, 0, 0), |
639 | GATE(CLK_SMMU_FIMC_SCC, "smmu_fimc_scc" , "mout_aclk_266_isp_sub" , |
640 | GATE_IP_ISP0, 11, 0, 0), |
641 | GATE(CLK_SMMU_FIMC_SCP, "smmu_fimc_scp" , "mout_aclk_266_isp_sub" , |
642 | GATE_IP_ISP0, 12, 0, 0), |
643 | GATE(CLK_SMMU_FIMC_MCU, "smmu_fimc_mcu" , "mout_aclk_400_isp_sub" , |
644 | GATE_IP_ISP0, 13, 0, 0), |
645 | GATE(CLK_SMMU_FIMC_ODC, "smmu_fimc_odc" , "mout_aclk_266_isp_sub" , |
646 | GATE_IP_ISP1, 4, 0, 0), |
647 | GATE(CLK_SMMU_FIMC_DIS0, "smmu_fimc_dis0" , "mout_aclk_266_isp_sub" , |
648 | GATE_IP_ISP1, 5, 0, 0), |
649 | GATE(CLK_SMMU_FIMC_DIS1, "smmu_fimc_dis1" , "mout_aclk_266_isp_sub" , |
650 | GATE_IP_ISP1, 6, 0, 0), |
651 | GATE(CLK_SMMU_FIMC_3DNR, "smmu_fimc_3dnr" , "mout_aclk_266_isp_sub" , |
652 | GATE_IP_ISP1, 7, 0, 0), |
653 | }; |
654 | |
655 | static const struct samsung_gate_clock exynos5250_disp_gate_clks[] __initconst = { |
656 | GATE(CLK_FIMD1, "fimd1" , "mout_aclk200_disp1_sub" , GATE_IP_DISP1, 0, 0, |
657 | 0), |
658 | GATE(CLK_MIE1, "mie1" , "mout_aclk200_disp1_sub" , GATE_IP_DISP1, 1, 0, |
659 | 0), |
660 | GATE(CLK_DSIM0, "dsim0" , "mout_aclk200_disp1_sub" , GATE_IP_DISP1, 3, 0, |
661 | 0), |
662 | GATE(CLK_DP, "dp" , "mout_aclk200_disp1_sub" , GATE_IP_DISP1, 4, 0, 0), |
663 | GATE(CLK_MIXER, "mixer" , "mout_aclk200_disp1_sub" , GATE_IP_DISP1, 5, 0, |
664 | 0), |
665 | GATE(CLK_HDMI, "hdmi" , "mout_aclk200_disp1_sub" , GATE_IP_DISP1, 6, 0, |
666 | 0), |
667 | GATE(CLK_SMMU_TV, "smmu_tv" , "mout_aclk200_disp1_sub" , |
668 | GATE_IP_DISP1, 9, 0, 0), |
669 | GATE(CLK_SMMU_FIMD1, "smmu_fimd1" , "mout_aclk200_disp1_sub" , |
670 | GATE_IP_DISP1, 8, 0, 0), |
671 | }; |
672 | |
673 | static struct exynos5_subcmu_reg_dump exynos5250_disp_suspend_regs[] = { |
674 | { GATE_IP_DISP1, 0xffffffff, 0xffffffff }, /* DISP1 gates */ |
675 | { SRC_TOP3, 0, BIT(4) }, /* MUX mout_aclk200_disp1_sub */ |
676 | { SRC_TOP3, 0, BIT(6) }, /* MUX mout_aclk300_disp1_sub */ |
677 | }; |
678 | |
679 | static const struct exynos5_subcmu_info exynos5250_disp_subcmu = { |
680 | .gate_clks = exynos5250_disp_gate_clks, |
681 | .nr_gate_clks = ARRAY_SIZE(exynos5250_disp_gate_clks), |
682 | .suspend_regs = exynos5250_disp_suspend_regs, |
683 | .nr_suspend_regs = ARRAY_SIZE(exynos5250_disp_suspend_regs), |
684 | .pd_name = "DISP1" , |
685 | }; |
686 | |
687 | static const struct exynos5_subcmu_info *exynos5250_subcmus[] = { |
688 | &exynos5250_disp_subcmu, |
689 | }; |
690 | |
691 | static const struct samsung_pll_rate_table vpll_24mhz_tbl[] __initconst = { |
692 | /* sorted in descending order */ |
693 | /* PLL_36XX_RATE(rate, m, p, s, k) */ |
694 | PLL_36XX_RATE(24 * MHZ, 266000000, 266, 3, 3, 0), |
695 | /* Not in UM, but need for eDP on snow */ |
696 | PLL_36XX_RATE(24 * MHZ, 70500000, 94, 2, 4, 0), |
697 | { }, |
698 | }; |
699 | |
700 | static const struct samsung_pll_rate_table epll_24mhz_tbl[] __initconst = { |
701 | /* sorted in descending order */ |
702 | /* PLL_36XX_RATE(rate, m, p, s, k) */ |
703 | PLL_36XX_RATE(24 * MHZ, 192000000, 64, 2, 2, 0), |
704 | PLL_36XX_RATE(24 * MHZ, 180633605, 90, 3, 2, 20762), |
705 | PLL_36XX_RATE(24 * MHZ, 180000000, 90, 3, 2, 0), |
706 | PLL_36XX_RATE(24 * MHZ, 73728000, 98, 2, 4, 19923), |
707 | PLL_36XX_RATE(24 * MHZ, 67737602, 90, 2, 4, 20762), |
708 | PLL_36XX_RATE(24 * MHZ, 49152000, 98, 3, 4, 19923), |
709 | PLL_36XX_RATE(24 * MHZ, 45158401, 90, 3, 4, 20762), |
710 | PLL_36XX_RATE(24 * MHZ, 32768001, 131, 3, 5, 4719), |
711 | { }, |
712 | }; |
713 | |
714 | static const struct samsung_pll_rate_table apll_24mhz_tbl[] __initconst = { |
715 | /* sorted in descending order */ |
716 | /* PLL_35XX_RATE(fin, rate, m, p, s) */ |
717 | PLL_35XX_RATE(24 * MHZ, 1700000000, 425, 6, 0), |
718 | PLL_35XX_RATE(24 * MHZ, 1600000000, 200, 3, 0), |
719 | PLL_35XX_RATE(24 * MHZ, 1500000000, 250, 4, 0), |
720 | PLL_35XX_RATE(24 * MHZ, 1400000000, 175, 3, 0), |
721 | PLL_35XX_RATE(24 * MHZ, 1300000000, 325, 6, 0), |
722 | PLL_35XX_RATE(24 * MHZ, 1200000000, 200, 4, 0), |
723 | PLL_35XX_RATE(24 * MHZ, 1100000000, 275, 6, 0), |
724 | PLL_35XX_RATE(24 * MHZ, 1000000000, 125, 3, 0), |
725 | PLL_35XX_RATE(24 * MHZ, 900000000, 150, 4, 0), |
726 | PLL_35XX_RATE(24 * MHZ, 800000000, 100, 3, 0), |
727 | PLL_35XX_RATE(24 * MHZ, 700000000, 175, 3, 1), |
728 | PLL_35XX_RATE(24 * MHZ, 600000000, 200, 4, 1), |
729 | PLL_35XX_RATE(24 * MHZ, 500000000, 125, 3, 1), |
730 | PLL_35XX_RATE(24 * MHZ, 400000000, 100, 3, 1), |
731 | PLL_35XX_RATE(24 * MHZ, 300000000, 200, 4, 2), |
732 | PLL_35XX_RATE(24 * MHZ, 200000000, 100, 3, 2), |
733 | }; |
734 | |
735 | static struct samsung_pll_clock exynos5250_plls[nr_plls] __initdata = { |
736 | [apll] = PLL(pll_35xx, CLK_FOUT_APLL, "fout_apll" , "fin_pll" , APLL_LOCK, |
737 | APLL_CON0, NULL), |
738 | [mpll] = PLL(pll_35xx, CLK_FOUT_MPLL, "fout_mpll" , "fin_pll" , MPLL_LOCK, |
739 | MPLL_CON0, NULL), |
740 | [bpll] = PLL(pll_35xx, CLK_FOUT_BPLL, "fout_bpll" , "fin_pll" , BPLL_LOCK, |
741 | BPLL_CON0, NULL), |
742 | [gpll] = PLL(pll_35xx, CLK_FOUT_GPLL, "fout_gpll" , "fin_pll" , GPLL_LOCK, |
743 | GPLL_CON0, NULL), |
744 | [cpll] = PLL(pll_35xx, CLK_FOUT_CPLL, "fout_cpll" , "fin_pll" , CPLL_LOCK, |
745 | CPLL_CON0, NULL), |
746 | [epll] = PLL(pll_36xx, CLK_FOUT_EPLL, "fout_epll" , "fin_pll" , EPLL_LOCK, |
747 | EPLL_CON0, NULL), |
748 | [vpll] = PLL(pll_36xx, CLK_FOUT_VPLL, "fout_vpll" , "mout_vpllsrc" , |
749 | VPLL_LOCK, VPLL_CON0, NULL), |
750 | }; |
751 | |
752 | #define E5250_CPU_DIV0(apll, pclk_dbg, atb, periph, acp, cpud) \ |
753 | ((((apll) << 24) | ((pclk_dbg) << 20) | ((atb) << 16) | \ |
754 | ((periph) << 12) | ((acp) << 8) | ((cpud) << 4))) |
755 | #define E5250_CPU_DIV1(hpm, copy) \ |
756 | (((hpm) << 4) | (copy)) |
757 | |
758 | static const struct exynos_cpuclk_cfg_data exynos5250_armclk_d[] __initconst = { |
759 | { 1700000, E5250_CPU_DIV0(5, 3, 7, 7, 7, 3), E5250_CPU_DIV1(2, 0), }, |
760 | { 1600000, E5250_CPU_DIV0(4, 1, 7, 7, 7, 3), E5250_CPU_DIV1(2, 0), }, |
761 | { 1500000, E5250_CPU_DIV0(4, 1, 7, 7, 7, 2), E5250_CPU_DIV1(2, 0), }, |
762 | { 1400000, E5250_CPU_DIV0(4, 1, 6, 7, 7, 2), E5250_CPU_DIV1(2, 0), }, |
763 | { 1300000, E5250_CPU_DIV0(3, 1, 6, 7, 7, 2), E5250_CPU_DIV1(2, 0), }, |
764 | { 1200000, E5250_CPU_DIV0(3, 1, 5, 7, 7, 2), E5250_CPU_DIV1(2, 0), }, |
765 | { 1100000, E5250_CPU_DIV0(3, 1, 5, 7, 7, 3), E5250_CPU_DIV1(2, 0), }, |
766 | { 1000000, E5250_CPU_DIV0(2, 1, 4, 7, 7, 1), E5250_CPU_DIV1(2, 0), }, |
767 | { 900000, E5250_CPU_DIV0(2, 1, 4, 7, 7, 1), E5250_CPU_DIV1(2, 0), }, |
768 | { 800000, E5250_CPU_DIV0(2, 1, 4, 7, 7, 1), E5250_CPU_DIV1(2, 0), }, |
769 | { 700000, E5250_CPU_DIV0(1, 1, 3, 7, 7, 1), E5250_CPU_DIV1(2, 0), }, |
770 | { 600000, E5250_CPU_DIV0(1, 1, 3, 7, 7, 1), E5250_CPU_DIV1(2, 0), }, |
771 | { 500000, E5250_CPU_DIV0(1, 1, 2, 7, 7, 1), E5250_CPU_DIV1(2, 0), }, |
772 | { 400000, E5250_CPU_DIV0(1, 1, 2, 7, 7, 1), E5250_CPU_DIV1(2, 0), }, |
773 | { 300000, E5250_CPU_DIV0(1, 1, 1, 7, 7, 1), E5250_CPU_DIV1(2, 0), }, |
774 | { 200000, E5250_CPU_DIV0(1, 1, 1, 7, 7, 1), E5250_CPU_DIV1(2, 0), }, |
775 | { 0 }, |
776 | }; |
777 | |
778 | static const struct samsung_cpu_clock exynos5250_cpu_clks[] __initconst = { |
779 | CPU_CLK(CLK_ARM_CLK, "armclk" , CLK_MOUT_APLL, CLK_MOUT_MPLL, CLK_CPU_HAS_DIV1, 0x200, |
780 | exynos5250_armclk_d), |
781 | }; |
782 | |
783 | static const struct of_device_id ext_clk_match[] __initconst = { |
784 | { .compatible = "samsung,clock-xxti" , .data = (void *)0, }, |
785 | { }, |
786 | }; |
787 | |
788 | /* register exynox5250 clocks */ |
789 | static void __init exynos5250_clk_init(struct device_node *np) |
790 | { |
791 | struct samsung_clk_provider *ctx; |
792 | unsigned int tmp; |
793 | struct clk_hw **hws; |
794 | |
795 | if (np) { |
796 | reg_base = of_iomap(node: np, index: 0); |
797 | if (!reg_base) |
798 | panic(fmt: "%s: failed to map registers\n" , __func__); |
799 | } else { |
800 | panic(fmt: "%s: unable to determine soc\n" , __func__); |
801 | } |
802 | |
803 | ctx = samsung_clk_init(NULL, base: reg_base, CLKS_NR); |
804 | hws = ctx->clk_data.hws; |
805 | |
806 | samsung_clk_of_register_fixed_ext(ctx, fixed_rate_clk: exynos5250_fixed_rate_ext_clks, |
807 | ARRAY_SIZE(exynos5250_fixed_rate_ext_clks), |
808 | clk_matches: ext_clk_match); |
809 | samsung_clk_register_mux(ctx, clk_list: exynos5250_pll_pmux_clks, |
810 | ARRAY_SIZE(exynos5250_pll_pmux_clks)); |
811 | |
812 | if (clk_hw_get_rate(hw: hws[CLK_FIN_PLL]) == 24 * MHZ) { |
813 | exynos5250_plls[epll].rate_table = epll_24mhz_tbl; |
814 | exynos5250_plls[apll].rate_table = apll_24mhz_tbl; |
815 | } |
816 | |
817 | if (clk_hw_get_rate(hw: hws[CLK_MOUT_VPLLSRC]) == 24 * MHZ) |
818 | exynos5250_plls[vpll].rate_table = vpll_24mhz_tbl; |
819 | |
820 | samsung_clk_register_pll(ctx, pll_list: exynos5250_plls, |
821 | ARRAY_SIZE(exynos5250_plls)); |
822 | samsung_clk_register_fixed_rate(ctx, clk_list: exynos5250_fixed_rate_clks, |
823 | ARRAY_SIZE(exynos5250_fixed_rate_clks)); |
824 | samsung_clk_register_fixed_factor(ctx, list: exynos5250_fixed_factor_clks, |
825 | ARRAY_SIZE(exynos5250_fixed_factor_clks)); |
826 | samsung_clk_register_mux(ctx, clk_list: exynos5250_mux_clks, |
827 | ARRAY_SIZE(exynos5250_mux_clks)); |
828 | samsung_clk_register_div(ctx, clk_list: exynos5250_div_clks, |
829 | ARRAY_SIZE(exynos5250_div_clks)); |
830 | samsung_clk_register_gate(ctx, clk_list: exynos5250_gate_clks, |
831 | ARRAY_SIZE(exynos5250_gate_clks)); |
832 | samsung_clk_register_cpu(ctx, list: exynos5250_cpu_clks, |
833 | ARRAY_SIZE(exynos5250_cpu_clks)); |
834 | |
835 | /* |
836 | * Enable arm clock down (in idle) and set arm divider |
837 | * ratios in WFI/WFE state. |
838 | */ |
839 | tmp = (PWR_CTRL1_CORE2_DOWN_RATIO | PWR_CTRL1_CORE1_DOWN_RATIO | |
840 | PWR_CTRL1_DIV2_DOWN_EN | PWR_CTRL1_DIV1_DOWN_EN | |
841 | PWR_CTRL1_USE_CORE1_WFE | PWR_CTRL1_USE_CORE0_WFE | |
842 | PWR_CTRL1_USE_CORE1_WFI | PWR_CTRL1_USE_CORE0_WFI); |
843 | __raw_writel(val: tmp, addr: reg_base + PWR_CTRL1); |
844 | |
845 | /* |
846 | * Enable arm clock up (on exiting idle). Set arm divider |
847 | * ratios when not in idle along with the standby duration |
848 | * ratios. |
849 | */ |
850 | tmp = (PWR_CTRL2_DIV2_UP_EN | PWR_CTRL2_DIV1_UP_EN | |
851 | PWR_CTRL2_DUR_STANDBY2_VAL | PWR_CTRL2_DUR_STANDBY1_VAL | |
852 | PWR_CTRL2_CORE2_UP_RATIO | PWR_CTRL2_CORE1_UP_RATIO); |
853 | __raw_writel(val: tmp, addr: reg_base + PWR_CTRL2); |
854 | |
855 | samsung_clk_sleep_init(reg_base, exynos5250_clk_regs, |
856 | ARRAY_SIZE(exynos5250_clk_regs)); |
857 | exynos5_subcmus_init(ctx, ARRAY_SIZE(exynos5250_subcmus), |
858 | cmu: exynos5250_subcmus); |
859 | |
860 | samsung_clk_of_add_provider(np, ctx); |
861 | |
862 | pr_info("Exynos5250: clock setup completed, armclk=%ld\n" , |
863 | clk_hw_get_rate(hws[CLK_DIV_ARM2])); |
864 | } |
865 | CLK_OF_DECLARE_DRIVER(exynos5250_clk, "samsung,exynos5250-clock" , exynos5250_clk_init); |
866 | |