1 /* linux/arch/arm/mach-s5pv210/clock.c
2  *
3  * Copyright (c) 2010 Samsung Electronics Co., Ltd.
4  *		http://www.samsung.com/
5  *
6  * S5PV210 - Clock support
7  *
8  * This program is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License version 2 as
10  * published by the Free Software Foundation.
11 */
12 
13 #include <linux/init.h>
14 #include <linux/module.h>
15 #include <linux/kernel.h>
16 #include <linux/list.h>
17 #include <linux/errno.h>
18 #include <linux/err.h>
19 #include <linux/clk.h>
20 #include <linux/device.h>
21 #include <linux/io.h>
22 
23 #include <mach/map.h>
24 
25 #include <plat/cpu-freq.h>
26 #include <mach/regs-clock.h>
27 #include <plat/clock.h>
28 #include <plat/cpu.h>
29 #include <plat/pll.h>
30 #include <plat/s5p-clock.h>
31 #include <plat/clock-clksrc.h>
32 
33 #include "common.h"
34 
35 static unsigned long xtal;
36 
37 static struct clksrc_clk clk_mout_apll = {
38 	.clk	= {
39 		.name		= "mout_apll",
40 	},
41 	.sources	= &clk_src_apll,
42 	.reg_src	= { .reg = S5P_CLK_SRC0, .shift = 0, .size = 1 },
43 };
44 
45 static struct clksrc_clk clk_mout_epll = {
46 	.clk	= {
47 		.name		= "mout_epll",
48 	},
49 	.sources	= &clk_src_epll,
50 	.reg_src	= { .reg = S5P_CLK_SRC0, .shift = 8, .size = 1 },
51 };
52 
53 static struct clksrc_clk clk_mout_mpll = {
54 	.clk = {
55 		.name		= "mout_mpll",
56 	},
57 	.sources	= &clk_src_mpll,
58 	.reg_src	= { .reg = S5P_CLK_SRC0, .shift = 4, .size = 1 },
59 };
60 
61 static struct clk *clkset_armclk_list[] = {
62 	[0] = &clk_mout_apll.clk,
63 	[1] = &clk_mout_mpll.clk,
64 };
65 
66 static struct clksrc_sources clkset_armclk = {
67 	.sources	= clkset_armclk_list,
68 	.nr_sources	= ARRAY_SIZE(clkset_armclk_list),
69 };
70 
71 static struct clksrc_clk clk_armclk = {
72 	.clk	= {
73 		.name		= "armclk",
74 	},
75 	.sources	= &clkset_armclk,
76 	.reg_src	= { .reg = S5P_CLK_SRC0, .shift = 16, .size = 1 },
77 	.reg_div	= { .reg = S5P_CLK_DIV0, .shift = 0, .size = 3 },
78 };
79 
80 static struct clksrc_clk clk_hclk_msys = {
81 	.clk	= {
82 		.name		= "hclk_msys",
83 		.parent		= &clk_armclk.clk,
84 	},
85 	.reg_div	= { .reg = S5P_CLK_DIV0, .shift = 8, .size = 3 },
86 };
87 
88 static struct clksrc_clk clk_pclk_msys = {
89 	.clk	= {
90 		.name		= "pclk_msys",
91 		.parent		= &clk_hclk_msys.clk,
92 	},
93 	.reg_div        = { .reg = S5P_CLK_DIV0, .shift = 12, .size = 3 },
94 };
95 
96 static struct clksrc_clk clk_sclk_a2m = {
97 	.clk	= {
98 		.name		= "sclk_a2m",
99 		.parent		= &clk_mout_apll.clk,
100 	},
101 	.reg_div	= { .reg = S5P_CLK_DIV0, .shift = 4, .size = 3 },
102 };
103 
104 static struct clk *clkset_hclk_sys_list[] = {
105 	[0] = &clk_mout_mpll.clk,
106 	[1] = &clk_sclk_a2m.clk,
107 };
108 
109 static struct clksrc_sources clkset_hclk_sys = {
110 	.sources	= clkset_hclk_sys_list,
111 	.nr_sources	= ARRAY_SIZE(clkset_hclk_sys_list),
112 };
113 
114 static struct clksrc_clk clk_hclk_dsys = {
115 	.clk	= {
116 		.name	= "hclk_dsys",
117 	},
118 	.sources	= &clkset_hclk_sys,
119 	.reg_src        = { .reg = S5P_CLK_SRC0, .shift = 20, .size = 1 },
120 	.reg_div        = { .reg = S5P_CLK_DIV0, .shift = 16, .size = 4 },
121 };
122 
123 static struct clksrc_clk clk_pclk_dsys = {
124 	.clk	= {
125 		.name	= "pclk_dsys",
126 		.parent	= &clk_hclk_dsys.clk,
127 	},
128 	.reg_div = { .reg = S5P_CLK_DIV0, .shift = 20, .size = 3 },
129 };
130 
131 static struct clksrc_clk clk_hclk_psys = {
132 	.clk	= {
133 		.name	= "hclk_psys",
134 	},
135 	.sources	= &clkset_hclk_sys,
136 	.reg_src        = { .reg = S5P_CLK_SRC0, .shift = 24, .size = 1 },
137 	.reg_div        = { .reg = S5P_CLK_DIV0, .shift = 24, .size = 4 },
138 };
139 
140 static struct clksrc_clk clk_pclk_psys = {
141 	.clk	= {
142 		.name	= "pclk_psys",
143 		.parent	= &clk_hclk_psys.clk,
144 	},
145 	.reg_div        = { .reg = S5P_CLK_DIV0, .shift = 28, .size = 3 },
146 };
147 
s5pv210_clk_ip0_ctrl(struct clk * clk,int enable)148 static int s5pv210_clk_ip0_ctrl(struct clk *clk, int enable)
149 {
150 	return s5p_gatectrl(S5P_CLKGATE_IP0, clk, enable);
151 }
152 
s5pv210_clk_ip1_ctrl(struct clk * clk,int enable)153 static int s5pv210_clk_ip1_ctrl(struct clk *clk, int enable)
154 {
155 	return s5p_gatectrl(S5P_CLKGATE_IP1, clk, enable);
156 }
157 
s5pv210_clk_ip2_ctrl(struct clk * clk,int enable)158 static int s5pv210_clk_ip2_ctrl(struct clk *clk, int enable)
159 {
160 	return s5p_gatectrl(S5P_CLKGATE_IP2, clk, enable);
161 }
162 
s5pv210_clk_ip3_ctrl(struct clk * clk,int enable)163 static int s5pv210_clk_ip3_ctrl(struct clk *clk, int enable)
164 {
165 	return s5p_gatectrl(S5P_CLKGATE_IP3, clk, enable);
166 }
167 
s5pv210_clk_mask0_ctrl(struct clk * clk,int enable)168 static int s5pv210_clk_mask0_ctrl(struct clk *clk, int enable)
169 {
170 	return s5p_gatectrl(S5P_CLK_SRC_MASK0, clk, enable);
171 }
172 
s5pv210_clk_mask1_ctrl(struct clk * clk,int enable)173 static int s5pv210_clk_mask1_ctrl(struct clk *clk, int enable)
174 {
175 	return s5p_gatectrl(S5P_CLK_SRC_MASK1, clk, enable);
176 }
177 
s5pv210_clk_hdmiphy_ctrl(struct clk * clk,int enable)178 static int s5pv210_clk_hdmiphy_ctrl(struct clk *clk, int enable)
179 {
180 	return s5p_gatectrl(S5P_HDMI_PHY_CONTROL, clk, enable);
181 }
182 
exynos4_clk_dac_ctrl(struct clk * clk,int enable)183 static int exynos4_clk_dac_ctrl(struct clk *clk, int enable)
184 {
185 	return s5p_gatectrl(S5P_DAC_PHY_CONTROL, clk, enable);
186 }
187 
188 static struct clk clk_sclk_hdmi27m = {
189 	.name		= "sclk_hdmi27m",
190 	.rate		= 27000000,
191 };
192 
193 static struct clk clk_sclk_hdmiphy = {
194 	.name		= "sclk_hdmiphy",
195 };
196 
197 static struct clk clk_sclk_usbphy0 = {
198 	.name		= "sclk_usbphy0",
199 };
200 
201 static struct clk clk_sclk_usbphy1 = {
202 	.name		= "sclk_usbphy1",
203 };
204 
205 static struct clk clk_pcmcdclk0 = {
206 	.name		= "pcmcdclk",
207 };
208 
209 static struct clk clk_pcmcdclk1 = {
210 	.name		= "pcmcdclk",
211 };
212 
213 static struct clk clk_pcmcdclk2 = {
214 	.name		= "pcmcdclk",
215 };
216 
217 static struct clk dummy_apb_pclk = {
218 	.name		= "apb_pclk",
219 	.id		= -1,
220 };
221 
222 static struct clk *clkset_vpllsrc_list[] = {
223 	[0] = &clk_fin_vpll,
224 	[1] = &clk_sclk_hdmi27m,
225 };
226 
227 static struct clksrc_sources clkset_vpllsrc = {
228 	.sources	= clkset_vpllsrc_list,
229 	.nr_sources	= ARRAY_SIZE(clkset_vpllsrc_list),
230 };
231 
232 static struct clksrc_clk clk_vpllsrc = {
233 	.clk	= {
234 		.name		= "vpll_src",
235 		.enable		= s5pv210_clk_mask0_ctrl,
236 		.ctrlbit	= (1 << 7),
237 	},
238 	.sources	= &clkset_vpllsrc,
239 	.reg_src	= { .reg = S5P_CLK_SRC1, .shift = 28, .size = 1 },
240 };
241 
242 static struct clk *clkset_sclk_vpll_list[] = {
243 	[0] = &clk_vpllsrc.clk,
244 	[1] = &clk_fout_vpll,
245 };
246 
247 static struct clksrc_sources clkset_sclk_vpll = {
248 	.sources	= clkset_sclk_vpll_list,
249 	.nr_sources	= ARRAY_SIZE(clkset_sclk_vpll_list),
250 };
251 
252 static struct clksrc_clk clk_sclk_vpll = {
253 	.clk	= {
254 		.name		= "sclk_vpll",
255 	},
256 	.sources	= &clkset_sclk_vpll,
257 	.reg_src	= { .reg = S5P_CLK_SRC0, .shift = 12, .size = 1 },
258 };
259 
260 static struct clk *clkset_moutdmc0src_list[] = {
261 	[0] = &clk_sclk_a2m.clk,
262 	[1] = &clk_mout_mpll.clk,
263 	[2] = NULL,
264 	[3] = NULL,
265 };
266 
267 static struct clksrc_sources clkset_moutdmc0src = {
268 	.sources	= clkset_moutdmc0src_list,
269 	.nr_sources	= ARRAY_SIZE(clkset_moutdmc0src_list),
270 };
271 
272 static struct clksrc_clk clk_mout_dmc0 = {
273 	.clk	= {
274 		.name		= "mout_dmc0",
275 	},
276 	.sources	= &clkset_moutdmc0src,
277 	.reg_src	= { .reg = S5P_CLK_SRC6, .shift = 24, .size = 2 },
278 };
279 
280 static struct clksrc_clk clk_sclk_dmc0 = {
281 	.clk	= {
282 		.name		= "sclk_dmc0",
283 		.parent		= &clk_mout_dmc0.clk,
284 	},
285 	.reg_div	= { .reg = S5P_CLK_DIV6, .shift = 28, .size = 4 },
286 };
287 
s5pv210_clk_imem_get_rate(struct clk * clk)288 static unsigned long s5pv210_clk_imem_get_rate(struct clk *clk)
289 {
290 	return clk_get_rate(clk->parent) / 2;
291 }
292 
293 static struct clk_ops clk_hclk_imem_ops = {
294 	.get_rate	= s5pv210_clk_imem_get_rate,
295 };
296 
s5pv210_clk_fout_apll_get_rate(struct clk * clk)297 static unsigned long s5pv210_clk_fout_apll_get_rate(struct clk *clk)
298 {
299 	return s5p_get_pll45xx(xtal, __raw_readl(S5P_APLL_CON), pll_4508);
300 }
301 
302 static struct clk_ops clk_fout_apll_ops = {
303 	.get_rate	= s5pv210_clk_fout_apll_get_rate,
304 };
305 
306 static struct clk init_clocks_off[] = {
307 	{
308 		.name		= "dma",
309 		.devname	= "dma-pl330.0",
310 		.parent		= &clk_hclk_psys.clk,
311 		.enable		= s5pv210_clk_ip0_ctrl,
312 		.ctrlbit	= (1 << 3),
313 	}, {
314 		.name		= "dma",
315 		.devname	= "dma-pl330.1",
316 		.parent		= &clk_hclk_psys.clk,
317 		.enable		= s5pv210_clk_ip0_ctrl,
318 		.ctrlbit	= (1 << 4),
319 	}, {
320 		.name		= "rot",
321 		.parent		= &clk_hclk_dsys.clk,
322 		.enable		= s5pv210_clk_ip0_ctrl,
323 		.ctrlbit	= (1<<29),
324 	}, {
325 		.name		= "fimc",
326 		.devname	= "s5pv210-fimc.0",
327 		.parent		= &clk_hclk_dsys.clk,
328 		.enable		= s5pv210_clk_ip0_ctrl,
329 		.ctrlbit	= (1 << 24),
330 	}, {
331 		.name		= "fimc",
332 		.devname	= "s5pv210-fimc.1",
333 		.parent		= &clk_hclk_dsys.clk,
334 		.enable		= s5pv210_clk_ip0_ctrl,
335 		.ctrlbit	= (1 << 25),
336 	}, {
337 		.name		= "fimc",
338 		.devname	= "s5pv210-fimc.2",
339 		.parent		= &clk_hclk_dsys.clk,
340 		.enable		= s5pv210_clk_ip0_ctrl,
341 		.ctrlbit	= (1 << 26),
342 	}, {
343 		.name		= "mfc",
344 		.devname	= "s5p-mfc",
345 		.parent		= &clk_pclk_psys.clk,
346 		.enable		= s5pv210_clk_ip0_ctrl,
347 		.ctrlbit	= (1 << 16),
348 	}, {
349 		.name		= "dac",
350 		.devname	= "s5p-sdo",
351 		.parent		= &clk_hclk_dsys.clk,
352 		.enable		= s5pv210_clk_ip1_ctrl,
353 		.ctrlbit	= (1 << 10),
354 	}, {
355 		.name		= "mixer",
356 		.devname	= "s5p-mixer",
357 		.parent		= &clk_hclk_dsys.clk,
358 		.enable		= s5pv210_clk_ip1_ctrl,
359 		.ctrlbit	= (1 << 9),
360 	}, {
361 		.name		= "vp",
362 		.devname	= "s5p-mixer",
363 		.parent		= &clk_hclk_dsys.clk,
364 		.enable		= s5pv210_clk_ip1_ctrl,
365 		.ctrlbit	= (1 << 8),
366 	}, {
367 		.name		= "hdmi",
368 		.devname	= "s5pv210-hdmi",
369 		.parent		= &clk_hclk_dsys.clk,
370 		.enable		= s5pv210_clk_ip1_ctrl,
371 		.ctrlbit	= (1 << 11),
372 	}, {
373 		.name		= "hdmiphy",
374 		.devname	= "s5pv210-hdmi",
375 		.enable		= s5pv210_clk_hdmiphy_ctrl,
376 		.ctrlbit	= (1 << 0),
377 	}, {
378 		.name		= "dacphy",
379 		.devname	= "s5p-sdo",
380 		.enable		= exynos4_clk_dac_ctrl,
381 		.ctrlbit	= (1 << 0),
382 	}, {
383 		.name		= "otg",
384 		.parent		= &clk_hclk_psys.clk,
385 		.enable		= s5pv210_clk_ip1_ctrl,
386 		.ctrlbit	= (1<<16),
387 	}, {
388 		.name		= "usb-host",
389 		.parent		= &clk_hclk_psys.clk,
390 		.enable		= s5pv210_clk_ip1_ctrl,
391 		.ctrlbit	= (1<<17),
392 	}, {
393 		.name		= "lcd",
394 		.parent		= &clk_hclk_dsys.clk,
395 		.enable		= s5pv210_clk_ip1_ctrl,
396 		.ctrlbit	= (1<<0),
397 	}, {
398 		.name		= "cfcon",
399 		.parent		= &clk_hclk_psys.clk,
400 		.enable		= s5pv210_clk_ip1_ctrl,
401 		.ctrlbit	= (1<<25),
402 	}, {
403 		.name		= "systimer",
404 		.parent		= &clk_pclk_psys.clk,
405 		.enable		= s5pv210_clk_ip3_ctrl,
406 		.ctrlbit	= (1<<16),
407 	}, {
408 		.name		= "watchdog",
409 		.parent		= &clk_pclk_psys.clk,
410 		.enable		= s5pv210_clk_ip3_ctrl,
411 		.ctrlbit	= (1<<22),
412 	}, {
413 		.name		= "rtc",
414 		.parent		= &clk_pclk_psys.clk,
415 		.enable		= s5pv210_clk_ip3_ctrl,
416 		.ctrlbit	= (1<<15),
417 	}, {
418 		.name		= "i2c",
419 		.devname	= "s3c2440-i2c.0",
420 		.parent		= &clk_pclk_psys.clk,
421 		.enable		= s5pv210_clk_ip3_ctrl,
422 		.ctrlbit	= (1<<7),
423 	}, {
424 		.name		= "i2c",
425 		.devname	= "s3c2440-i2c.1",
426 		.parent		= &clk_pclk_psys.clk,
427 		.enable		= s5pv210_clk_ip3_ctrl,
428 		.ctrlbit	= (1 << 10),
429 	}, {
430 		.name		= "i2c",
431 		.devname	= "s3c2440-i2c.2",
432 		.parent		= &clk_pclk_psys.clk,
433 		.enable		= s5pv210_clk_ip3_ctrl,
434 		.ctrlbit	= (1<<9),
435 	}, {
436 		.name		= "i2c",
437 		.devname	= "s3c2440-hdmiphy-i2c",
438 		.parent		= &clk_pclk_psys.clk,
439 		.enable		= s5pv210_clk_ip3_ctrl,
440 		.ctrlbit	= (1 << 11),
441 	}, {
442 		.name		= "spi",
443 		.devname	= "s3c64xx-spi.0",
444 		.parent		= &clk_pclk_psys.clk,
445 		.enable		= s5pv210_clk_ip3_ctrl,
446 		.ctrlbit	= (1<<12),
447 	}, {
448 		.name		= "spi",
449 		.devname	= "s3c64xx-spi.1",
450 		.parent		= &clk_pclk_psys.clk,
451 		.enable		= s5pv210_clk_ip3_ctrl,
452 		.ctrlbit	= (1<<13),
453 	}, {
454 		.name		= "spi",
455 		.devname	= "s3c64xx-spi.2",
456 		.parent		= &clk_pclk_psys.clk,
457 		.enable		= s5pv210_clk_ip3_ctrl,
458 		.ctrlbit	= (1<<14),
459 	}, {
460 		.name		= "timers",
461 		.parent		= &clk_pclk_psys.clk,
462 		.enable		= s5pv210_clk_ip3_ctrl,
463 		.ctrlbit	= (1<<23),
464 	}, {
465 		.name		= "adc",
466 		.parent		= &clk_pclk_psys.clk,
467 		.enable		= s5pv210_clk_ip3_ctrl,
468 		.ctrlbit	= (1<<24),
469 	}, {
470 		.name		= "keypad",
471 		.parent		= &clk_pclk_psys.clk,
472 		.enable		= s5pv210_clk_ip3_ctrl,
473 		.ctrlbit	= (1<<21),
474 	}, {
475 		.name		= "iis",
476 		.devname	= "samsung-i2s.0",
477 		.parent		= &clk_p,
478 		.enable		= s5pv210_clk_ip3_ctrl,
479 		.ctrlbit	= (1<<4),
480 	}, {
481 		.name		= "iis",
482 		.devname	= "samsung-i2s.1",
483 		.parent		= &clk_p,
484 		.enable		= s5pv210_clk_ip3_ctrl,
485 		.ctrlbit	= (1 << 5),
486 	}, {
487 		.name		= "iis",
488 		.devname	= "samsung-i2s.2",
489 		.parent		= &clk_p,
490 		.enable		= s5pv210_clk_ip3_ctrl,
491 		.ctrlbit	= (1 << 6),
492 	}, {
493 		.name		= "spdif",
494 		.parent		= &clk_p,
495 		.enable		= s5pv210_clk_ip3_ctrl,
496 		.ctrlbit	= (1 << 0),
497 	},
498 };
499 
500 static struct clk init_clocks[] = {
501 	{
502 		.name		= "hclk_imem",
503 		.parent		= &clk_hclk_msys.clk,
504 		.ctrlbit	= (1 << 5),
505 		.enable		= s5pv210_clk_ip0_ctrl,
506 		.ops		= &clk_hclk_imem_ops,
507 	}, {
508 		.name		= "uart",
509 		.devname	= "s5pv210-uart.0",
510 		.parent		= &clk_pclk_psys.clk,
511 		.enable		= s5pv210_clk_ip3_ctrl,
512 		.ctrlbit	= (1 << 17),
513 	}, {
514 		.name		= "uart",
515 		.devname	= "s5pv210-uart.1",
516 		.parent		= &clk_pclk_psys.clk,
517 		.enable		= s5pv210_clk_ip3_ctrl,
518 		.ctrlbit	= (1 << 18),
519 	}, {
520 		.name		= "uart",
521 		.devname	= "s5pv210-uart.2",
522 		.parent		= &clk_pclk_psys.clk,
523 		.enable		= s5pv210_clk_ip3_ctrl,
524 		.ctrlbit	= (1 << 19),
525 	}, {
526 		.name		= "uart",
527 		.devname	= "s5pv210-uart.3",
528 		.parent		= &clk_pclk_psys.clk,
529 		.enable		= s5pv210_clk_ip3_ctrl,
530 		.ctrlbit	= (1 << 20),
531 	}, {
532 		.name		= "sromc",
533 		.parent		= &clk_hclk_psys.clk,
534 		.enable		= s5pv210_clk_ip1_ctrl,
535 		.ctrlbit	= (1 << 26),
536 	},
537 };
538 
539 static struct clk clk_hsmmc0 = {
540 	.name		= "hsmmc",
541 	.devname	= "s3c-sdhci.0",
542 	.parent		= &clk_hclk_psys.clk,
543 	.enable		= s5pv210_clk_ip2_ctrl,
544 	.ctrlbit	= (1<<16),
545 };
546 
547 static struct clk clk_hsmmc1 = {
548 	.name		= "hsmmc",
549 	.devname	= "s3c-sdhci.1",
550 	.parent		= &clk_hclk_psys.clk,
551 	.enable		= s5pv210_clk_ip2_ctrl,
552 	.ctrlbit	= (1<<17),
553 };
554 
555 static struct clk clk_hsmmc2 = {
556 	.name		= "hsmmc",
557 	.devname	= "s3c-sdhci.2",
558 	.parent		= &clk_hclk_psys.clk,
559 	.enable		= s5pv210_clk_ip2_ctrl,
560 	.ctrlbit	= (1<<18),
561 };
562 
563 static struct clk clk_hsmmc3 = {
564 	.name		= "hsmmc",
565 	.devname	= "s3c-sdhci.3",
566 	.parent		= &clk_hclk_psys.clk,
567 	.enable		= s5pv210_clk_ip2_ctrl,
568 	.ctrlbit	= (1<<19),
569 };
570 
571 static struct clk *clkset_uart_list[] = {
572 	[6] = &clk_mout_mpll.clk,
573 	[7] = &clk_mout_epll.clk,
574 };
575 
576 static struct clksrc_sources clkset_uart = {
577 	.sources	= clkset_uart_list,
578 	.nr_sources	= ARRAY_SIZE(clkset_uart_list),
579 };
580 
581 static struct clk *clkset_group1_list[] = {
582 	[0] = &clk_sclk_a2m.clk,
583 	[1] = &clk_mout_mpll.clk,
584 	[2] = &clk_mout_epll.clk,
585 	[3] = &clk_sclk_vpll.clk,
586 };
587 
588 static struct clksrc_sources clkset_group1 = {
589 	.sources	= clkset_group1_list,
590 	.nr_sources	= ARRAY_SIZE(clkset_group1_list),
591 };
592 
593 static struct clk *clkset_sclk_onenand_list[] = {
594 	[0] = &clk_hclk_psys.clk,
595 	[1] = &clk_hclk_dsys.clk,
596 };
597 
598 static struct clksrc_sources clkset_sclk_onenand = {
599 	.sources	= clkset_sclk_onenand_list,
600 	.nr_sources	= ARRAY_SIZE(clkset_sclk_onenand_list),
601 };
602 
603 static struct clk *clkset_sclk_dac_list[] = {
604 	[0] = &clk_sclk_vpll.clk,
605 	[1] = &clk_sclk_hdmiphy,
606 };
607 
608 static struct clksrc_sources clkset_sclk_dac = {
609 	.sources	= clkset_sclk_dac_list,
610 	.nr_sources	= ARRAY_SIZE(clkset_sclk_dac_list),
611 };
612 
613 static struct clksrc_clk clk_sclk_dac = {
614 	.clk		= {
615 		.name		= "sclk_dac",
616 		.enable		= s5pv210_clk_mask0_ctrl,
617 		.ctrlbit	= (1 << 2),
618 	},
619 	.sources	= &clkset_sclk_dac,
620 	.reg_src	= { .reg = S5P_CLK_SRC1, .shift = 8, .size = 1 },
621 };
622 
623 static struct clksrc_clk clk_sclk_pixel = {
624 	.clk		= {
625 		.name		= "sclk_pixel",
626 		.parent		= &clk_sclk_vpll.clk,
627 	},
628 	.reg_div	= { .reg = S5P_CLK_DIV1, .shift = 0, .size = 4},
629 };
630 
631 static struct clk *clkset_sclk_hdmi_list[] = {
632 	[0] = &clk_sclk_pixel.clk,
633 	[1] = &clk_sclk_hdmiphy,
634 };
635 
636 static struct clksrc_sources clkset_sclk_hdmi = {
637 	.sources	= clkset_sclk_hdmi_list,
638 	.nr_sources	= ARRAY_SIZE(clkset_sclk_hdmi_list),
639 };
640 
641 static struct clksrc_clk clk_sclk_hdmi = {
642 	.clk		= {
643 		.name		= "sclk_hdmi",
644 		.enable		= s5pv210_clk_mask0_ctrl,
645 		.ctrlbit	= (1 << 0),
646 	},
647 	.sources	= &clkset_sclk_hdmi,
648 	.reg_src	= { .reg = S5P_CLK_SRC1, .shift = 0, .size = 1 },
649 };
650 
651 static struct clk *clkset_sclk_mixer_list[] = {
652 	[0] = &clk_sclk_dac.clk,
653 	[1] = &clk_sclk_hdmi.clk,
654 };
655 
656 static struct clksrc_sources clkset_sclk_mixer = {
657 	.sources	= clkset_sclk_mixer_list,
658 	.nr_sources	= ARRAY_SIZE(clkset_sclk_mixer_list),
659 };
660 
661 static struct clksrc_clk clk_sclk_mixer = {
662 	.clk		= {
663 		.name		= "sclk_mixer",
664 		.enable		= s5pv210_clk_mask0_ctrl,
665 		.ctrlbit	= (1 << 1),
666 	},
667 	.sources = &clkset_sclk_mixer,
668 	.reg_src = { .reg = S5P_CLK_SRC1, .shift = 4, .size = 1 },
669 };
670 
671 static struct clksrc_clk *sclk_tv[] = {
672 	&clk_sclk_dac,
673 	&clk_sclk_pixel,
674 	&clk_sclk_hdmi,
675 	&clk_sclk_mixer,
676 };
677 
678 static struct clk *clkset_sclk_audio0_list[] = {
679 	[0] = &clk_ext_xtal_mux,
680 	[1] = &clk_pcmcdclk0,
681 	[2] = &clk_sclk_hdmi27m,
682 	[3] = &clk_sclk_usbphy0,
683 	[4] = &clk_sclk_usbphy1,
684 	[5] = &clk_sclk_hdmiphy,
685 	[6] = &clk_mout_mpll.clk,
686 	[7] = &clk_mout_epll.clk,
687 	[8] = &clk_sclk_vpll.clk,
688 };
689 
690 static struct clksrc_sources clkset_sclk_audio0 = {
691 	.sources	= clkset_sclk_audio0_list,
692 	.nr_sources	= ARRAY_SIZE(clkset_sclk_audio0_list),
693 };
694 
695 static struct clksrc_clk clk_sclk_audio0 = {
696 	.clk		= {
697 		.name		= "sclk_audio",
698 		.devname	= "soc-audio.0",
699 		.enable		= s5pv210_clk_mask0_ctrl,
700 		.ctrlbit	= (1 << 24),
701 	},
702 	.sources = &clkset_sclk_audio0,
703 	.reg_src = { .reg = S5P_CLK_SRC6, .shift = 0, .size = 4 },
704 	.reg_div = { .reg = S5P_CLK_DIV6, .shift = 0, .size = 4 },
705 };
706 
707 static struct clk *clkset_sclk_audio1_list[] = {
708 	[0] = &clk_ext_xtal_mux,
709 	[1] = &clk_pcmcdclk1,
710 	[2] = &clk_sclk_hdmi27m,
711 	[3] = &clk_sclk_usbphy0,
712 	[4] = &clk_sclk_usbphy1,
713 	[5] = &clk_sclk_hdmiphy,
714 	[6] = &clk_mout_mpll.clk,
715 	[7] = &clk_mout_epll.clk,
716 	[8] = &clk_sclk_vpll.clk,
717 };
718 
719 static struct clksrc_sources clkset_sclk_audio1 = {
720 	.sources	= clkset_sclk_audio1_list,
721 	.nr_sources	= ARRAY_SIZE(clkset_sclk_audio1_list),
722 };
723 
724 static struct clksrc_clk clk_sclk_audio1 = {
725 	.clk		= {
726 		.name		= "sclk_audio",
727 		.devname	= "soc-audio.1",
728 		.enable		= s5pv210_clk_mask0_ctrl,
729 		.ctrlbit	= (1 << 25),
730 	},
731 	.sources = &clkset_sclk_audio1,
732 	.reg_src = { .reg = S5P_CLK_SRC6, .shift = 4, .size = 4 },
733 	.reg_div = { .reg = S5P_CLK_DIV6, .shift = 4, .size = 4 },
734 };
735 
736 static struct clk *clkset_sclk_audio2_list[] = {
737 	[0] = &clk_ext_xtal_mux,
738 	[1] = &clk_pcmcdclk0,
739 	[2] = &clk_sclk_hdmi27m,
740 	[3] = &clk_sclk_usbphy0,
741 	[4] = &clk_sclk_usbphy1,
742 	[5] = &clk_sclk_hdmiphy,
743 	[6] = &clk_mout_mpll.clk,
744 	[7] = &clk_mout_epll.clk,
745 	[8] = &clk_sclk_vpll.clk,
746 };
747 
748 static struct clksrc_sources clkset_sclk_audio2 = {
749 	.sources	= clkset_sclk_audio2_list,
750 	.nr_sources	= ARRAY_SIZE(clkset_sclk_audio2_list),
751 };
752 
753 static struct clksrc_clk clk_sclk_audio2 = {
754 	.clk		= {
755 		.name		= "sclk_audio",
756 		.devname	= "soc-audio.2",
757 		.enable		= s5pv210_clk_mask0_ctrl,
758 		.ctrlbit	= (1 << 26),
759 	},
760 	.sources = &clkset_sclk_audio2,
761 	.reg_src = { .reg = S5P_CLK_SRC6, .shift = 8, .size = 4 },
762 	.reg_div = { .reg = S5P_CLK_DIV6, .shift = 8, .size = 4 },
763 };
764 
765 static struct clk *clkset_sclk_spdif_list[] = {
766 	[0] = &clk_sclk_audio0.clk,
767 	[1] = &clk_sclk_audio1.clk,
768 	[2] = &clk_sclk_audio2.clk,
769 };
770 
771 static struct clksrc_sources clkset_sclk_spdif = {
772 	.sources	= clkset_sclk_spdif_list,
773 	.nr_sources	= ARRAY_SIZE(clkset_sclk_spdif_list),
774 };
775 
776 static struct clksrc_clk clk_sclk_spdif = {
777 	.clk		= {
778 		.name		= "sclk_spdif",
779 		.enable		= s5pv210_clk_mask0_ctrl,
780 		.ctrlbit	= (1 << 27),
781 		.ops		= &s5p_sclk_spdif_ops,
782 	},
783 	.sources = &clkset_sclk_spdif,
784 	.reg_src = { .reg = S5P_CLK_SRC6, .shift = 12, .size = 2 },
785 };
786 
787 static struct clk *clkset_group2_list[] = {
788 	[0] = &clk_ext_xtal_mux,
789 	[1] = &clk_xusbxti,
790 	[2] = &clk_sclk_hdmi27m,
791 	[3] = &clk_sclk_usbphy0,
792 	[4] = &clk_sclk_usbphy1,
793 	[5] = &clk_sclk_hdmiphy,
794 	[6] = &clk_mout_mpll.clk,
795 	[7] = &clk_mout_epll.clk,
796 	[8] = &clk_sclk_vpll.clk,
797 };
798 
799 static struct clksrc_sources clkset_group2 = {
800 	.sources	= clkset_group2_list,
801 	.nr_sources	= ARRAY_SIZE(clkset_group2_list),
802 };
803 
804 static struct clksrc_clk clksrcs[] = {
805 	{
806 		.clk	= {
807 			.name		= "sclk_dmc",
808 		},
809 		.sources = &clkset_group1,
810 		.reg_src = { .reg = S5P_CLK_SRC6, .shift = 24, .size = 2 },
811 		.reg_div = { .reg = S5P_CLK_DIV6, .shift = 28, .size = 4 },
812 	}, {
813 		.clk	= {
814 			.name		= "sclk_onenand",
815 		},
816 		.sources = &clkset_sclk_onenand,
817 		.reg_src = { .reg = S5P_CLK_SRC0, .shift = 28, .size = 1 },
818 		.reg_div = { .reg = S5P_CLK_DIV6, .shift = 12, .size = 3 },
819 	}, {
820 		.clk	= {
821 			.name		= "sclk_fimc",
822 			.devname	= "s5pv210-fimc.0",
823 			.enable		= s5pv210_clk_mask1_ctrl,
824 			.ctrlbit	= (1 << 2),
825 		},
826 		.sources = &clkset_group2,
827 		.reg_src = { .reg = S5P_CLK_SRC3, .shift = 12, .size = 4 },
828 		.reg_div = { .reg = S5P_CLK_DIV3, .shift = 12, .size = 4 },
829 	}, {
830 		.clk	= {
831 			.name		= "sclk_fimc",
832 			.devname	= "s5pv210-fimc.1",
833 			.enable		= s5pv210_clk_mask1_ctrl,
834 			.ctrlbit	= (1 << 3),
835 		},
836 		.sources = &clkset_group2,
837 		.reg_src = { .reg = S5P_CLK_SRC3, .shift = 16, .size = 4 },
838 		.reg_div = { .reg = S5P_CLK_DIV3, .shift = 16, .size = 4 },
839 	}, {
840 		.clk	= {
841 			.name		= "sclk_fimc",
842 			.devname	= "s5pv210-fimc.2",
843 			.enable		= s5pv210_clk_mask1_ctrl,
844 			.ctrlbit	= (1 << 4),
845 		},
846 		.sources = &clkset_group2,
847 		.reg_src = { .reg = S5P_CLK_SRC3, .shift = 20, .size = 4 },
848 		.reg_div = { .reg = S5P_CLK_DIV3, .shift = 20, .size = 4 },
849 	}, {
850 		.clk		= {
851 			.name		= "sclk_cam0",
852 			.enable		= s5pv210_clk_mask0_ctrl,
853 			.ctrlbit	= (1 << 3),
854 		},
855 		.sources = &clkset_group2,
856 		.reg_src = { .reg = S5P_CLK_SRC1, .shift = 12, .size = 4 },
857 		.reg_div = { .reg = S5P_CLK_DIV1, .shift = 12, .size = 4 },
858 	}, {
859 		.clk		= {
860 			.name		= "sclk_cam1",
861 			.enable		= s5pv210_clk_mask0_ctrl,
862 			.ctrlbit	= (1 << 4),
863 		},
864 		.sources = &clkset_group2,
865 		.reg_src = { .reg = S5P_CLK_SRC1, .shift = 16, .size = 4 },
866 		.reg_div = { .reg = S5P_CLK_DIV1, .shift = 16, .size = 4 },
867 	}, {
868 		.clk		= {
869 			.name		= "sclk_fimd",
870 			.enable		= s5pv210_clk_mask0_ctrl,
871 			.ctrlbit	= (1 << 5),
872 		},
873 		.sources = &clkset_group2,
874 		.reg_src = { .reg = S5P_CLK_SRC1, .shift = 20, .size = 4 },
875 		.reg_div = { .reg = S5P_CLK_DIV1, .shift = 20, .size = 4 },
876 	}, {
877 		.clk		= {
878 			.name		= "sclk_mfc",
879 			.devname	= "s5p-mfc",
880 			.enable		= s5pv210_clk_ip0_ctrl,
881 			.ctrlbit	= (1 << 16),
882 		},
883 		.sources = &clkset_group1,
884 		.reg_src = { .reg = S5P_CLK_SRC2, .shift = 4, .size = 2 },
885 		.reg_div = { .reg = S5P_CLK_DIV2, .shift = 4, .size = 4 },
886 	}, {
887 		.clk		= {
888 			.name		= "sclk_g2d",
889 			.enable		= s5pv210_clk_ip0_ctrl,
890 			.ctrlbit	= (1 << 12),
891 		},
892 		.sources = &clkset_group1,
893 		.reg_src = { .reg = S5P_CLK_SRC2, .shift = 8, .size = 2 },
894 		.reg_div = { .reg = S5P_CLK_DIV2, .shift = 8, .size = 4 },
895 	}, {
896 		.clk		= {
897 			.name		= "sclk_g3d",
898 			.enable		= s5pv210_clk_ip0_ctrl,
899 			.ctrlbit	= (1 << 8),
900 		},
901 		.sources = &clkset_group1,
902 		.reg_src = { .reg = S5P_CLK_SRC2, .shift = 0, .size = 2 },
903 		.reg_div = { .reg = S5P_CLK_DIV2, .shift = 0, .size = 4 },
904 	}, {
905 		.clk		= {
906 			.name		= "sclk_csis",
907 			.enable		= s5pv210_clk_mask0_ctrl,
908 			.ctrlbit	= (1 << 6),
909 		},
910 		.sources = &clkset_group2,
911 		.reg_src = { .reg = S5P_CLK_SRC1, .shift = 24, .size = 4 },
912 		.reg_div = { .reg = S5P_CLK_DIV1, .shift = 28, .size = 4 },
913 	}, {
914 		.clk		= {
915 			.name		= "sclk_pwi",
916 			.enable		= s5pv210_clk_mask0_ctrl,
917 			.ctrlbit	= (1 << 29),
918 		},
919 		.sources = &clkset_group2,
920 		.reg_src = { .reg = S5P_CLK_SRC6, .shift = 20, .size = 4 },
921 		.reg_div = { .reg = S5P_CLK_DIV6, .shift = 24, .size = 4 },
922 	}, {
923 		.clk		= {
924 			.name		= "sclk_pwm",
925 			.enable		= s5pv210_clk_mask0_ctrl,
926 			.ctrlbit	= (1 << 19),
927 		},
928 		.sources = &clkset_group2,
929 		.reg_src = { .reg = S5P_CLK_SRC5, .shift = 12, .size = 4 },
930 		.reg_div = { .reg = S5P_CLK_DIV5, .shift = 12, .size = 4 },
931 	},
932 };
933 
934 static struct clksrc_clk clk_sclk_uart0 = {
935 	.clk	= {
936 		.name		= "uclk1",
937 		.devname	= "s5pv210-uart.0",
938 		.enable		= s5pv210_clk_mask0_ctrl,
939 		.ctrlbit	= (1 << 12),
940 	},
941 	.sources = &clkset_uart,
942 	.reg_src = { .reg = S5P_CLK_SRC4, .shift = 16, .size = 4 },
943 	.reg_div = { .reg = S5P_CLK_DIV4, .shift = 16, .size = 4 },
944 };
945 
946 static struct clksrc_clk clk_sclk_uart1 = {
947 	.clk		= {
948 		.name		= "uclk1",
949 		.devname	= "s5pv210-uart.1",
950 		.enable		= s5pv210_clk_mask0_ctrl,
951 		.ctrlbit	= (1 << 13),
952 	},
953 	.sources = &clkset_uart,
954 	.reg_src = { .reg = S5P_CLK_SRC4, .shift = 20, .size = 4 },
955 	.reg_div = { .reg = S5P_CLK_DIV4, .shift = 20, .size = 4 },
956 };
957 
958 static struct clksrc_clk clk_sclk_uart2 = {
959 	.clk		= {
960 		.name		= "uclk1",
961 		.devname	= "s5pv210-uart.2",
962 		.enable		= s5pv210_clk_mask0_ctrl,
963 		.ctrlbit	= (1 << 14),
964 	},
965 	.sources = &clkset_uart,
966 	.reg_src = { .reg = S5P_CLK_SRC4, .shift = 24, .size = 4 },
967 	.reg_div = { .reg = S5P_CLK_DIV4, .shift = 24, .size = 4 },
968 };
969 
970 static struct clksrc_clk clk_sclk_uart3	= {
971 	.clk		= {
972 		.name		= "uclk1",
973 		.devname	= "s5pv210-uart.3",
974 		.enable		= s5pv210_clk_mask0_ctrl,
975 		.ctrlbit	= (1 << 15),
976 	},
977 	.sources = &clkset_uart,
978 	.reg_src = { .reg = S5P_CLK_SRC4, .shift = 28, .size = 4 },
979 	.reg_div = { .reg = S5P_CLK_DIV4, .shift = 28, .size = 4 },
980 };
981 
982 static struct clksrc_clk clk_sclk_mmc0 = {
983 	.clk		= {
984 		.name		= "sclk_mmc",
985 		.devname	= "s3c-sdhci.0",
986 		.enable		= s5pv210_clk_mask0_ctrl,
987 		.ctrlbit	= (1 << 8),
988 	},
989 	.sources = &clkset_group2,
990 	.reg_src = { .reg = S5P_CLK_SRC4, .shift = 0, .size = 4 },
991 	.reg_div = { .reg = S5P_CLK_DIV4, .shift = 0, .size = 4 },
992 };
993 
994 static struct clksrc_clk clk_sclk_mmc1 = {
995 	.clk		= {
996 		.name		= "sclk_mmc",
997 		.devname	= "s3c-sdhci.1",
998 		.enable		= s5pv210_clk_mask0_ctrl,
999 		.ctrlbit	= (1 << 9),
1000 	},
1001 	.sources = &clkset_group2,
1002 	.reg_src = { .reg = S5P_CLK_SRC4, .shift = 4, .size = 4 },
1003 	.reg_div = { .reg = S5P_CLK_DIV4, .shift = 4, .size = 4 },
1004 };
1005 
1006 static struct clksrc_clk clk_sclk_mmc2 = {
1007 	.clk		= {
1008 		.name		= "sclk_mmc",
1009 		.devname	= "s3c-sdhci.2",
1010 		.enable		= s5pv210_clk_mask0_ctrl,
1011 		.ctrlbit	= (1 << 10),
1012 	},
1013 	.sources = &clkset_group2,
1014 	.reg_src = { .reg = S5P_CLK_SRC4, .shift = 8, .size = 4 },
1015 	.reg_div = { .reg = S5P_CLK_DIV4, .shift = 8, .size = 4 },
1016 };
1017 
1018 static struct clksrc_clk clk_sclk_mmc3 = {
1019 	.clk		= {
1020 		.name		= "sclk_mmc",
1021 		.devname	= "s3c-sdhci.3",
1022 		.enable		= s5pv210_clk_mask0_ctrl,
1023 		.ctrlbit	= (1 << 11),
1024 	},
1025 	.sources = &clkset_group2,
1026 	.reg_src = { .reg = S5P_CLK_SRC4, .shift = 12, .size = 4 },
1027 	.reg_div = { .reg = S5P_CLK_DIV4, .shift = 12, .size = 4 },
1028 };
1029 
1030 static struct clksrc_clk clk_sclk_spi0 = {
1031 	.clk		= {
1032 		.name		= "sclk_spi",
1033 		.devname	= "s3c64xx-spi.0",
1034 		.enable		= s5pv210_clk_mask0_ctrl,
1035 		.ctrlbit	= (1 << 16),
1036 	},
1037 	.sources = &clkset_group2,
1038 	.reg_src = { .reg = S5P_CLK_SRC5, .shift = 0, .size = 4 },
1039 	.reg_div = { .reg = S5P_CLK_DIV5, .shift = 0, .size = 4 },
1040 	};
1041 
1042 static struct clksrc_clk clk_sclk_spi1 = {
1043 	.clk		= {
1044 		.name		= "sclk_spi",
1045 		.devname	= "s3c64xx-spi.1",
1046 		.enable		= s5pv210_clk_mask0_ctrl,
1047 		.ctrlbit	= (1 << 17),
1048 	},
1049 	.sources = &clkset_group2,
1050 	.reg_src = { .reg = S5P_CLK_SRC5, .shift = 4, .size = 4 },
1051 	.reg_div = { .reg = S5P_CLK_DIV5, .shift = 4, .size = 4 },
1052 	};
1053 
1054 
1055 static struct clksrc_clk *clksrc_cdev[] = {
1056 	&clk_sclk_uart0,
1057 	&clk_sclk_uart1,
1058 	&clk_sclk_uart2,
1059 	&clk_sclk_uart3,
1060 	&clk_sclk_mmc0,
1061 	&clk_sclk_mmc1,
1062 	&clk_sclk_mmc2,
1063 	&clk_sclk_mmc3,
1064 	&clk_sclk_spi0,
1065 	&clk_sclk_spi1,
1066 };
1067 
1068 static struct clk *clk_cdev[] = {
1069 	&clk_hsmmc0,
1070 	&clk_hsmmc1,
1071 	&clk_hsmmc2,
1072 	&clk_hsmmc3,
1073 };
1074 
1075 /* Clock initialisation code */
1076 static struct clksrc_clk *sysclks[] = {
1077 	&clk_mout_apll,
1078 	&clk_mout_epll,
1079 	&clk_mout_mpll,
1080 	&clk_armclk,
1081 	&clk_hclk_msys,
1082 	&clk_sclk_a2m,
1083 	&clk_hclk_dsys,
1084 	&clk_hclk_psys,
1085 	&clk_pclk_msys,
1086 	&clk_pclk_dsys,
1087 	&clk_pclk_psys,
1088 	&clk_vpllsrc,
1089 	&clk_sclk_vpll,
1090 	&clk_mout_dmc0,
1091 	&clk_sclk_dmc0,
1092 	&clk_sclk_audio0,
1093 	&clk_sclk_audio1,
1094 	&clk_sclk_audio2,
1095 	&clk_sclk_spdif,
1096 };
1097 
1098 static u32 epll_div[][6] = {
1099 	{  48000000, 0, 48, 3, 3, 0 },
1100 	{  96000000, 0, 48, 3, 2, 0 },
1101 	{ 144000000, 1, 72, 3, 2, 0 },
1102 	{ 192000000, 0, 48, 3, 1, 0 },
1103 	{ 288000000, 1, 72, 3, 1, 0 },
1104 	{  32750000, 1, 65, 3, 4, 35127 },
1105 	{  32768000, 1, 65, 3, 4, 35127 },
1106 	{  45158400, 0, 45, 3, 3, 10355 },
1107 	{  45000000, 0, 45, 3, 3, 10355 },
1108 	{  45158000, 0, 45, 3, 3, 10355 },
1109 	{  49125000, 0, 49, 3, 3, 9961 },
1110 	{  49152000, 0, 49, 3, 3, 9961 },
1111 	{  67737600, 1, 67, 3, 3, 48366 },
1112 	{  67738000, 1, 67, 3, 3, 48366 },
1113 	{  73800000, 1, 73, 3, 3, 47710 },
1114 	{  73728000, 1, 73, 3, 3, 47710 },
1115 	{  36000000, 1, 32, 3, 4, 0 },
1116 	{  60000000, 1, 60, 3, 3, 0 },
1117 	{  72000000, 1, 72, 3, 3, 0 },
1118 	{  80000000, 1, 80, 3, 3, 0 },
1119 	{  84000000, 0, 42, 3, 2, 0 },
1120 	{  50000000, 0, 50, 3, 3, 0 },
1121 };
1122 
s5pv210_epll_set_rate(struct clk * clk,unsigned long rate)1123 static int s5pv210_epll_set_rate(struct clk *clk, unsigned long rate)
1124 {
1125 	unsigned int epll_con, epll_con_k;
1126 	unsigned int i;
1127 
1128 	/* Return if nothing changed */
1129 	if (clk->rate == rate)
1130 		return 0;
1131 
1132 	epll_con = __raw_readl(S5P_EPLL_CON);
1133 	epll_con_k = __raw_readl(S5P_EPLL_CON1);
1134 
1135 	epll_con_k &= ~PLL46XX_KDIV_MASK;
1136 	epll_con &= ~(1 << 27 |
1137 			PLL46XX_MDIV_MASK << PLL46XX_MDIV_SHIFT |
1138 			PLL46XX_PDIV_MASK << PLL46XX_PDIV_SHIFT |
1139 			PLL46XX_SDIV_MASK << PLL46XX_SDIV_SHIFT);
1140 
1141 	for (i = 0; i < ARRAY_SIZE(epll_div); i++) {
1142 		if (epll_div[i][0] == rate) {
1143 			epll_con_k |= epll_div[i][5] << 0;
1144 			epll_con |= (epll_div[i][1] << 27 |
1145 					epll_div[i][2] << PLL46XX_MDIV_SHIFT |
1146 					epll_div[i][3] << PLL46XX_PDIV_SHIFT |
1147 					epll_div[i][4] << PLL46XX_SDIV_SHIFT);
1148 			break;
1149 		}
1150 	}
1151 
1152 	if (i == ARRAY_SIZE(epll_div)) {
1153 		printk(KERN_ERR "%s: Invalid Clock EPLL Frequency\n",
1154 				__func__);
1155 		return -EINVAL;
1156 	}
1157 
1158 	__raw_writel(epll_con, S5P_EPLL_CON);
1159 	__raw_writel(epll_con_k, S5P_EPLL_CON1);
1160 
1161 	printk(KERN_WARNING "EPLL Rate changes from %lu to %lu\n",
1162 			clk->rate, rate);
1163 
1164 	clk->rate = rate;
1165 
1166 	return 0;
1167 }
1168 
1169 static struct clk_ops s5pv210_epll_ops = {
1170 	.set_rate = s5pv210_epll_set_rate,
1171 	.get_rate = s5p_epll_get_rate,
1172 };
1173 
1174 static u32 vpll_div[][5] = {
1175 	{  54000000, 3, 53, 3, 0 },
1176 	{ 108000000, 3, 53, 2, 0 },
1177 };
1178 
s5pv210_vpll_get_rate(struct clk * clk)1179 static unsigned long s5pv210_vpll_get_rate(struct clk *clk)
1180 {
1181 	return clk->rate;
1182 }
1183 
s5pv210_vpll_set_rate(struct clk * clk,unsigned long rate)1184 static int s5pv210_vpll_set_rate(struct clk *clk, unsigned long rate)
1185 {
1186 	unsigned int vpll_con;
1187 	unsigned int i;
1188 
1189 	/* Return if nothing changed */
1190 	if (clk->rate == rate)
1191 		return 0;
1192 
1193 	vpll_con = __raw_readl(S5P_VPLL_CON);
1194 	vpll_con &= ~(0x1 << 27 |					\
1195 			PLL90XX_MDIV_MASK << PLL90XX_MDIV_SHIFT |	\
1196 			PLL90XX_PDIV_MASK << PLL90XX_PDIV_SHIFT |	\
1197 			PLL90XX_SDIV_MASK << PLL90XX_SDIV_SHIFT);
1198 
1199 	for (i = 0; i < ARRAY_SIZE(vpll_div); i++) {
1200 		if (vpll_div[i][0] == rate) {
1201 			vpll_con |= vpll_div[i][1] << PLL90XX_PDIV_SHIFT;
1202 			vpll_con |= vpll_div[i][2] << PLL90XX_MDIV_SHIFT;
1203 			vpll_con |= vpll_div[i][3] << PLL90XX_SDIV_SHIFT;
1204 			vpll_con |= vpll_div[i][4] << 27;
1205 			break;
1206 		}
1207 	}
1208 
1209 	if (i == ARRAY_SIZE(vpll_div)) {
1210 		printk(KERN_ERR "%s: Invalid Clock VPLL Frequency\n",
1211 				__func__);
1212 		return -EINVAL;
1213 	}
1214 
1215 	__raw_writel(vpll_con, S5P_VPLL_CON);
1216 
1217 	/* Wait for VPLL lock */
1218 	while (!(__raw_readl(S5P_VPLL_CON) & (1 << PLL90XX_LOCKED_SHIFT)))
1219 		continue;
1220 
1221 	clk->rate = rate;
1222 	return 0;
1223 }
1224 static struct clk_ops s5pv210_vpll_ops = {
1225 	.get_rate = s5pv210_vpll_get_rate,
1226 	.set_rate = s5pv210_vpll_set_rate,
1227 };
1228 
s5pv210_setup_clocks(void)1229 void __init_or_cpufreq s5pv210_setup_clocks(void)
1230 {
1231 	struct clk *xtal_clk;
1232 	unsigned long vpllsrc;
1233 	unsigned long armclk;
1234 	unsigned long hclk_msys;
1235 	unsigned long hclk_dsys;
1236 	unsigned long hclk_psys;
1237 	unsigned long pclk_msys;
1238 	unsigned long pclk_dsys;
1239 	unsigned long pclk_psys;
1240 	unsigned long apll;
1241 	unsigned long mpll;
1242 	unsigned long epll;
1243 	unsigned long vpll;
1244 	unsigned int ptr;
1245 	u32 clkdiv0, clkdiv1;
1246 
1247 	/* Set functions for clk_fout_epll */
1248 	clk_fout_epll.enable = s5p_epll_enable;
1249 	clk_fout_epll.ops = &s5pv210_epll_ops;
1250 
1251 	printk(KERN_DEBUG "%s: registering clocks\n", __func__);
1252 
1253 	clkdiv0 = __raw_readl(S5P_CLK_DIV0);
1254 	clkdiv1 = __raw_readl(S5P_CLK_DIV1);
1255 
1256 	printk(KERN_DEBUG "%s: clkdiv0 = %08x, clkdiv1 = %08x\n",
1257 				__func__, clkdiv0, clkdiv1);
1258 
1259 	xtal_clk = clk_get(NULL, "xtal");
1260 	BUG_ON(IS_ERR(xtal_clk));
1261 
1262 	xtal = clk_get_rate(xtal_clk);
1263 	clk_put(xtal_clk);
1264 
1265 	printk(KERN_DEBUG "%s: xtal is %ld\n", __func__, xtal);
1266 
1267 	apll = s5p_get_pll45xx(xtal, __raw_readl(S5P_APLL_CON), pll_4508);
1268 	mpll = s5p_get_pll45xx(xtal, __raw_readl(S5P_MPLL_CON), pll_4502);
1269 	epll = s5p_get_pll46xx(xtal, __raw_readl(S5P_EPLL_CON),
1270 				__raw_readl(S5P_EPLL_CON1), pll_4600);
1271 	vpllsrc = clk_get_rate(&clk_vpllsrc.clk);
1272 	vpll = s5p_get_pll45xx(vpllsrc, __raw_readl(S5P_VPLL_CON), pll_4502);
1273 
1274 	clk_fout_apll.ops = &clk_fout_apll_ops;
1275 	clk_fout_mpll.rate = mpll;
1276 	clk_fout_epll.rate = epll;
1277 	clk_fout_vpll.ops = &s5pv210_vpll_ops;
1278 	clk_fout_vpll.rate = vpll;
1279 
1280 	printk(KERN_INFO "S5PV210: PLL settings, A=%ld, M=%ld, E=%ld V=%ld",
1281 			apll, mpll, epll, vpll);
1282 
1283 	armclk = clk_get_rate(&clk_armclk.clk);
1284 	hclk_msys = clk_get_rate(&clk_hclk_msys.clk);
1285 	hclk_dsys = clk_get_rate(&clk_hclk_dsys.clk);
1286 	hclk_psys = clk_get_rate(&clk_hclk_psys.clk);
1287 	pclk_msys = clk_get_rate(&clk_pclk_msys.clk);
1288 	pclk_dsys = clk_get_rate(&clk_pclk_dsys.clk);
1289 	pclk_psys = clk_get_rate(&clk_pclk_psys.clk);
1290 
1291 	printk(KERN_INFO "S5PV210: ARMCLK=%ld, HCLKM=%ld, HCLKD=%ld\n"
1292 			 "HCLKP=%ld, PCLKM=%ld, PCLKD=%ld, PCLKP=%ld\n",
1293 			armclk, hclk_msys, hclk_dsys, hclk_psys,
1294 			pclk_msys, pclk_dsys, pclk_psys);
1295 
1296 	clk_f.rate = armclk;
1297 	clk_h.rate = hclk_psys;
1298 	clk_p.rate = pclk_psys;
1299 
1300 	for (ptr = 0; ptr < ARRAY_SIZE(clksrcs); ptr++)
1301 		s3c_set_clksrc(&clksrcs[ptr], true);
1302 }
1303 
1304 static struct clk *clks[] __initdata = {
1305 	&clk_sclk_hdmi27m,
1306 	&clk_sclk_hdmiphy,
1307 	&clk_sclk_usbphy0,
1308 	&clk_sclk_usbphy1,
1309 	&clk_pcmcdclk0,
1310 	&clk_pcmcdclk1,
1311 	&clk_pcmcdclk2,
1312 };
1313 
1314 static struct clk_lookup s5pv210_clk_lookup[] = {
1315 	CLKDEV_INIT(NULL, "clk_uart_baud0", &clk_p),
1316 	CLKDEV_INIT("s5pv210-uart.0", "clk_uart_baud1", &clk_sclk_uart0.clk),
1317 	CLKDEV_INIT("s5pv210-uart.1", "clk_uart_baud1", &clk_sclk_uart1.clk),
1318 	CLKDEV_INIT("s5pv210-uart.2", "clk_uart_baud1", &clk_sclk_uart2.clk),
1319 	CLKDEV_INIT("s5pv210-uart.3", "clk_uart_baud1", &clk_sclk_uart3.clk),
1320 	CLKDEV_INIT("s3c-sdhci.0", "mmc_busclk.0", &clk_hsmmc0),
1321 	CLKDEV_INIT("s3c-sdhci.1", "mmc_busclk.0", &clk_hsmmc1),
1322 	CLKDEV_INIT("s3c-sdhci.2", "mmc_busclk.0", &clk_hsmmc2),
1323 	CLKDEV_INIT("s3c-sdhci.3", "mmc_busclk.0", &clk_hsmmc3),
1324 	CLKDEV_INIT("s3c-sdhci.0", "mmc_busclk.2", &clk_sclk_mmc0.clk),
1325 	CLKDEV_INIT("s3c-sdhci.1", "mmc_busclk.2", &clk_sclk_mmc1.clk),
1326 	CLKDEV_INIT("s3c-sdhci.2", "mmc_busclk.2", &clk_sclk_mmc2.clk),
1327 	CLKDEV_INIT("s3c-sdhci.3", "mmc_busclk.2", &clk_sclk_mmc3.clk),
1328 	CLKDEV_INIT(NULL, "spi_busclk0", &clk_p),
1329 	CLKDEV_INIT("s3c64xx-spi.0", "spi_busclk1", &clk_sclk_spi0.clk),
1330 	CLKDEV_INIT("s3c64xx-spi.1", "spi_busclk1", &clk_sclk_spi1.clk),
1331 };
1332 
s5pv210_register_clocks(void)1333 void __init s5pv210_register_clocks(void)
1334 {
1335 	int ptr;
1336 
1337 	s3c24xx_register_clocks(clks, ARRAY_SIZE(clks));
1338 
1339 	for (ptr = 0; ptr < ARRAY_SIZE(sysclks); ptr++)
1340 		s3c_register_clksrc(sysclks[ptr], 1);
1341 
1342 	for (ptr = 0; ptr < ARRAY_SIZE(sclk_tv); ptr++)
1343 		s3c_register_clksrc(sclk_tv[ptr], 1);
1344 
1345 	for (ptr = 0; ptr < ARRAY_SIZE(clksrc_cdev); ptr++)
1346 		s3c_register_clksrc(clksrc_cdev[ptr], 1);
1347 
1348 	s3c_register_clksrc(clksrcs, ARRAY_SIZE(clksrcs));
1349 	s3c_register_clocks(init_clocks, ARRAY_SIZE(init_clocks));
1350 
1351 	s3c_register_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off));
1352 	s3c_disable_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off));
1353 	clkdev_add_table(s5pv210_clk_lookup, ARRAY_SIZE(s5pv210_clk_lookup));
1354 
1355 	s3c24xx_register_clocks(clk_cdev, ARRAY_SIZE(clk_cdev));
1356 	for (ptr = 0; ptr < ARRAY_SIZE(clk_cdev); ptr++)
1357 		s3c_disable_clocks(clk_cdev[ptr], 1);
1358 
1359 	s3c24xx_register_clock(&dummy_apb_pclk);
1360 	s3c_pwmclk_init();
1361 }
1362