• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2012 Samsung Electronics Co., Ltd.
3  *		http://www.samsung.com
4  *
5  * Clock support for EXYNOS5 SoCs
6  *
7  * This program is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License version 2 as
9  * published by the Free Software Foundation.
10 */
11 
12 #include <linux/kernel.h>
13 #include <linux/err.h>
14 #include <linux/io.h>
15 #include <linux/syscore_ops.h>
16 
17 #include <plat/cpu-freq.h>
18 #include <plat/clock.h>
19 #include <plat/cpu.h>
20 #include <plat/pll.h>
21 #include <plat/s5p-clock.h>
22 #include <plat/clock-clksrc.h>
23 #include <plat/pm.h>
24 
25 #include <mach/map.h>
26 #include <mach/regs-clock.h>
27 #include <mach/sysmmu.h>
28 
29 #include "common.h"
30 
31 #ifdef CONFIG_PM_SLEEP
32 static struct sleep_save exynos5_clock_save[] = {
33 	/* will be implemented */
34 };
35 #endif
36 
37 static struct clk exynos5_clk_sclk_dptxphy = {
38 	.name		= "sclk_dptx",
39 };
40 
41 static struct clk exynos5_clk_sclk_hdmi24m = {
42 	.name		= "sclk_hdmi24m",
43 	.rate		= 24000000,
44 };
45 
46 static struct clk exynos5_clk_sclk_hdmi27m = {
47 	.name		= "sclk_hdmi27m",
48 	.rate		= 27000000,
49 };
50 
51 static struct clk exynos5_clk_sclk_hdmiphy = {
52 	.name		= "sclk_hdmiphy",
53 };
54 
55 static struct clk exynos5_clk_sclk_usbphy = {
56 	.name		= "sclk_usbphy",
57 	.rate		= 48000000,
58 };
59 
exynos5_clksrc_mask_top_ctrl(struct clk * clk,int enable)60 static int exynos5_clksrc_mask_top_ctrl(struct clk *clk, int enable)
61 {
62 	return s5p_gatectrl(EXYNOS5_CLKSRC_MASK_TOP, clk, enable);
63 }
64 
exynos5_clksrc_mask_disp1_0_ctrl(struct clk * clk,int enable)65 static int exynos5_clksrc_mask_disp1_0_ctrl(struct clk *clk, int enable)
66 {
67 	return s5p_gatectrl(EXYNOS5_CLKSRC_MASK_DISP1_0, clk, enable);
68 }
69 
exynos5_clksrc_mask_fsys_ctrl(struct clk * clk,int enable)70 static int exynos5_clksrc_mask_fsys_ctrl(struct clk *clk, int enable)
71 {
72 	return s5p_gatectrl(EXYNOS5_CLKSRC_MASK_FSYS, clk, enable);
73 }
74 
exynos5_clksrc_mask_gscl_ctrl(struct clk * clk,int enable)75 static int exynos5_clksrc_mask_gscl_ctrl(struct clk *clk, int enable)
76 {
77 	return s5p_gatectrl(EXYNOS5_CLKSRC_MASK_GSCL, clk, enable);
78 }
79 
exynos5_clksrc_mask_peric0_ctrl(struct clk * clk,int enable)80 static int exynos5_clksrc_mask_peric0_ctrl(struct clk *clk, int enable)
81 {
82 	return s5p_gatectrl(EXYNOS5_CLKSRC_MASK_PERIC0, clk, enable);
83 }
84 
exynos5_clk_ip_core_ctrl(struct clk * clk,int enable)85 static int exynos5_clk_ip_core_ctrl(struct clk *clk, int enable)
86 {
87 	return s5p_gatectrl(EXYNOS5_CLKGATE_IP_CORE, clk, enable);
88 }
89 
exynos5_clk_ip_disp1_ctrl(struct clk * clk,int enable)90 static int exynos5_clk_ip_disp1_ctrl(struct clk *clk, int enable)
91 {
92 	return s5p_gatectrl(EXYNOS5_CLKGATE_IP_DISP1, clk, enable);
93 }
94 
exynos5_clk_ip_fsys_ctrl(struct clk * clk,int enable)95 static int exynos5_clk_ip_fsys_ctrl(struct clk *clk, int enable)
96 {
97 	return s5p_gatectrl(EXYNOS5_CLKGATE_IP_FSYS, clk, enable);
98 }
99 
exynos5_clk_block_ctrl(struct clk * clk,int enable)100 static int exynos5_clk_block_ctrl(struct clk *clk, int enable)
101 {
102 	return s5p_gatectrl(EXYNOS5_CLKGATE_BLOCK, clk, enable);
103 }
104 
exynos5_clk_ip_gen_ctrl(struct clk * clk,int enable)105 static int exynos5_clk_ip_gen_ctrl(struct clk *clk, int enable)
106 {
107 	return s5p_gatectrl(EXYNOS5_CLKGATE_IP_GEN, clk, enable);
108 }
109 
exynos5_clk_ip_gps_ctrl(struct clk * clk,int enable)110 static int exynos5_clk_ip_gps_ctrl(struct clk *clk, int enable)
111 {
112 	return s5p_gatectrl(EXYNOS5_CLKGATE_IP_GPS, clk, enable);
113 }
114 
exynos5_clk_ip_mfc_ctrl(struct clk * clk,int enable)115 static int exynos5_clk_ip_mfc_ctrl(struct clk *clk, int enable)
116 {
117 	return s5p_gatectrl(EXYNOS5_CLKGATE_IP_MFC, clk, enable);
118 }
119 
exynos5_clk_ip_peric_ctrl(struct clk * clk,int enable)120 static int exynos5_clk_ip_peric_ctrl(struct clk *clk, int enable)
121 {
122 	return s5p_gatectrl(EXYNOS5_CLKGATE_IP_PERIC, clk, enable);
123 }
124 
exynos5_clk_ip_peris_ctrl(struct clk * clk,int enable)125 static int exynos5_clk_ip_peris_ctrl(struct clk *clk, int enable)
126 {
127 	return s5p_gatectrl(EXYNOS5_CLKGATE_IP_PERIS, clk, enable);
128 }
129 
130 /* Core list of CMU_CPU side */
131 
132 static struct clksrc_clk exynos5_clk_mout_apll = {
133 	.clk	= {
134 		.name		= "mout_apll",
135 	},
136 	.sources = &clk_src_apll,
137 	.reg_src = { .reg = EXYNOS5_CLKSRC_CPU, .shift = 0, .size = 1 },
138 };
139 
140 static struct clksrc_clk exynos5_clk_sclk_apll = {
141 	.clk	= {
142 		.name		= "sclk_apll",
143 		.parent		= &exynos5_clk_mout_apll.clk,
144 	},
145 	.reg_div = { .reg = EXYNOS5_CLKDIV_CPU0, .shift = 24, .size = 3 },
146 };
147 
148 static struct clksrc_clk exynos5_clk_mout_bpll = {
149 	.clk	= {
150 		.name		= "mout_bpll",
151 	},
152 	.sources = &clk_src_bpll,
153 	.reg_src = { .reg = EXYNOS5_CLKSRC_CDREX, .shift = 0, .size = 1 },
154 };
155 
156 static struct clk *exynos5_clk_src_bpll_user_list[] = {
157 	[0] = &clk_fin_mpll,
158 	[1] = &exynos5_clk_mout_bpll.clk,
159 };
160 
161 static struct clksrc_sources exynos5_clk_src_bpll_user = {
162 	.sources	= exynos5_clk_src_bpll_user_list,
163 	.nr_sources	= ARRAY_SIZE(exynos5_clk_src_bpll_user_list),
164 };
165 
166 static struct clksrc_clk exynos5_clk_mout_bpll_user = {
167 	.clk	= {
168 		.name		= "mout_bpll_user",
169 	},
170 	.sources = &exynos5_clk_src_bpll_user,
171 	.reg_src = { .reg = EXYNOS5_CLKSRC_TOP2, .shift = 24, .size = 1 },
172 };
173 
174 static struct clksrc_clk exynos5_clk_mout_cpll = {
175 	.clk	= {
176 		.name		= "mout_cpll",
177 	},
178 	.sources = &clk_src_cpll,
179 	.reg_src = { .reg = EXYNOS5_CLKSRC_TOP2, .shift = 8, .size = 1 },
180 };
181 
182 static struct clksrc_clk exynos5_clk_mout_epll = {
183 	.clk	= {
184 		.name		= "mout_epll",
185 	},
186 	.sources = &clk_src_epll,
187 	.reg_src = { .reg = EXYNOS5_CLKSRC_TOP2, .shift = 12, .size = 1 },
188 };
189 
190 struct clksrc_clk exynos5_clk_mout_mpll = {
191 	.clk = {
192 		.name		= "mout_mpll",
193 	},
194 	.sources = &clk_src_mpll,
195 	.reg_src = { .reg = EXYNOS5_CLKSRC_CORE1, .shift = 8, .size = 1 },
196 };
197 
198 static struct clk *exynos_clkset_vpllsrc_list[] = {
199 	[0] = &clk_fin_vpll,
200 	[1] = &exynos5_clk_sclk_hdmi27m,
201 };
202 
203 static struct clksrc_sources exynos5_clkset_vpllsrc = {
204 	.sources	= exynos_clkset_vpllsrc_list,
205 	.nr_sources	= ARRAY_SIZE(exynos_clkset_vpllsrc_list),
206 };
207 
208 static struct clksrc_clk exynos5_clk_vpllsrc = {
209 	.clk	= {
210 		.name		= "vpll_src",
211 		.enable		= exynos5_clksrc_mask_top_ctrl,
212 		.ctrlbit	= (1 << 0),
213 	},
214 	.sources = &exynos5_clkset_vpllsrc,
215 	.reg_src = { .reg = EXYNOS5_CLKSRC_TOP2, .shift = 0, .size = 1 },
216 };
217 
218 static struct clk *exynos5_clkset_sclk_vpll_list[] = {
219 	[0] = &exynos5_clk_vpllsrc.clk,
220 	[1] = &clk_fout_vpll,
221 };
222 
223 static struct clksrc_sources exynos5_clkset_sclk_vpll = {
224 	.sources	= exynos5_clkset_sclk_vpll_list,
225 	.nr_sources	= ARRAY_SIZE(exynos5_clkset_sclk_vpll_list),
226 };
227 
228 static struct clksrc_clk exynos5_clk_sclk_vpll = {
229 	.clk	= {
230 		.name		= "sclk_vpll",
231 	},
232 	.sources = &exynos5_clkset_sclk_vpll,
233 	.reg_src = { .reg = EXYNOS5_CLKSRC_TOP2, .shift = 16, .size = 1 },
234 };
235 
236 static struct clksrc_clk exynos5_clk_sclk_pixel = {
237 	.clk	= {
238 		.name		= "sclk_pixel",
239 		.parent		= &exynos5_clk_sclk_vpll.clk,
240 	},
241 	.reg_div = { .reg = EXYNOS5_CLKDIV_DISP1_0, .shift = 28, .size = 4 },
242 };
243 
244 static struct clk *exynos5_clkset_sclk_hdmi_list[] = {
245 	[0] = &exynos5_clk_sclk_pixel.clk,
246 	[1] = &exynos5_clk_sclk_hdmiphy,
247 };
248 
249 static struct clksrc_sources exynos5_clkset_sclk_hdmi = {
250 	.sources	= exynos5_clkset_sclk_hdmi_list,
251 	.nr_sources	= ARRAY_SIZE(exynos5_clkset_sclk_hdmi_list),
252 };
253 
254 static struct clksrc_clk exynos5_clk_sclk_hdmi = {
255 	.clk	= {
256 		.name		= "sclk_hdmi",
257 		.enable		= exynos5_clksrc_mask_disp1_0_ctrl,
258 		.ctrlbit	= (1 << 20),
259 	},
260 	.sources = &exynos5_clkset_sclk_hdmi,
261 	.reg_src = { .reg = EXYNOS5_CLKSRC_DISP1_0, .shift = 20, .size = 1 },
262 };
263 
264 static struct clksrc_clk *exynos5_sclk_tv[] = {
265 	&exynos5_clk_sclk_pixel,
266 	&exynos5_clk_sclk_hdmi,
267 };
268 
269 static struct clk *exynos5_clk_src_mpll_user_list[] = {
270 	[0] = &clk_fin_mpll,
271 	[1] = &exynos5_clk_mout_mpll.clk,
272 };
273 
274 static struct clksrc_sources exynos5_clk_src_mpll_user = {
275 	.sources	= exynos5_clk_src_mpll_user_list,
276 	.nr_sources	= ARRAY_SIZE(exynos5_clk_src_mpll_user_list),
277 };
278 
279 static struct clksrc_clk exynos5_clk_mout_mpll_user = {
280 	.clk	= {
281 		.name		= "mout_mpll_user",
282 	},
283 	.sources = &exynos5_clk_src_mpll_user,
284 	.reg_src = { .reg = EXYNOS5_CLKSRC_TOP2, .shift = 20, .size = 1 },
285 };
286 
287 static struct clk *exynos5_clkset_mout_cpu_list[] = {
288 	[0] = &exynos5_clk_mout_apll.clk,
289 	[1] = &exynos5_clk_mout_mpll.clk,
290 };
291 
292 static struct clksrc_sources exynos5_clkset_mout_cpu = {
293 	.sources	= exynos5_clkset_mout_cpu_list,
294 	.nr_sources	= ARRAY_SIZE(exynos5_clkset_mout_cpu_list),
295 };
296 
297 static struct clksrc_clk exynos5_clk_mout_cpu = {
298 	.clk	= {
299 		.name		= "mout_cpu",
300 	},
301 	.sources = &exynos5_clkset_mout_cpu,
302 	.reg_src = { .reg = EXYNOS5_CLKSRC_CPU, .shift = 16, .size = 1 },
303 };
304 
305 static struct clksrc_clk exynos5_clk_dout_armclk = {
306 	.clk	= {
307 		.name		= "dout_armclk",
308 		.parent		= &exynos5_clk_mout_cpu.clk,
309 	},
310 	.reg_div = { .reg = EXYNOS5_CLKDIV_CPU0, .shift = 0, .size = 3 },
311 };
312 
313 static struct clksrc_clk exynos5_clk_dout_arm2clk = {
314 	.clk	= {
315 		.name		= "dout_arm2clk",
316 		.parent		= &exynos5_clk_dout_armclk.clk,
317 	},
318 	.reg_div = { .reg = EXYNOS5_CLKDIV_CPU0, .shift = 28, .size = 3 },
319 };
320 
321 static struct clk exynos5_clk_armclk = {
322 	.name		= "armclk",
323 	.parent		= &exynos5_clk_dout_arm2clk.clk,
324 };
325 
326 /* Core list of CMU_CDREX side */
327 
328 static struct clk *exynos5_clkset_cdrex_list[] = {
329 	[0] = &exynos5_clk_mout_mpll.clk,
330 	[1] = &exynos5_clk_mout_bpll.clk,
331 };
332 
333 static struct clksrc_sources exynos5_clkset_cdrex = {
334 	.sources	= exynos5_clkset_cdrex_list,
335 	.nr_sources	= ARRAY_SIZE(exynos5_clkset_cdrex_list),
336 };
337 
338 static struct clksrc_clk exynos5_clk_cdrex = {
339 	.clk	= {
340 		.name		= "clk_cdrex",
341 	},
342 	.sources = &exynos5_clkset_cdrex,
343 	.reg_src = { .reg = EXYNOS5_CLKSRC_CDREX, .shift = 4, .size = 1 },
344 	.reg_div = { .reg = EXYNOS5_CLKDIV_CDREX, .shift = 16, .size = 3 },
345 };
346 
347 static struct clksrc_clk exynos5_clk_aclk_acp = {
348 	.clk	= {
349 		.name		= "aclk_acp",
350 		.parent		= &exynos5_clk_mout_mpll.clk,
351 	},
352 	.reg_div = { .reg = EXYNOS5_CLKDIV_ACP, .shift = 0, .size = 3 },
353 };
354 
355 static struct clksrc_clk exynos5_clk_pclk_acp = {
356 	.clk	= {
357 		.name		= "pclk_acp",
358 		.parent		= &exynos5_clk_aclk_acp.clk,
359 	},
360 	.reg_div = { .reg = EXYNOS5_CLKDIV_ACP, .shift = 4, .size = 3 },
361 };
362 
363 /* Core list of CMU_TOP side */
364 
365 struct clk *exynos5_clkset_aclk_top_list[] = {
366 	[0] = &exynos5_clk_mout_mpll_user.clk,
367 	[1] = &exynos5_clk_mout_bpll_user.clk,
368 };
369 
370 struct clksrc_sources exynos5_clkset_aclk = {
371 	.sources	= exynos5_clkset_aclk_top_list,
372 	.nr_sources	= ARRAY_SIZE(exynos5_clkset_aclk_top_list),
373 };
374 
375 static struct clksrc_clk exynos5_clk_aclk_400 = {
376 	.clk	= {
377 		.name		= "aclk_400",
378 	},
379 	.sources = &exynos5_clkset_aclk,
380 	.reg_src = { .reg = EXYNOS5_CLKSRC_TOP0, .shift = 20, .size = 1 },
381 	.reg_div = { .reg = EXYNOS5_CLKDIV_TOP0, .shift = 24, .size = 3 },
382 };
383 
384 struct clk *exynos5_clkset_aclk_333_166_list[] = {
385 	[0] = &exynos5_clk_mout_cpll.clk,
386 	[1] = &exynos5_clk_mout_mpll_user.clk,
387 };
388 
389 struct clksrc_sources exynos5_clkset_aclk_333_166 = {
390 	.sources	= exynos5_clkset_aclk_333_166_list,
391 	.nr_sources	= ARRAY_SIZE(exynos5_clkset_aclk_333_166_list),
392 };
393 
394 static struct clksrc_clk exynos5_clk_aclk_333 = {
395 	.clk	= {
396 		.name		= "aclk_333",
397 	},
398 	.sources = &exynos5_clkset_aclk_333_166,
399 	.reg_src = { .reg = EXYNOS5_CLKSRC_TOP0, .shift = 16, .size = 1 },
400 	.reg_div = { .reg = EXYNOS5_CLKDIV_TOP0, .shift = 20, .size = 3 },
401 };
402 
403 static struct clksrc_clk exynos5_clk_aclk_166 = {
404 	.clk	= {
405 		.name		= "aclk_166",
406 	},
407 	.sources = &exynos5_clkset_aclk_333_166,
408 	.reg_src = { .reg = EXYNOS5_CLKSRC_TOP0, .shift = 8, .size = 1 },
409 	.reg_div = { .reg = EXYNOS5_CLKDIV_TOP0, .shift = 8, .size = 3 },
410 };
411 
412 static struct clksrc_clk exynos5_clk_aclk_266 = {
413 	.clk	= {
414 		.name		= "aclk_266",
415 		.parent		= &exynos5_clk_mout_mpll_user.clk,
416 	},
417 	.reg_div = { .reg = EXYNOS5_CLKDIV_TOP0, .shift = 16, .size = 3 },
418 };
419 
420 static struct clksrc_clk exynos5_clk_aclk_200 = {
421 	.clk	= {
422 		.name		= "aclk_200",
423 	},
424 	.sources = &exynos5_clkset_aclk,
425 	.reg_src = { .reg = EXYNOS5_CLKSRC_TOP0, .shift = 12, .size = 1 },
426 	.reg_div = { .reg = EXYNOS5_CLKDIV_TOP0, .shift = 12, .size = 3 },
427 };
428 
429 static struct clksrc_clk exynos5_clk_aclk_66_pre = {
430 	.clk	= {
431 		.name		= "aclk_66_pre",
432 		.parent		= &exynos5_clk_mout_mpll_user.clk,
433 	},
434 	.reg_div = { .reg = EXYNOS5_CLKDIV_TOP1, .shift = 24, .size = 3 },
435 };
436 
437 static struct clksrc_clk exynos5_clk_aclk_66 = {
438 	.clk	= {
439 		.name		= "aclk_66",
440 		.parent		= &exynos5_clk_aclk_66_pre.clk,
441 	},
442 	.reg_div = { .reg = EXYNOS5_CLKDIV_TOP0, .shift = 0, .size = 3 },
443 };
444 
445 static struct clk exynos5_init_clocks_off[] = {
446 	{
447 		.name		= "timers",
448 		.parent		= &exynos5_clk_aclk_66.clk,
449 		.enable		= exynos5_clk_ip_peric_ctrl,
450 		.ctrlbit	= (1 << 24),
451 	}, {
452 		.name		= "rtc",
453 		.parent		= &exynos5_clk_aclk_66.clk,
454 		.enable		= exynos5_clk_ip_peris_ctrl,
455 		.ctrlbit	= (1 << 20),
456 	}, {
457 		.name		= "hsmmc",
458 		.devname	= "exynos4-sdhci.0",
459 		.parent		= &exynos5_clk_aclk_200.clk,
460 		.enable		= exynos5_clk_ip_fsys_ctrl,
461 		.ctrlbit	= (1 << 12),
462 	}, {
463 		.name		= "hsmmc",
464 		.devname	= "exynos4-sdhci.1",
465 		.parent		= &exynos5_clk_aclk_200.clk,
466 		.enable		= exynos5_clk_ip_fsys_ctrl,
467 		.ctrlbit	= (1 << 13),
468 	}, {
469 		.name		= "hsmmc",
470 		.devname	= "exynos4-sdhci.2",
471 		.parent		= &exynos5_clk_aclk_200.clk,
472 		.enable		= exynos5_clk_ip_fsys_ctrl,
473 		.ctrlbit	= (1 << 14),
474 	}, {
475 		.name		= "hsmmc",
476 		.devname	= "exynos4-sdhci.3",
477 		.parent		= &exynos5_clk_aclk_200.clk,
478 		.enable		= exynos5_clk_ip_fsys_ctrl,
479 		.ctrlbit	= (1 << 15),
480 	}, {
481 		.name		= "dwmci",
482 		.parent		= &exynos5_clk_aclk_200.clk,
483 		.enable		= exynos5_clk_ip_fsys_ctrl,
484 		.ctrlbit	= (1 << 16),
485 	}, {
486 		.name		= "sata",
487 		.devname	= "ahci",
488 		.enable		= exynos5_clk_ip_fsys_ctrl,
489 		.ctrlbit	= (1 << 6),
490 	}, {
491 		.name		= "sata_phy",
492 		.enable		= exynos5_clk_ip_fsys_ctrl,
493 		.ctrlbit	= (1 << 24),
494 	}, {
495 		.name		= "sata_phy_i2c",
496 		.enable		= exynos5_clk_ip_fsys_ctrl,
497 		.ctrlbit	= (1 << 25),
498 	}, {
499 		.name		= "mfc",
500 		.devname	= "s5p-mfc",
501 		.enable		= exynos5_clk_ip_mfc_ctrl,
502 		.ctrlbit	= (1 << 0),
503 	}, {
504 		.name		= "hdmi",
505 		.devname	= "exynos4-hdmi",
506 		.enable		= exynos5_clk_ip_disp1_ctrl,
507 		.ctrlbit	= (1 << 6),
508 	}, {
509 		.name		= "mixer",
510 		.devname	= "s5p-mixer",
511 		.enable		= exynos5_clk_ip_disp1_ctrl,
512 		.ctrlbit	= (1 << 5),
513 	}, {
514 		.name		= "jpeg",
515 		.enable		= exynos5_clk_ip_gen_ctrl,
516 		.ctrlbit	= (1 << 2),
517 	}, {
518 		.name		= "dsim0",
519 		.enable		= exynos5_clk_ip_disp1_ctrl,
520 		.ctrlbit	= (1 << 3),
521 	}, {
522 		.name		= "iis",
523 		.devname	= "samsung-i2s.1",
524 		.enable		= exynos5_clk_ip_peric_ctrl,
525 		.ctrlbit	= (1 << 20),
526 	}, {
527 		.name		= "iis",
528 		.devname	= "samsung-i2s.2",
529 		.enable		= exynos5_clk_ip_peric_ctrl,
530 		.ctrlbit	= (1 << 21),
531 	}, {
532 		.name		= "pcm",
533 		.devname	= "samsung-pcm.1",
534 		.enable		= exynos5_clk_ip_peric_ctrl,
535 		.ctrlbit	= (1 << 22),
536 	}, {
537 		.name		= "pcm",
538 		.devname	= "samsung-pcm.2",
539 		.enable		= exynos5_clk_ip_peric_ctrl,
540 		.ctrlbit	= (1 << 23),
541 	}, {
542 		.name		= "spdif",
543 		.devname	= "samsung-spdif",
544 		.enable		= exynos5_clk_ip_peric_ctrl,
545 		.ctrlbit	= (1 << 26),
546 	}, {
547 		.name		= "ac97",
548 		.devname	= "samsung-ac97",
549 		.enable		= exynos5_clk_ip_peric_ctrl,
550 		.ctrlbit	= (1 << 27),
551 	}, {
552 		.name		= "usbhost",
553 		.enable		= exynos5_clk_ip_fsys_ctrl ,
554 		.ctrlbit	= (1 << 18),
555 	}, {
556 		.name		= "usbotg",
557 		.enable		= exynos5_clk_ip_fsys_ctrl,
558 		.ctrlbit	= (1 << 7),
559 	}, {
560 		.name		= "gps",
561 		.enable		= exynos5_clk_ip_gps_ctrl,
562 		.ctrlbit	= ((1 << 3) | (1 << 2) | (1 << 0)),
563 	}, {
564 		.name		= "nfcon",
565 		.enable		= exynos5_clk_ip_fsys_ctrl,
566 		.ctrlbit	= (1 << 22),
567 	}, {
568 		.name		= "iop",
569 		.enable		= exynos5_clk_ip_fsys_ctrl,
570 		.ctrlbit	= ((1 << 30) | (1 << 26) | (1 << 23)),
571 	}, {
572 		.name		= "core_iop",
573 		.enable		= exynos5_clk_ip_core_ctrl,
574 		.ctrlbit	= ((1 << 21) | (1 << 3)),
575 	}, {
576 		.name		= "mcu_iop",
577 		.enable		= exynos5_clk_ip_fsys_ctrl,
578 		.ctrlbit	= (1 << 0),
579 	}, {
580 		.name		= "i2c",
581 		.devname	= "s3c2440-i2c.0",
582 		.parent		= &exynos5_clk_aclk_66.clk,
583 		.enable		= exynos5_clk_ip_peric_ctrl,
584 		.ctrlbit	= (1 << 6),
585 	}, {
586 		.name		= "i2c",
587 		.devname	= "s3c2440-i2c.1",
588 		.parent		= &exynos5_clk_aclk_66.clk,
589 		.enable		= exynos5_clk_ip_peric_ctrl,
590 		.ctrlbit	= (1 << 7),
591 	}, {
592 		.name		= "i2c",
593 		.devname	= "s3c2440-i2c.2",
594 		.parent		= &exynos5_clk_aclk_66.clk,
595 		.enable		= exynos5_clk_ip_peric_ctrl,
596 		.ctrlbit	= (1 << 8),
597 	}, {
598 		.name		= "i2c",
599 		.devname	= "s3c2440-i2c.3",
600 		.parent		= &exynos5_clk_aclk_66.clk,
601 		.enable		= exynos5_clk_ip_peric_ctrl,
602 		.ctrlbit	= (1 << 9),
603 	}, {
604 		.name		= "i2c",
605 		.devname	= "s3c2440-i2c.4",
606 		.parent		= &exynos5_clk_aclk_66.clk,
607 		.enable		= exynos5_clk_ip_peric_ctrl,
608 		.ctrlbit	= (1 << 10),
609 	}, {
610 		.name		= "i2c",
611 		.devname	= "s3c2440-i2c.5",
612 		.parent		= &exynos5_clk_aclk_66.clk,
613 		.enable		= exynos5_clk_ip_peric_ctrl,
614 		.ctrlbit	= (1 << 11),
615 	}, {
616 		.name		= "i2c",
617 		.devname	= "s3c2440-i2c.6",
618 		.parent		= &exynos5_clk_aclk_66.clk,
619 		.enable		= exynos5_clk_ip_peric_ctrl,
620 		.ctrlbit	= (1 << 12),
621 	}, {
622 		.name		= "i2c",
623 		.devname	= "s3c2440-i2c.7",
624 		.parent		= &exynos5_clk_aclk_66.clk,
625 		.enable		= exynos5_clk_ip_peric_ctrl,
626 		.ctrlbit	= (1 << 13),
627 	}, {
628 		.name		= "i2c",
629 		.devname	= "s3c2440-hdmiphy-i2c",
630 		.parent		= &exynos5_clk_aclk_66.clk,
631 		.enable		= exynos5_clk_ip_peric_ctrl,
632 		.ctrlbit	= (1 << 14),
633 	}
634 };
635 
636 static struct clk exynos5_init_clocks_on[] = {
637 	{
638 		.name		= "uart",
639 		.devname	= "s5pv210-uart.0",
640 		.enable		= exynos5_clk_ip_peric_ctrl,
641 		.ctrlbit	= (1 << 0),
642 	}, {
643 		.name		= "uart",
644 		.devname	= "s5pv210-uart.1",
645 		.enable		= exynos5_clk_ip_peric_ctrl,
646 		.ctrlbit	= (1 << 1),
647 	}, {
648 		.name		= "uart",
649 		.devname	= "s5pv210-uart.2",
650 		.enable		= exynos5_clk_ip_peric_ctrl,
651 		.ctrlbit	= (1 << 2),
652 	}, {
653 		.name		= "uart",
654 		.devname	= "s5pv210-uart.3",
655 		.enable		= exynos5_clk_ip_peric_ctrl,
656 		.ctrlbit	= (1 << 3),
657 	}, {
658 		.name		= "uart",
659 		.devname	= "s5pv210-uart.4",
660 		.enable		= exynos5_clk_ip_peric_ctrl,
661 		.ctrlbit	= (1 << 4),
662 	}, {
663 		.name		= "uart",
664 		.devname	= "s5pv210-uart.5",
665 		.enable		= exynos5_clk_ip_peric_ctrl,
666 		.ctrlbit	= (1 << 5),
667 	}
668 };
669 
670 static struct clk exynos5_clk_pdma0 = {
671 	.name		= "dma",
672 	.devname	= "dma-pl330.0",
673 	.enable		= exynos5_clk_ip_fsys_ctrl,
674 	.ctrlbit	= (1 << 1),
675 };
676 
677 static struct clk exynos5_clk_pdma1 = {
678 	.name		= "dma",
679 	.devname	= "dma-pl330.1",
680 	.enable		= exynos5_clk_ip_fsys_ctrl,
681 	.ctrlbit	= (1 << 2),
682 };
683 
684 static struct clk exynos5_clk_mdma1 = {
685 	.name		= "dma",
686 	.devname	= "dma-pl330.2",
687 	.enable		= exynos5_clk_ip_gen_ctrl,
688 	.ctrlbit	= (1 << 4),
689 };
690 
691 struct clk *exynos5_clkset_group_list[] = {
692 	[0] = &clk_ext_xtal_mux,
693 	[1] = NULL,
694 	[2] = &exynos5_clk_sclk_hdmi24m,
695 	[3] = &exynos5_clk_sclk_dptxphy,
696 	[4] = &exynos5_clk_sclk_usbphy,
697 	[5] = &exynos5_clk_sclk_hdmiphy,
698 	[6] = &exynos5_clk_mout_mpll_user.clk,
699 	[7] = &exynos5_clk_mout_epll.clk,
700 	[8] = &exynos5_clk_sclk_vpll.clk,
701 	[9] = &exynos5_clk_mout_cpll.clk,
702 };
703 
704 struct clksrc_sources exynos5_clkset_group = {
705 	.sources	= exynos5_clkset_group_list,
706 	.nr_sources	= ARRAY_SIZE(exynos5_clkset_group_list),
707 };
708 
709 /* Possible clock sources for aclk_266_gscl_sub Mux */
710 static struct clk *clk_src_gscl_266_list[] = {
711 	[0] = &clk_ext_xtal_mux,
712 	[1] = &exynos5_clk_aclk_266.clk,
713 };
714 
715 static struct clksrc_sources clk_src_gscl_266 = {
716 	.sources	= clk_src_gscl_266_list,
717 	.nr_sources	= ARRAY_SIZE(clk_src_gscl_266_list),
718 };
719 
720 static struct clksrc_clk exynos5_clk_dout_mmc0 = {
721 	.clk		= {
722 		.name		= "dout_mmc0",
723 	},
724 	.sources = &exynos5_clkset_group,
725 	.reg_src = { .reg = EXYNOS5_CLKSRC_FSYS, .shift = 0, .size = 4 },
726 	.reg_div = { .reg = EXYNOS5_CLKDIV_FSYS1, .shift = 0, .size = 4 },
727 };
728 
729 static struct clksrc_clk exynos5_clk_dout_mmc1 = {
730 	.clk		= {
731 		.name		= "dout_mmc1",
732 	},
733 	.sources = &exynos5_clkset_group,
734 	.reg_src = { .reg = EXYNOS5_CLKSRC_FSYS, .shift = 4, .size = 4 },
735 	.reg_div = { .reg = EXYNOS5_CLKDIV_FSYS1, .shift = 16, .size = 4 },
736 };
737 
738 static struct clksrc_clk exynos5_clk_dout_mmc2 = {
739 	.clk		= {
740 		.name		= "dout_mmc2",
741 	},
742 	.sources = &exynos5_clkset_group,
743 	.reg_src = { .reg = EXYNOS5_CLKSRC_FSYS, .shift = 8, .size = 4 },
744 	.reg_div = { .reg = EXYNOS5_CLKDIV_FSYS2, .shift = 0, .size = 4 },
745 };
746 
747 static struct clksrc_clk exynos5_clk_dout_mmc3 = {
748 	.clk		= {
749 		.name		= "dout_mmc3",
750 	},
751 	.sources = &exynos5_clkset_group,
752 	.reg_src = { .reg = EXYNOS5_CLKSRC_FSYS, .shift = 12, .size = 4 },
753 	.reg_div = { .reg = EXYNOS5_CLKDIV_FSYS2, .shift = 16, .size = 4 },
754 };
755 
756 static struct clksrc_clk exynos5_clk_dout_mmc4 = {
757 	.clk		= {
758 		.name		= "dout_mmc4",
759 	},
760 	.sources = &exynos5_clkset_group,
761 	.reg_src = { .reg = EXYNOS5_CLKSRC_FSYS, .shift = 16, .size = 4 },
762 	.reg_div = { .reg = EXYNOS5_CLKDIV_FSYS3, .shift = 0, .size = 4 },
763 };
764 
765 static struct clksrc_clk exynos5_clk_sclk_uart0 = {
766 	.clk	= {
767 		.name		= "uclk1",
768 		.devname	= "exynos4210-uart.0",
769 		.enable		= exynos5_clksrc_mask_peric0_ctrl,
770 		.ctrlbit	= (1 << 0),
771 	},
772 	.sources = &exynos5_clkset_group,
773 	.reg_src = { .reg = EXYNOS5_CLKSRC_PERIC0, .shift = 0, .size = 4 },
774 	.reg_div = { .reg = EXYNOS5_CLKDIV_PERIC0, .shift = 0, .size = 4 },
775 };
776 
777 static struct clksrc_clk exynos5_clk_sclk_uart1 = {
778 	.clk	= {
779 		.name		= "uclk1",
780 		.devname	= "exynos4210-uart.1",
781 		.enable		= exynos5_clksrc_mask_peric0_ctrl,
782 		.ctrlbit	= (1 << 4),
783 	},
784 	.sources = &exynos5_clkset_group,
785 	.reg_src = { .reg = EXYNOS5_CLKSRC_PERIC0, .shift = 4, .size = 4 },
786 	.reg_div = { .reg = EXYNOS5_CLKDIV_PERIC0, .shift = 4, .size = 4 },
787 };
788 
789 static struct clksrc_clk exynos5_clk_sclk_uart2 = {
790 	.clk	= {
791 		.name		= "uclk1",
792 		.devname	= "exynos4210-uart.2",
793 		.enable		= exynos5_clksrc_mask_peric0_ctrl,
794 		.ctrlbit	= (1 << 8),
795 	},
796 	.sources = &exynos5_clkset_group,
797 	.reg_src = { .reg = EXYNOS5_CLKSRC_PERIC0, .shift = 8, .size = 4 },
798 	.reg_div = { .reg = EXYNOS5_CLKDIV_PERIC0, .shift = 8, .size = 4 },
799 };
800 
801 static struct clksrc_clk exynos5_clk_sclk_uart3 = {
802 	.clk	= {
803 		.name		= "uclk1",
804 		.devname	= "exynos4210-uart.3",
805 		.enable		= exynos5_clksrc_mask_peric0_ctrl,
806 		.ctrlbit	= (1 << 12),
807 	},
808 	.sources = &exynos5_clkset_group,
809 	.reg_src = { .reg = EXYNOS5_CLKSRC_PERIC0, .shift = 12, .size = 4 },
810 	.reg_div = { .reg = EXYNOS5_CLKDIV_PERIC0, .shift = 12, .size = 4 },
811 };
812 
813 static struct clksrc_clk exynos5_clk_sclk_mmc0 = {
814 	.clk	= {
815 		.name		= "sclk_mmc",
816 		.devname	= "exynos4-sdhci.0",
817 		.parent		= &exynos5_clk_dout_mmc0.clk,
818 		.enable		= exynos5_clksrc_mask_fsys_ctrl,
819 		.ctrlbit	= (1 << 0),
820 	},
821 	.reg_div = { .reg = EXYNOS5_CLKDIV_FSYS1, .shift = 8, .size = 8 },
822 };
823 
824 static struct clksrc_clk exynos5_clk_sclk_mmc1 = {
825 	.clk	= {
826 		.name		= "sclk_mmc",
827 		.devname	= "exynos4-sdhci.1",
828 		.parent		= &exynos5_clk_dout_mmc1.clk,
829 		.enable		= exynos5_clksrc_mask_fsys_ctrl,
830 		.ctrlbit	= (1 << 4),
831 	},
832 	.reg_div = { .reg = EXYNOS5_CLKDIV_FSYS1, .shift = 24, .size = 8 },
833 };
834 
835 static struct clksrc_clk exynos5_clk_sclk_mmc2 = {
836 	.clk	= {
837 		.name		= "sclk_mmc",
838 		.devname	= "exynos4-sdhci.2",
839 		.parent		= &exynos5_clk_dout_mmc2.clk,
840 		.enable		= exynos5_clksrc_mask_fsys_ctrl,
841 		.ctrlbit	= (1 << 8),
842 	},
843 	.reg_div = { .reg = EXYNOS5_CLKDIV_FSYS2, .shift = 8, .size = 8 },
844 };
845 
846 static struct clksrc_clk exynos5_clk_sclk_mmc3 = {
847 	.clk	= {
848 		.name		= "sclk_mmc",
849 		.devname	= "exynos4-sdhci.3",
850 		.parent		= &exynos5_clk_dout_mmc3.clk,
851 		.enable		= exynos5_clksrc_mask_fsys_ctrl,
852 		.ctrlbit	= (1 << 12),
853 	},
854 	.reg_div = { .reg = EXYNOS5_CLKDIV_FSYS2, .shift = 24, .size = 8 },
855 };
856 
857 static struct clksrc_clk exynos5_clksrcs[] = {
858 	{
859 		.clk	= {
860 			.name		= "sclk_dwmci",
861 			.parent		= &exynos5_clk_dout_mmc4.clk,
862 			.enable		= exynos5_clksrc_mask_fsys_ctrl,
863 			.ctrlbit	= (1 << 16),
864 		},
865 		.reg_div = { .reg = EXYNOS5_CLKDIV_FSYS3, .shift = 8, .size = 8 },
866 	}, {
867 		.clk	= {
868 			.name		= "sclk_fimd",
869 			.devname	= "s3cfb.1",
870 			.enable		= exynos5_clksrc_mask_disp1_0_ctrl,
871 			.ctrlbit	= (1 << 0),
872 		},
873 		.sources = &exynos5_clkset_group,
874 		.reg_src = { .reg = EXYNOS5_CLKSRC_DISP1_0, .shift = 0, .size = 4 },
875 		.reg_div = { .reg = EXYNOS5_CLKDIV_DISP1_0, .shift = 0, .size = 4 },
876 	}, {
877 		.clk	= {
878 			.name		= "aclk_266_gscl",
879 		},
880 		.sources = &clk_src_gscl_266,
881 		.reg_src = { .reg = EXYNOS5_CLKSRC_TOP3, .shift = 8, .size = 1 },
882 	}, {
883 		.clk	= {
884 			.name		= "sclk_g3d",
885 			.devname	= "mali-t604.0",
886 			.enable		= exynos5_clk_block_ctrl,
887 			.ctrlbit	= (1 << 1),
888 		},
889 		.sources = &exynos5_clkset_aclk,
890 		.reg_src = { .reg = EXYNOS5_CLKSRC_TOP0, .shift = 20, .size = 1 },
891 		.reg_div = { .reg = EXYNOS5_CLKDIV_TOP0, .shift = 24, .size = 3 },
892 	}, {
893 		.clk	= {
894 			.name		= "sclk_gscl_wrap",
895 			.devname	= "s5p-mipi-csis.0",
896 			.enable		= exynos5_clksrc_mask_gscl_ctrl,
897 			.ctrlbit	= (1 << 24),
898 		},
899 		.sources = &exynos5_clkset_group,
900 		.reg_src = { .reg = EXYNOS5_CLKSRC_GSCL, .shift = 24, .size = 4 },
901 		.reg_div = { .reg = EXYNOS5_CLKDIV_GSCL, .shift = 24, .size = 4 },
902 	}, {
903 		.clk	= {
904 			.name		= "sclk_gscl_wrap",
905 			.devname	= "s5p-mipi-csis.1",
906 			.enable		= exynos5_clksrc_mask_gscl_ctrl,
907 			.ctrlbit	= (1 << 28),
908 		},
909 		.sources = &exynos5_clkset_group,
910 		.reg_src = { .reg = EXYNOS5_CLKSRC_GSCL, .shift = 28, .size = 4 },
911 		.reg_div = { .reg = EXYNOS5_CLKDIV_GSCL, .shift = 28, .size = 4 },
912 	}, {
913 		.clk	= {
914 			.name		= "sclk_cam0",
915 			.enable		= exynos5_clksrc_mask_gscl_ctrl,
916 			.ctrlbit	= (1 << 16),
917 		},
918 		.sources = &exynos5_clkset_group,
919 		.reg_src = { .reg = EXYNOS5_CLKSRC_GSCL, .shift = 16, .size = 4 },
920 		.reg_div = { .reg = EXYNOS5_CLKDIV_GSCL, .shift = 16, .size = 4 },
921 	}, {
922 		.clk	= {
923 			.name		= "sclk_cam1",
924 			.enable		= exynos5_clksrc_mask_gscl_ctrl,
925 			.ctrlbit	= (1 << 20),
926 		},
927 		.sources = &exynos5_clkset_group,
928 		.reg_src = { .reg = EXYNOS5_CLKSRC_GSCL, .shift = 20, .size = 4 },
929 		.reg_div = { .reg = EXYNOS5_CLKDIV_GSCL, .shift = 20, .size = 4 },
930 	}, {
931 		.clk	= {
932 			.name		= "sclk_jpeg",
933 			.parent		= &exynos5_clk_mout_cpll.clk,
934 		},
935 		.reg_div = { .reg = EXYNOS5_CLKDIV_GEN, .shift = 4, .size = 3 },
936 	},
937 };
938 
939 /* Clock initialization code */
940 static struct clksrc_clk *exynos5_sysclks[] = {
941 	&exynos5_clk_mout_apll,
942 	&exynos5_clk_sclk_apll,
943 	&exynos5_clk_mout_bpll,
944 	&exynos5_clk_mout_bpll_user,
945 	&exynos5_clk_mout_cpll,
946 	&exynos5_clk_mout_epll,
947 	&exynos5_clk_mout_mpll,
948 	&exynos5_clk_mout_mpll_user,
949 	&exynos5_clk_vpllsrc,
950 	&exynos5_clk_sclk_vpll,
951 	&exynos5_clk_mout_cpu,
952 	&exynos5_clk_dout_armclk,
953 	&exynos5_clk_dout_arm2clk,
954 	&exynos5_clk_cdrex,
955 	&exynos5_clk_aclk_400,
956 	&exynos5_clk_aclk_333,
957 	&exynos5_clk_aclk_266,
958 	&exynos5_clk_aclk_200,
959 	&exynos5_clk_aclk_166,
960 	&exynos5_clk_aclk_66_pre,
961 	&exynos5_clk_aclk_66,
962 	&exynos5_clk_dout_mmc0,
963 	&exynos5_clk_dout_mmc1,
964 	&exynos5_clk_dout_mmc2,
965 	&exynos5_clk_dout_mmc3,
966 	&exynos5_clk_dout_mmc4,
967 	&exynos5_clk_aclk_acp,
968 	&exynos5_clk_pclk_acp,
969 };
970 
971 static struct clk *exynos5_clk_cdev[] = {
972 	&exynos5_clk_pdma0,
973 	&exynos5_clk_pdma1,
974 	&exynos5_clk_mdma1,
975 };
976 
977 static struct clksrc_clk *exynos5_clksrc_cdev[] = {
978 	&exynos5_clk_sclk_uart0,
979 	&exynos5_clk_sclk_uart1,
980 	&exynos5_clk_sclk_uart2,
981 	&exynos5_clk_sclk_uart3,
982 	&exynos5_clk_sclk_mmc0,
983 	&exynos5_clk_sclk_mmc1,
984 	&exynos5_clk_sclk_mmc2,
985 	&exynos5_clk_sclk_mmc3,
986 };
987 
988 static struct clk_lookup exynos5_clk_lookup[] = {
989 	CLKDEV_INIT("exynos4210-uart.0", "clk_uart_baud0", &exynos5_clk_sclk_uart0.clk),
990 	CLKDEV_INIT("exynos4210-uart.1", "clk_uart_baud0", &exynos5_clk_sclk_uart1.clk),
991 	CLKDEV_INIT("exynos4210-uart.2", "clk_uart_baud0", &exynos5_clk_sclk_uart2.clk),
992 	CLKDEV_INIT("exynos4210-uart.3", "clk_uart_baud0", &exynos5_clk_sclk_uart3.clk),
993 	CLKDEV_INIT("exynos4-sdhci.0", "mmc_busclk.2", &exynos5_clk_sclk_mmc0.clk),
994 	CLKDEV_INIT("exynos4-sdhci.1", "mmc_busclk.2", &exynos5_clk_sclk_mmc1.clk),
995 	CLKDEV_INIT("exynos4-sdhci.2", "mmc_busclk.2", &exynos5_clk_sclk_mmc2.clk),
996 	CLKDEV_INIT("exynos4-sdhci.3", "mmc_busclk.2", &exynos5_clk_sclk_mmc3.clk),
997 	CLKDEV_INIT("dma-pl330.0", "apb_pclk", &exynos5_clk_pdma0),
998 	CLKDEV_INIT("dma-pl330.1", "apb_pclk", &exynos5_clk_pdma1),
999 	CLKDEV_INIT("dma-pl330.2", "apb_pclk", &exynos5_clk_mdma1),
1000 };
1001 
exynos5_epll_get_rate(struct clk * clk)1002 static unsigned long exynos5_epll_get_rate(struct clk *clk)
1003 {
1004 	return clk->rate;
1005 }
1006 
1007 static struct clk *exynos5_clks[] __initdata = {
1008 	&exynos5_clk_sclk_hdmi27m,
1009 	&exynos5_clk_sclk_hdmiphy,
1010 	&clk_fout_bpll,
1011 	&clk_fout_cpll,
1012 	&exynos5_clk_armclk,
1013 };
1014 
1015 static u32 epll_div[][6] = {
1016 	{ 192000000, 0, 48, 3, 1, 0 },
1017 	{ 180000000, 0, 45, 3, 1, 0 },
1018 	{  73728000, 1, 73, 3, 3, 47710 },
1019 	{  67737600, 1, 90, 4, 3, 20762 },
1020 	{  49152000, 0, 49, 3, 3, 9961 },
1021 	{  45158400, 0, 45, 3, 3, 10381 },
1022 	{ 180633600, 0, 45, 3, 1, 10381 },
1023 };
1024 
exynos5_epll_set_rate(struct clk * clk,unsigned long rate)1025 static int exynos5_epll_set_rate(struct clk *clk, unsigned long rate)
1026 {
1027 	unsigned int epll_con, epll_con_k;
1028 	unsigned int i;
1029 	unsigned int tmp;
1030 	unsigned int epll_rate;
1031 	unsigned int locktime;
1032 	unsigned int lockcnt;
1033 
1034 	/* Return if nothing changed */
1035 	if (clk->rate == rate)
1036 		return 0;
1037 
1038 	if (clk->parent)
1039 		epll_rate = clk_get_rate(clk->parent);
1040 	else
1041 		epll_rate = clk_ext_xtal_mux.rate;
1042 
1043 	if (epll_rate != 24000000) {
1044 		pr_err("Invalid Clock : recommended clock is 24MHz.\n");
1045 		return -EINVAL;
1046 	}
1047 
1048 	epll_con = __raw_readl(EXYNOS5_EPLL_CON0);
1049 	epll_con &= ~(0x1 << 27 | \
1050 			PLL46XX_MDIV_MASK << PLL46XX_MDIV_SHIFT |   \
1051 			PLL46XX_PDIV_MASK << PLL46XX_PDIV_SHIFT | \
1052 			PLL46XX_SDIV_MASK << PLL46XX_SDIV_SHIFT);
1053 
1054 	for (i = 0; i < ARRAY_SIZE(epll_div); i++) {
1055 		if (epll_div[i][0] == rate) {
1056 			epll_con_k = epll_div[i][5] << 0;
1057 			epll_con |= epll_div[i][1] << 27;
1058 			epll_con |= epll_div[i][2] << PLL46XX_MDIV_SHIFT;
1059 			epll_con |= epll_div[i][3] << PLL46XX_PDIV_SHIFT;
1060 			epll_con |= epll_div[i][4] << PLL46XX_SDIV_SHIFT;
1061 			break;
1062 		}
1063 	}
1064 
1065 	if (i == ARRAY_SIZE(epll_div)) {
1066 		printk(KERN_ERR "%s: Invalid Clock EPLL Frequency\n",
1067 				__func__);
1068 		return -EINVAL;
1069 	}
1070 
1071 	epll_rate /= 1000000;
1072 
1073 	/* 3000 max_cycls : specification data */
1074 	locktime = 3000 / epll_rate * epll_div[i][3];
1075 	lockcnt = locktime * 10000 / (10000 / epll_rate);
1076 
1077 	__raw_writel(lockcnt, EXYNOS5_EPLL_LOCK);
1078 
1079 	__raw_writel(epll_con, EXYNOS5_EPLL_CON0);
1080 	__raw_writel(epll_con_k, EXYNOS5_EPLL_CON1);
1081 
1082 	do {
1083 		tmp = __raw_readl(EXYNOS5_EPLL_CON0);
1084 	} while (!(tmp & 0x1 << EXYNOS5_EPLLCON0_LOCKED_SHIFT));
1085 
1086 	clk->rate = rate;
1087 
1088 	return 0;
1089 }
1090 
1091 static struct clk_ops exynos5_epll_ops = {
1092 	.get_rate = exynos5_epll_get_rate,
1093 	.set_rate = exynos5_epll_set_rate,
1094 };
1095 
1096 static int xtal_rate;
1097 
exynos5_fout_apll_get_rate(struct clk * clk)1098 static unsigned long exynos5_fout_apll_get_rate(struct clk *clk)
1099 {
1100 	return s5p_get_pll35xx(xtal_rate, __raw_readl(EXYNOS5_APLL_CON0));
1101 }
1102 
1103 static struct clk_ops exynos5_fout_apll_ops = {
1104 	.get_rate = exynos5_fout_apll_get_rate,
1105 };
1106 
1107 #ifdef CONFIG_PM
exynos5_clock_suspend(void)1108 static int exynos5_clock_suspend(void)
1109 {
1110 	s3c_pm_do_save(exynos5_clock_save, ARRAY_SIZE(exynos5_clock_save));
1111 
1112 	return 0;
1113 }
1114 
exynos5_clock_resume(void)1115 static void exynos5_clock_resume(void)
1116 {
1117 	s3c_pm_do_restore_core(exynos5_clock_save, ARRAY_SIZE(exynos5_clock_save));
1118 }
1119 #else
1120 #define exynos5_clock_suspend NULL
1121 #define exynos5_clock_resume NULL
1122 #endif
1123 
1124 struct syscore_ops exynos5_clock_syscore_ops = {
1125 	.suspend	= exynos5_clock_suspend,
1126 	.resume		= exynos5_clock_resume,
1127 };
1128 
exynos5_setup_clocks(void)1129 void __init_or_cpufreq exynos5_setup_clocks(void)
1130 {
1131 	struct clk *xtal_clk;
1132 	unsigned long apll;
1133 	unsigned long bpll;
1134 	unsigned long cpll;
1135 	unsigned long mpll;
1136 	unsigned long epll;
1137 	unsigned long vpll;
1138 	unsigned long vpllsrc;
1139 	unsigned long xtal;
1140 	unsigned long armclk;
1141 	unsigned long mout_cdrex;
1142 	unsigned long aclk_400;
1143 	unsigned long aclk_333;
1144 	unsigned long aclk_266;
1145 	unsigned long aclk_200;
1146 	unsigned long aclk_166;
1147 	unsigned long aclk_66;
1148 	unsigned int ptr;
1149 
1150 	printk(KERN_DEBUG "%s: registering clocks\n", __func__);
1151 
1152 	xtal_clk = clk_get(NULL, "xtal");
1153 	BUG_ON(IS_ERR(xtal_clk));
1154 
1155 	xtal = clk_get_rate(xtal_clk);
1156 
1157 	xtal_rate = xtal;
1158 
1159 	clk_put(xtal_clk);
1160 
1161 	printk(KERN_DEBUG "%s: xtal is %ld\n", __func__, xtal);
1162 
1163 	apll = s5p_get_pll35xx(xtal, __raw_readl(EXYNOS5_APLL_CON0));
1164 	bpll = s5p_get_pll35xx(xtal, __raw_readl(EXYNOS5_BPLL_CON0));
1165 	cpll = s5p_get_pll35xx(xtal, __raw_readl(EXYNOS5_CPLL_CON0));
1166 	mpll = s5p_get_pll35xx(xtal, __raw_readl(EXYNOS5_MPLL_CON0));
1167 	epll = s5p_get_pll36xx(xtal, __raw_readl(EXYNOS5_EPLL_CON0),
1168 			__raw_readl(EXYNOS5_EPLL_CON1));
1169 
1170 	vpllsrc = clk_get_rate(&exynos5_clk_vpllsrc.clk);
1171 	vpll = s5p_get_pll36xx(vpllsrc, __raw_readl(EXYNOS5_VPLL_CON0),
1172 			__raw_readl(EXYNOS5_VPLL_CON1));
1173 
1174 	clk_fout_apll.ops = &exynos5_fout_apll_ops;
1175 	clk_fout_bpll.rate = bpll;
1176 	clk_fout_cpll.rate = cpll;
1177 	clk_fout_mpll.rate = mpll;
1178 	clk_fout_epll.rate = epll;
1179 	clk_fout_vpll.rate = vpll;
1180 
1181 	printk(KERN_INFO "EXYNOS5: PLL settings, A=%ld, B=%ld, C=%ld\n"
1182 			"M=%ld, E=%ld V=%ld",
1183 			apll, bpll, cpll, mpll, epll, vpll);
1184 
1185 	armclk = clk_get_rate(&exynos5_clk_armclk);
1186 	mout_cdrex = clk_get_rate(&exynos5_clk_cdrex.clk);
1187 
1188 	aclk_400 = clk_get_rate(&exynos5_clk_aclk_400.clk);
1189 	aclk_333 = clk_get_rate(&exynos5_clk_aclk_333.clk);
1190 	aclk_266 = clk_get_rate(&exynos5_clk_aclk_266.clk);
1191 	aclk_200 = clk_get_rate(&exynos5_clk_aclk_200.clk);
1192 	aclk_166 = clk_get_rate(&exynos5_clk_aclk_166.clk);
1193 	aclk_66 = clk_get_rate(&exynos5_clk_aclk_66.clk);
1194 
1195 	printk(KERN_INFO "EXYNOS5: ARMCLK=%ld, CDREX=%ld, ACLK400=%ld\n"
1196 			"ACLK333=%ld, ACLK266=%ld, ACLK200=%ld\n"
1197 			"ACLK166=%ld, ACLK66=%ld\n",
1198 			armclk, mout_cdrex, aclk_400,
1199 			aclk_333, aclk_266, aclk_200,
1200 			aclk_166, aclk_66);
1201 
1202 
1203 	clk_fout_epll.ops = &exynos5_epll_ops;
1204 
1205 	if (clk_set_parent(&exynos5_clk_mout_epll.clk, &clk_fout_epll))
1206 		printk(KERN_ERR "Unable to set parent %s of clock %s.\n",
1207 				clk_fout_epll.name, exynos5_clk_mout_epll.clk.name);
1208 
1209 	clk_set_rate(&exynos5_clk_sclk_apll.clk, 100000000);
1210 	clk_set_rate(&exynos5_clk_aclk_266.clk, 300000000);
1211 
1212 	clk_set_rate(&exynos5_clk_aclk_acp.clk, 267000000);
1213 	clk_set_rate(&exynos5_clk_pclk_acp.clk, 134000000);
1214 
1215 	for (ptr = 0; ptr < ARRAY_SIZE(exynos5_clksrcs); ptr++)
1216 		s3c_set_clksrc(&exynos5_clksrcs[ptr], true);
1217 }
1218 
exynos5_register_clocks(void)1219 void __init exynos5_register_clocks(void)
1220 {
1221 	int ptr;
1222 
1223 	s3c24xx_register_clocks(exynos5_clks, ARRAY_SIZE(exynos5_clks));
1224 
1225 	for (ptr = 0; ptr < ARRAY_SIZE(exynos5_sysclks); ptr++)
1226 		s3c_register_clksrc(exynos5_sysclks[ptr], 1);
1227 
1228 	for (ptr = 0; ptr < ARRAY_SIZE(exynos5_sclk_tv); ptr++)
1229 		s3c_register_clksrc(exynos5_sclk_tv[ptr], 1);
1230 
1231 	for (ptr = 0; ptr < ARRAY_SIZE(exynos5_clksrc_cdev); ptr++)
1232 		s3c_register_clksrc(exynos5_clksrc_cdev[ptr], 1);
1233 
1234 	s3c_register_clksrc(exynos5_clksrcs, ARRAY_SIZE(exynos5_clksrcs));
1235 	s3c_register_clocks(exynos5_init_clocks_on, ARRAY_SIZE(exynos5_init_clocks_on));
1236 
1237 	s3c24xx_register_clocks(exynos5_clk_cdev, ARRAY_SIZE(exynos5_clk_cdev));
1238 	for (ptr = 0; ptr < ARRAY_SIZE(exynos5_clk_cdev); ptr++)
1239 		s3c_disable_clocks(exynos5_clk_cdev[ptr], 1);
1240 
1241 	s3c_register_clocks(exynos5_init_clocks_off, ARRAY_SIZE(exynos5_init_clocks_off));
1242 	s3c_disable_clocks(exynos5_init_clocks_off, ARRAY_SIZE(exynos5_init_clocks_off));
1243 	clkdev_add_table(exynos5_clk_lookup, ARRAY_SIZE(exynos5_clk_lookup));
1244 
1245 	register_syscore_ops(&exynos5_clock_syscore_ops);
1246 	s3c_pwmclk_init();
1247 }
1248