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		= "jpeg",
344 		.parent		= &clk_hclk_dsys.clk,
345 		.enable		= s5pv210_clk_ip0_ctrl,
346 		.ctrlbit	= (1 << 28),
347 	}, {
348 		.name		= "mfc",
349 		.devname	= "s5p-mfc",
350 		.parent		= &clk_pclk_psys.clk,
351 		.enable		= s5pv210_clk_ip0_ctrl,
352 		.ctrlbit	= (1 << 16),
353 	}, {
354 		.name		= "dac",
355 		.devname	= "s5p-sdo",
356 		.parent		= &clk_hclk_dsys.clk,
357 		.enable		= s5pv210_clk_ip1_ctrl,
358 		.ctrlbit	= (1 << 10),
359 	}, {
360 		.name		= "mixer",
361 		.devname	= "s5p-mixer",
362 		.parent		= &clk_hclk_dsys.clk,
363 		.enable		= s5pv210_clk_ip1_ctrl,
364 		.ctrlbit	= (1 << 9),
365 	}, {
366 		.name		= "vp",
367 		.devname	= "s5p-mixer",
368 		.parent		= &clk_hclk_dsys.clk,
369 		.enable		= s5pv210_clk_ip1_ctrl,
370 		.ctrlbit	= (1 << 8),
371 	}, {
372 		.name		= "hdmi",
373 		.devname	= "s5pv210-hdmi",
374 		.parent		= &clk_hclk_dsys.clk,
375 		.enable		= s5pv210_clk_ip1_ctrl,
376 		.ctrlbit	= (1 << 11),
377 	}, {
378 		.name		= "hdmiphy",
379 		.devname	= "s5pv210-hdmi",
380 		.enable		= s5pv210_clk_hdmiphy_ctrl,
381 		.ctrlbit	= (1 << 0),
382 	}, {
383 		.name		= "dacphy",
384 		.devname	= "s5p-sdo",
385 		.enable		= exynos4_clk_dac_ctrl,
386 		.ctrlbit	= (1 << 0),
387 	}, {
388 		.name		= "otg",
389 		.parent		= &clk_hclk_psys.clk,
390 		.enable		= s5pv210_clk_ip1_ctrl,
391 		.ctrlbit	= (1<<16),
392 	}, {
393 		.name		= "usb-host",
394 		.parent		= &clk_hclk_psys.clk,
395 		.enable		= s5pv210_clk_ip1_ctrl,
396 		.ctrlbit	= (1<<17),
397 	}, {
398 		.name		= "lcd",
399 		.parent		= &clk_hclk_dsys.clk,
400 		.enable		= s5pv210_clk_ip1_ctrl,
401 		.ctrlbit	= (1<<0),
402 	}, {
403 		.name		= "cfcon",
404 		.parent		= &clk_hclk_psys.clk,
405 		.enable		= s5pv210_clk_ip1_ctrl,
406 		.ctrlbit	= (1<<25),
407 	}, {
408 		.name		= "systimer",
409 		.parent		= &clk_pclk_psys.clk,
410 		.enable		= s5pv210_clk_ip3_ctrl,
411 		.ctrlbit	= (1<<16),
412 	}, {
413 		.name		= "watchdog",
414 		.parent		= &clk_pclk_psys.clk,
415 		.enable		= s5pv210_clk_ip3_ctrl,
416 		.ctrlbit	= (1<<22),
417 	}, {
418 		.name		= "rtc",
419 		.parent		= &clk_pclk_psys.clk,
420 		.enable		= s5pv210_clk_ip3_ctrl,
421 		.ctrlbit	= (1<<15),
422 	}, {
423 		.name		= "i2c",
424 		.devname	= "s3c2440-i2c.0",
425 		.parent		= &clk_pclk_psys.clk,
426 		.enable		= s5pv210_clk_ip3_ctrl,
427 		.ctrlbit	= (1<<7),
428 	}, {
429 		.name		= "i2c",
430 		.devname	= "s3c2440-i2c.1",
431 		.parent		= &clk_pclk_psys.clk,
432 		.enable		= s5pv210_clk_ip3_ctrl,
433 		.ctrlbit	= (1 << 10),
434 	}, {
435 		.name		= "i2c",
436 		.devname	= "s3c2440-i2c.2",
437 		.parent		= &clk_pclk_psys.clk,
438 		.enable		= s5pv210_clk_ip3_ctrl,
439 		.ctrlbit	= (1<<9),
440 	}, {
441 		.name		= "i2c",
442 		.devname	= "s3c2440-hdmiphy-i2c",
443 		.parent		= &clk_pclk_psys.clk,
444 		.enable		= s5pv210_clk_ip3_ctrl,
445 		.ctrlbit	= (1 << 11),
446 	}, {
447 		.name		= "spi",
448 		.devname	= "s3c64xx-spi.0",
449 		.parent		= &clk_pclk_psys.clk,
450 		.enable		= s5pv210_clk_ip3_ctrl,
451 		.ctrlbit	= (1<<12),
452 	}, {
453 		.name		= "spi",
454 		.devname	= "s3c64xx-spi.1",
455 		.parent		= &clk_pclk_psys.clk,
456 		.enable		= s5pv210_clk_ip3_ctrl,
457 		.ctrlbit	= (1<<13),
458 	}, {
459 		.name		= "spi",
460 		.devname	= "s3c64xx-spi.2",
461 		.parent		= &clk_pclk_psys.clk,
462 		.enable		= s5pv210_clk_ip3_ctrl,
463 		.ctrlbit	= (1<<14),
464 	}, {
465 		.name		= "timers",
466 		.parent		= &clk_pclk_psys.clk,
467 		.enable		= s5pv210_clk_ip3_ctrl,
468 		.ctrlbit	= (1<<23),
469 	}, {
470 		.name		= "adc",
471 		.parent		= &clk_pclk_psys.clk,
472 		.enable		= s5pv210_clk_ip3_ctrl,
473 		.ctrlbit	= (1<<24),
474 	}, {
475 		.name		= "keypad",
476 		.parent		= &clk_pclk_psys.clk,
477 		.enable		= s5pv210_clk_ip3_ctrl,
478 		.ctrlbit	= (1<<21),
479 	}, {
480 		.name		= "iis",
481 		.devname	= "samsung-i2s.0",
482 		.parent		= &clk_p,
483 		.enable		= s5pv210_clk_ip3_ctrl,
484 		.ctrlbit	= (1<<4),
485 	}, {
486 		.name		= "iis",
487 		.devname	= "samsung-i2s.1",
488 		.parent		= &clk_p,
489 		.enable		= s5pv210_clk_ip3_ctrl,
490 		.ctrlbit	= (1 << 5),
491 	}, {
492 		.name		= "iis",
493 		.devname	= "samsung-i2s.2",
494 		.parent		= &clk_p,
495 		.enable		= s5pv210_clk_ip3_ctrl,
496 		.ctrlbit	= (1 << 6),
497 	}, {
498 		.name		= "spdif",
499 		.parent		= &clk_p,
500 		.enable		= s5pv210_clk_ip3_ctrl,
501 		.ctrlbit	= (1 << 0),
502 	},
503 };
504 
505 static struct clk init_clocks[] = {
506 	{
507 		.name		= "hclk_imem",
508 		.parent		= &clk_hclk_msys.clk,
509 		.ctrlbit	= (1 << 5),
510 		.enable		= s5pv210_clk_ip0_ctrl,
511 		.ops		= &clk_hclk_imem_ops,
512 	}, {
513 		.name		= "uart",
514 		.devname	= "s5pv210-uart.0",
515 		.parent		= &clk_pclk_psys.clk,
516 		.enable		= s5pv210_clk_ip3_ctrl,
517 		.ctrlbit	= (1 << 17),
518 	}, {
519 		.name		= "uart",
520 		.devname	= "s5pv210-uart.1",
521 		.parent		= &clk_pclk_psys.clk,
522 		.enable		= s5pv210_clk_ip3_ctrl,
523 		.ctrlbit	= (1 << 18),
524 	}, {
525 		.name		= "uart",
526 		.devname	= "s5pv210-uart.2",
527 		.parent		= &clk_pclk_psys.clk,
528 		.enable		= s5pv210_clk_ip3_ctrl,
529 		.ctrlbit	= (1 << 19),
530 	}, {
531 		.name		= "uart",
532 		.devname	= "s5pv210-uart.3",
533 		.parent		= &clk_pclk_psys.clk,
534 		.enable		= s5pv210_clk_ip3_ctrl,
535 		.ctrlbit	= (1 << 20),
536 	}, {
537 		.name		= "sromc",
538 		.parent		= &clk_hclk_psys.clk,
539 		.enable		= s5pv210_clk_ip1_ctrl,
540 		.ctrlbit	= (1 << 26),
541 	},
542 };
543 
544 static struct clk clk_hsmmc0 = {
545 	.name		= "hsmmc",
546 	.devname	= "s3c-sdhci.0",
547 	.parent		= &clk_hclk_psys.clk,
548 	.enable		= s5pv210_clk_ip2_ctrl,
549 	.ctrlbit	= (1<<16),
550 };
551 
552 static struct clk clk_hsmmc1 = {
553 	.name		= "hsmmc",
554 	.devname	= "s3c-sdhci.1",
555 	.parent		= &clk_hclk_psys.clk,
556 	.enable		= s5pv210_clk_ip2_ctrl,
557 	.ctrlbit	= (1<<17),
558 };
559 
560 static struct clk clk_hsmmc2 = {
561 	.name		= "hsmmc",
562 	.devname	= "s3c-sdhci.2",
563 	.parent		= &clk_hclk_psys.clk,
564 	.enable		= s5pv210_clk_ip2_ctrl,
565 	.ctrlbit	= (1<<18),
566 };
567 
568 static struct clk clk_hsmmc3 = {
569 	.name		= "hsmmc",
570 	.devname	= "s3c-sdhci.3",
571 	.parent		= &clk_hclk_psys.clk,
572 	.enable		= s5pv210_clk_ip2_ctrl,
573 	.ctrlbit	= (1<<19),
574 };
575 
576 static struct clk *clkset_uart_list[] = {
577 	[6] = &clk_mout_mpll.clk,
578 	[7] = &clk_mout_epll.clk,
579 };
580 
581 static struct clksrc_sources clkset_uart = {
582 	.sources	= clkset_uart_list,
583 	.nr_sources	= ARRAY_SIZE(clkset_uart_list),
584 };
585 
586 static struct clk *clkset_group1_list[] = {
587 	[0] = &clk_sclk_a2m.clk,
588 	[1] = &clk_mout_mpll.clk,
589 	[2] = &clk_mout_epll.clk,
590 	[3] = &clk_sclk_vpll.clk,
591 };
592 
593 static struct clksrc_sources clkset_group1 = {
594 	.sources	= clkset_group1_list,
595 	.nr_sources	= ARRAY_SIZE(clkset_group1_list),
596 };
597 
598 static struct clk *clkset_sclk_onenand_list[] = {
599 	[0] = &clk_hclk_psys.clk,
600 	[1] = &clk_hclk_dsys.clk,
601 };
602 
603 static struct clksrc_sources clkset_sclk_onenand = {
604 	.sources	= clkset_sclk_onenand_list,
605 	.nr_sources	= ARRAY_SIZE(clkset_sclk_onenand_list),
606 };
607 
608 static struct clk *clkset_sclk_dac_list[] = {
609 	[0] = &clk_sclk_vpll.clk,
610 	[1] = &clk_sclk_hdmiphy,
611 };
612 
613 static struct clksrc_sources clkset_sclk_dac = {
614 	.sources	= clkset_sclk_dac_list,
615 	.nr_sources	= ARRAY_SIZE(clkset_sclk_dac_list),
616 };
617 
618 static struct clksrc_clk clk_sclk_dac = {
619 	.clk		= {
620 		.name		= "sclk_dac",
621 		.enable		= s5pv210_clk_mask0_ctrl,
622 		.ctrlbit	= (1 << 2),
623 	},
624 	.sources	= &clkset_sclk_dac,
625 	.reg_src	= { .reg = S5P_CLK_SRC1, .shift = 8, .size = 1 },
626 };
627 
628 static struct clksrc_clk clk_sclk_pixel = {
629 	.clk		= {
630 		.name		= "sclk_pixel",
631 		.parent		= &clk_sclk_vpll.clk,
632 	},
633 	.reg_div	= { .reg = S5P_CLK_DIV1, .shift = 0, .size = 4},
634 };
635 
636 static struct clk *clkset_sclk_hdmi_list[] = {
637 	[0] = &clk_sclk_pixel.clk,
638 	[1] = &clk_sclk_hdmiphy,
639 };
640 
641 static struct clksrc_sources clkset_sclk_hdmi = {
642 	.sources	= clkset_sclk_hdmi_list,
643 	.nr_sources	= ARRAY_SIZE(clkset_sclk_hdmi_list),
644 };
645 
646 static struct clksrc_clk clk_sclk_hdmi = {
647 	.clk		= {
648 		.name		= "sclk_hdmi",
649 		.enable		= s5pv210_clk_mask0_ctrl,
650 		.ctrlbit	= (1 << 0),
651 	},
652 	.sources	= &clkset_sclk_hdmi,
653 	.reg_src	= { .reg = S5P_CLK_SRC1, .shift = 0, .size = 1 },
654 };
655 
656 static struct clk *clkset_sclk_mixer_list[] = {
657 	[0] = &clk_sclk_dac.clk,
658 	[1] = &clk_sclk_hdmi.clk,
659 };
660 
661 static struct clksrc_sources clkset_sclk_mixer = {
662 	.sources	= clkset_sclk_mixer_list,
663 	.nr_sources	= ARRAY_SIZE(clkset_sclk_mixer_list),
664 };
665 
666 static struct clksrc_clk clk_sclk_mixer = {
667 	.clk		= {
668 		.name		= "sclk_mixer",
669 		.enable		= s5pv210_clk_mask0_ctrl,
670 		.ctrlbit	= (1 << 1),
671 	},
672 	.sources = &clkset_sclk_mixer,
673 	.reg_src = { .reg = S5P_CLK_SRC1, .shift = 4, .size = 1 },
674 };
675 
676 static struct clksrc_clk *sclk_tv[] = {
677 	&clk_sclk_dac,
678 	&clk_sclk_pixel,
679 	&clk_sclk_hdmi,
680 	&clk_sclk_mixer,
681 };
682 
683 static struct clk *clkset_sclk_audio0_list[] = {
684 	[0] = &clk_ext_xtal_mux,
685 	[1] = &clk_pcmcdclk0,
686 	[2] = &clk_sclk_hdmi27m,
687 	[3] = &clk_sclk_usbphy0,
688 	[4] = &clk_sclk_usbphy1,
689 	[5] = &clk_sclk_hdmiphy,
690 	[6] = &clk_mout_mpll.clk,
691 	[7] = &clk_mout_epll.clk,
692 	[8] = &clk_sclk_vpll.clk,
693 };
694 
695 static struct clksrc_sources clkset_sclk_audio0 = {
696 	.sources	= clkset_sclk_audio0_list,
697 	.nr_sources	= ARRAY_SIZE(clkset_sclk_audio0_list),
698 };
699 
700 static struct clksrc_clk clk_sclk_audio0 = {
701 	.clk		= {
702 		.name		= "sclk_audio",
703 		.devname	= "soc-audio.0",
704 		.enable		= s5pv210_clk_mask0_ctrl,
705 		.ctrlbit	= (1 << 24),
706 	},
707 	.sources = &clkset_sclk_audio0,
708 	.reg_src = { .reg = S5P_CLK_SRC6, .shift = 0, .size = 4 },
709 	.reg_div = { .reg = S5P_CLK_DIV6, .shift = 0, .size = 4 },
710 };
711 
712 static struct clk *clkset_sclk_audio1_list[] = {
713 	[0] = &clk_ext_xtal_mux,
714 	[1] = &clk_pcmcdclk1,
715 	[2] = &clk_sclk_hdmi27m,
716 	[3] = &clk_sclk_usbphy0,
717 	[4] = &clk_sclk_usbphy1,
718 	[5] = &clk_sclk_hdmiphy,
719 	[6] = &clk_mout_mpll.clk,
720 	[7] = &clk_mout_epll.clk,
721 	[8] = &clk_sclk_vpll.clk,
722 };
723 
724 static struct clksrc_sources clkset_sclk_audio1 = {
725 	.sources	= clkset_sclk_audio1_list,
726 	.nr_sources	= ARRAY_SIZE(clkset_sclk_audio1_list),
727 };
728 
729 static struct clksrc_clk clk_sclk_audio1 = {
730 	.clk		= {
731 		.name		= "sclk_audio",
732 		.devname	= "soc-audio.1",
733 		.enable		= s5pv210_clk_mask0_ctrl,
734 		.ctrlbit	= (1 << 25),
735 	},
736 	.sources = &clkset_sclk_audio1,
737 	.reg_src = { .reg = S5P_CLK_SRC6, .shift = 4, .size = 4 },
738 	.reg_div = { .reg = S5P_CLK_DIV6, .shift = 4, .size = 4 },
739 };
740 
741 static struct clk *clkset_sclk_audio2_list[] = {
742 	[0] = &clk_ext_xtal_mux,
743 	[1] = &clk_pcmcdclk0,
744 	[2] = &clk_sclk_hdmi27m,
745 	[3] = &clk_sclk_usbphy0,
746 	[4] = &clk_sclk_usbphy1,
747 	[5] = &clk_sclk_hdmiphy,
748 	[6] = &clk_mout_mpll.clk,
749 	[7] = &clk_mout_epll.clk,
750 	[8] = &clk_sclk_vpll.clk,
751 };
752 
753 static struct clksrc_sources clkset_sclk_audio2 = {
754 	.sources	= clkset_sclk_audio2_list,
755 	.nr_sources	= ARRAY_SIZE(clkset_sclk_audio2_list),
756 };
757 
758 static struct clksrc_clk clk_sclk_audio2 = {
759 	.clk		= {
760 		.name		= "sclk_audio",
761 		.devname	= "soc-audio.2",
762 		.enable		= s5pv210_clk_mask0_ctrl,
763 		.ctrlbit	= (1 << 26),
764 	},
765 	.sources = &clkset_sclk_audio2,
766 	.reg_src = { .reg = S5P_CLK_SRC6, .shift = 8, .size = 4 },
767 	.reg_div = { .reg = S5P_CLK_DIV6, .shift = 8, .size = 4 },
768 };
769 
770 static struct clk *clkset_sclk_spdif_list[] = {
771 	[0] = &clk_sclk_audio0.clk,
772 	[1] = &clk_sclk_audio1.clk,
773 	[2] = &clk_sclk_audio2.clk,
774 };
775 
776 static struct clksrc_sources clkset_sclk_spdif = {
777 	.sources	= clkset_sclk_spdif_list,
778 	.nr_sources	= ARRAY_SIZE(clkset_sclk_spdif_list),
779 };
780 
781 static struct clksrc_clk clk_sclk_spdif = {
782 	.clk		= {
783 		.name		= "sclk_spdif",
784 		.enable		= s5pv210_clk_mask0_ctrl,
785 		.ctrlbit	= (1 << 27),
786 		.ops		= &s5p_sclk_spdif_ops,
787 	},
788 	.sources = &clkset_sclk_spdif,
789 	.reg_src = { .reg = S5P_CLK_SRC6, .shift = 12, .size = 2 },
790 };
791 
792 static struct clk *clkset_group2_list[] = {
793 	[0] = &clk_ext_xtal_mux,
794 	[1] = &clk_xusbxti,
795 	[2] = &clk_sclk_hdmi27m,
796 	[3] = &clk_sclk_usbphy0,
797 	[4] = &clk_sclk_usbphy1,
798 	[5] = &clk_sclk_hdmiphy,
799 	[6] = &clk_mout_mpll.clk,
800 	[7] = &clk_mout_epll.clk,
801 	[8] = &clk_sclk_vpll.clk,
802 };
803 
804 static struct clksrc_sources clkset_group2 = {
805 	.sources	= clkset_group2_list,
806 	.nr_sources	= ARRAY_SIZE(clkset_group2_list),
807 };
808 
809 static struct clksrc_clk clksrcs[] = {
810 	{
811 		.clk	= {
812 			.name		= "sclk_dmc",
813 		},
814 		.sources = &clkset_group1,
815 		.reg_src = { .reg = S5P_CLK_SRC6, .shift = 24, .size = 2 },
816 		.reg_div = { .reg = S5P_CLK_DIV6, .shift = 28, .size = 4 },
817 	}, {
818 		.clk	= {
819 			.name		= "sclk_onenand",
820 		},
821 		.sources = &clkset_sclk_onenand,
822 		.reg_src = { .reg = S5P_CLK_SRC0, .shift = 28, .size = 1 },
823 		.reg_div = { .reg = S5P_CLK_DIV6, .shift = 12, .size = 3 },
824 	}, {
825 		.clk	= {
826 			.name		= "sclk_fimc",
827 			.devname	= "s5pv210-fimc.0",
828 			.enable		= s5pv210_clk_mask1_ctrl,
829 			.ctrlbit	= (1 << 2),
830 		},
831 		.sources = &clkset_group2,
832 		.reg_src = { .reg = S5P_CLK_SRC3, .shift = 12, .size = 4 },
833 		.reg_div = { .reg = S5P_CLK_DIV3, .shift = 12, .size = 4 },
834 	}, {
835 		.clk	= {
836 			.name		= "sclk_fimc",
837 			.devname	= "s5pv210-fimc.1",
838 			.enable		= s5pv210_clk_mask1_ctrl,
839 			.ctrlbit	= (1 << 3),
840 		},
841 		.sources = &clkset_group2,
842 		.reg_src = { .reg = S5P_CLK_SRC3, .shift = 16, .size = 4 },
843 		.reg_div = { .reg = S5P_CLK_DIV3, .shift = 16, .size = 4 },
844 	}, {
845 		.clk	= {
846 			.name		= "sclk_fimc",
847 			.devname	= "s5pv210-fimc.2",
848 			.enable		= s5pv210_clk_mask1_ctrl,
849 			.ctrlbit	= (1 << 4),
850 		},
851 		.sources = &clkset_group2,
852 		.reg_src = { .reg = S5P_CLK_SRC3, .shift = 20, .size = 4 },
853 		.reg_div = { .reg = S5P_CLK_DIV3, .shift = 20, .size = 4 },
854 	}, {
855 		.clk		= {
856 			.name		= "sclk_cam0",
857 			.enable		= s5pv210_clk_mask0_ctrl,
858 			.ctrlbit	= (1 << 3),
859 		},
860 		.sources = &clkset_group2,
861 		.reg_src = { .reg = S5P_CLK_SRC1, .shift = 12, .size = 4 },
862 		.reg_div = { .reg = S5P_CLK_DIV1, .shift = 12, .size = 4 },
863 	}, {
864 		.clk		= {
865 			.name		= "sclk_cam1",
866 			.enable		= s5pv210_clk_mask0_ctrl,
867 			.ctrlbit	= (1 << 4),
868 		},
869 		.sources = &clkset_group2,
870 		.reg_src = { .reg = S5P_CLK_SRC1, .shift = 16, .size = 4 },
871 		.reg_div = { .reg = S5P_CLK_DIV1, .shift = 16, .size = 4 },
872 	}, {
873 		.clk		= {
874 			.name		= "sclk_fimd",
875 			.enable		= s5pv210_clk_mask0_ctrl,
876 			.ctrlbit	= (1 << 5),
877 		},
878 		.sources = &clkset_group2,
879 		.reg_src = { .reg = S5P_CLK_SRC1, .shift = 20, .size = 4 },
880 		.reg_div = { .reg = S5P_CLK_DIV1, .shift = 20, .size = 4 },
881 	}, {
882 		.clk		= {
883 			.name		= "sclk_mfc",
884 			.devname	= "s5p-mfc",
885 			.enable		= s5pv210_clk_ip0_ctrl,
886 			.ctrlbit	= (1 << 16),
887 		},
888 		.sources = &clkset_group1,
889 		.reg_src = { .reg = S5P_CLK_SRC2, .shift = 4, .size = 2 },
890 		.reg_div = { .reg = S5P_CLK_DIV2, .shift = 4, .size = 4 },
891 	}, {
892 		.clk		= {
893 			.name		= "sclk_g2d",
894 			.enable		= s5pv210_clk_ip0_ctrl,
895 			.ctrlbit	= (1 << 12),
896 		},
897 		.sources = &clkset_group1,
898 		.reg_src = { .reg = S5P_CLK_SRC2, .shift = 8, .size = 2 },
899 		.reg_div = { .reg = S5P_CLK_DIV2, .shift = 8, .size = 4 },
900 	}, {
901 		.clk		= {
902 			.name		= "sclk_g3d",
903 			.enable		= s5pv210_clk_ip0_ctrl,
904 			.ctrlbit	= (1 << 8),
905 		},
906 		.sources = &clkset_group1,
907 		.reg_src = { .reg = S5P_CLK_SRC2, .shift = 0, .size = 2 },
908 		.reg_div = { .reg = S5P_CLK_DIV2, .shift = 0, .size = 4 },
909 	}, {
910 		.clk		= {
911 			.name		= "sclk_csis",
912 			.enable		= s5pv210_clk_mask0_ctrl,
913 			.ctrlbit	= (1 << 6),
914 		},
915 		.sources = &clkset_group2,
916 		.reg_src = { .reg = S5P_CLK_SRC1, .shift = 24, .size = 4 },
917 		.reg_div = { .reg = S5P_CLK_DIV1, .shift = 28, .size = 4 },
918 	}, {
919 		.clk		= {
920 			.name		= "sclk_pwi",
921 			.enable		= s5pv210_clk_mask0_ctrl,
922 			.ctrlbit	= (1 << 29),
923 		},
924 		.sources = &clkset_group2,
925 		.reg_src = { .reg = S5P_CLK_SRC6, .shift = 20, .size = 4 },
926 		.reg_div = { .reg = S5P_CLK_DIV6, .shift = 24, .size = 4 },
927 	}, {
928 		.clk		= {
929 			.name		= "sclk_pwm",
930 			.enable		= s5pv210_clk_mask0_ctrl,
931 			.ctrlbit	= (1 << 19),
932 		},
933 		.sources = &clkset_group2,
934 		.reg_src = { .reg = S5P_CLK_SRC5, .shift = 12, .size = 4 },
935 		.reg_div = { .reg = S5P_CLK_DIV5, .shift = 12, .size = 4 },
936 	},
937 };
938 
939 static struct clksrc_clk clk_sclk_uart0 = {
940 	.clk	= {
941 		.name		= "uclk1",
942 		.devname	= "s5pv210-uart.0",
943 		.enable		= s5pv210_clk_mask0_ctrl,
944 		.ctrlbit	= (1 << 12),
945 	},
946 	.sources = &clkset_uart,
947 	.reg_src = { .reg = S5P_CLK_SRC4, .shift = 16, .size = 4 },
948 	.reg_div = { .reg = S5P_CLK_DIV4, .shift = 16, .size = 4 },
949 };
950 
951 static struct clksrc_clk clk_sclk_uart1 = {
952 	.clk		= {
953 		.name		= "uclk1",
954 		.devname	= "s5pv210-uart.1",
955 		.enable		= s5pv210_clk_mask0_ctrl,
956 		.ctrlbit	= (1 << 13),
957 	},
958 	.sources = &clkset_uart,
959 	.reg_src = { .reg = S5P_CLK_SRC4, .shift = 20, .size = 4 },
960 	.reg_div = { .reg = S5P_CLK_DIV4, .shift = 20, .size = 4 },
961 };
962 
963 static struct clksrc_clk clk_sclk_uart2 = {
964 	.clk		= {
965 		.name		= "uclk1",
966 		.devname	= "s5pv210-uart.2",
967 		.enable		= s5pv210_clk_mask0_ctrl,
968 		.ctrlbit	= (1 << 14),
969 	},
970 	.sources = &clkset_uart,
971 	.reg_src = { .reg = S5P_CLK_SRC4, .shift = 24, .size = 4 },
972 	.reg_div = { .reg = S5P_CLK_DIV4, .shift = 24, .size = 4 },
973 };
974 
975 static struct clksrc_clk clk_sclk_uart3	= {
976 	.clk		= {
977 		.name		= "uclk1",
978 		.devname	= "s5pv210-uart.3",
979 		.enable		= s5pv210_clk_mask0_ctrl,
980 		.ctrlbit	= (1 << 15),
981 	},
982 	.sources = &clkset_uart,
983 	.reg_src = { .reg = S5P_CLK_SRC4, .shift = 28, .size = 4 },
984 	.reg_div = { .reg = S5P_CLK_DIV4, .shift = 28, .size = 4 },
985 };
986 
987 static struct clksrc_clk clk_sclk_mmc0 = {
988 	.clk		= {
989 		.name		= "sclk_mmc",
990 		.devname	= "s3c-sdhci.0",
991 		.enable		= s5pv210_clk_mask0_ctrl,
992 		.ctrlbit	= (1 << 8),
993 	},
994 	.sources = &clkset_group2,
995 	.reg_src = { .reg = S5P_CLK_SRC4, .shift = 0, .size = 4 },
996 	.reg_div = { .reg = S5P_CLK_DIV4, .shift = 0, .size = 4 },
997 };
998 
999 static struct clksrc_clk clk_sclk_mmc1 = {
1000 	.clk		= {
1001 		.name		= "sclk_mmc",
1002 		.devname	= "s3c-sdhci.1",
1003 		.enable		= s5pv210_clk_mask0_ctrl,
1004 		.ctrlbit	= (1 << 9),
1005 	},
1006 	.sources = &clkset_group2,
1007 	.reg_src = { .reg = S5P_CLK_SRC4, .shift = 4, .size = 4 },
1008 	.reg_div = { .reg = S5P_CLK_DIV4, .shift = 4, .size = 4 },
1009 };
1010 
1011 static struct clksrc_clk clk_sclk_mmc2 = {
1012 	.clk		= {
1013 		.name		= "sclk_mmc",
1014 		.devname	= "s3c-sdhci.2",
1015 		.enable		= s5pv210_clk_mask0_ctrl,
1016 		.ctrlbit	= (1 << 10),
1017 	},
1018 	.sources = &clkset_group2,
1019 	.reg_src = { .reg = S5P_CLK_SRC4, .shift = 8, .size = 4 },
1020 	.reg_div = { .reg = S5P_CLK_DIV4, .shift = 8, .size = 4 },
1021 };
1022 
1023 static struct clksrc_clk clk_sclk_mmc3 = {
1024 	.clk		= {
1025 		.name		= "sclk_mmc",
1026 		.devname	= "s3c-sdhci.3",
1027 		.enable		= s5pv210_clk_mask0_ctrl,
1028 		.ctrlbit	= (1 << 11),
1029 	},
1030 	.sources = &clkset_group2,
1031 	.reg_src = { .reg = S5P_CLK_SRC4, .shift = 12, .size = 4 },
1032 	.reg_div = { .reg = S5P_CLK_DIV4, .shift = 12, .size = 4 },
1033 };
1034 
1035 static struct clksrc_clk clk_sclk_spi0 = {
1036 	.clk		= {
1037 		.name		= "sclk_spi",
1038 		.devname	= "s3c64xx-spi.0",
1039 		.enable		= s5pv210_clk_mask0_ctrl,
1040 		.ctrlbit	= (1 << 16),
1041 	},
1042 	.sources = &clkset_group2,
1043 	.reg_src = { .reg = S5P_CLK_SRC5, .shift = 0, .size = 4 },
1044 	.reg_div = { .reg = S5P_CLK_DIV5, .shift = 0, .size = 4 },
1045 	};
1046 
1047 static struct clksrc_clk clk_sclk_spi1 = {
1048 	.clk		= {
1049 		.name		= "sclk_spi",
1050 		.devname	= "s3c64xx-spi.1",
1051 		.enable		= s5pv210_clk_mask0_ctrl,
1052 		.ctrlbit	= (1 << 17),
1053 	},
1054 	.sources = &clkset_group2,
1055 	.reg_src = { .reg = S5P_CLK_SRC5, .shift = 4, .size = 4 },
1056 	.reg_div = { .reg = S5P_CLK_DIV5, .shift = 4, .size = 4 },
1057 	};
1058 
1059 
1060 static struct clksrc_clk *clksrc_cdev[] = {
1061 	&clk_sclk_uart0,
1062 	&clk_sclk_uart1,
1063 	&clk_sclk_uart2,
1064 	&clk_sclk_uart3,
1065 	&clk_sclk_mmc0,
1066 	&clk_sclk_mmc1,
1067 	&clk_sclk_mmc2,
1068 	&clk_sclk_mmc3,
1069 	&clk_sclk_spi0,
1070 	&clk_sclk_spi1,
1071 };
1072 
1073 static struct clk *clk_cdev[] = {
1074 	&clk_hsmmc0,
1075 	&clk_hsmmc1,
1076 	&clk_hsmmc2,
1077 	&clk_hsmmc3,
1078 };
1079 
1080 /* Clock initialisation code */
1081 static struct clksrc_clk *sysclks[] = {
1082 	&clk_mout_apll,
1083 	&clk_mout_epll,
1084 	&clk_mout_mpll,
1085 	&clk_armclk,
1086 	&clk_hclk_msys,
1087 	&clk_sclk_a2m,
1088 	&clk_hclk_dsys,
1089 	&clk_hclk_psys,
1090 	&clk_pclk_msys,
1091 	&clk_pclk_dsys,
1092 	&clk_pclk_psys,
1093 	&clk_vpllsrc,
1094 	&clk_sclk_vpll,
1095 	&clk_mout_dmc0,
1096 	&clk_sclk_dmc0,
1097 	&clk_sclk_audio0,
1098 	&clk_sclk_audio1,
1099 	&clk_sclk_audio2,
1100 	&clk_sclk_spdif,
1101 };
1102 
1103 static u32 epll_div[][6] = {
1104 	{  48000000, 0, 48, 3, 3, 0 },
1105 	{  96000000, 0, 48, 3, 2, 0 },
1106 	{ 144000000, 1, 72, 3, 2, 0 },
1107 	{ 192000000, 0, 48, 3, 1, 0 },
1108 	{ 288000000, 1, 72, 3, 1, 0 },
1109 	{  32750000, 1, 65, 3, 4, 35127 },
1110 	{  32768000, 1, 65, 3, 4, 35127 },
1111 	{  45158400, 0, 45, 3, 3, 10355 },
1112 	{  45000000, 0, 45, 3, 3, 10355 },
1113 	{  45158000, 0, 45, 3, 3, 10355 },
1114 	{  49125000, 0, 49, 3, 3, 9961 },
1115 	{  49152000, 0, 49, 3, 3, 9961 },
1116 	{  67737600, 1, 67, 3, 3, 48366 },
1117 	{  67738000, 1, 67, 3, 3, 48366 },
1118 	{  73800000, 1, 73, 3, 3, 47710 },
1119 	{  73728000, 1, 73, 3, 3, 47710 },
1120 	{  36000000, 1, 32, 3, 4, 0 },
1121 	{  60000000, 1, 60, 3, 3, 0 },
1122 	{  72000000, 1, 72, 3, 3, 0 },
1123 	{  80000000, 1, 80, 3, 3, 0 },
1124 	{  84000000, 0, 42, 3, 2, 0 },
1125 	{  50000000, 0, 50, 3, 3, 0 },
1126 };
1127 
s5pv210_epll_set_rate(struct clk * clk,unsigned long rate)1128 static int s5pv210_epll_set_rate(struct clk *clk, unsigned long rate)
1129 {
1130 	unsigned int epll_con, epll_con_k;
1131 	unsigned int i;
1132 
1133 	/* Return if nothing changed */
1134 	if (clk->rate == rate)
1135 		return 0;
1136 
1137 	epll_con = __raw_readl(S5P_EPLL_CON);
1138 	epll_con_k = __raw_readl(S5P_EPLL_CON1);
1139 
1140 	epll_con_k &= ~PLL46XX_KDIV_MASK;
1141 	epll_con &= ~(1 << 27 |
1142 			PLL46XX_MDIV_MASK << PLL46XX_MDIV_SHIFT |
1143 			PLL46XX_PDIV_MASK << PLL46XX_PDIV_SHIFT |
1144 			PLL46XX_SDIV_MASK << PLL46XX_SDIV_SHIFT);
1145 
1146 	for (i = 0; i < ARRAY_SIZE(epll_div); i++) {
1147 		if (epll_div[i][0] == rate) {
1148 			epll_con_k |= epll_div[i][5] << 0;
1149 			epll_con |= (epll_div[i][1] << 27 |
1150 					epll_div[i][2] << PLL46XX_MDIV_SHIFT |
1151 					epll_div[i][3] << PLL46XX_PDIV_SHIFT |
1152 					epll_div[i][4] << PLL46XX_SDIV_SHIFT);
1153 			break;
1154 		}
1155 	}
1156 
1157 	if (i == ARRAY_SIZE(epll_div)) {
1158 		printk(KERN_ERR "%s: Invalid Clock EPLL Frequency\n",
1159 				__func__);
1160 		return -EINVAL;
1161 	}
1162 
1163 	__raw_writel(epll_con, S5P_EPLL_CON);
1164 	__raw_writel(epll_con_k, S5P_EPLL_CON1);
1165 
1166 	printk(KERN_WARNING "EPLL Rate changes from %lu to %lu\n",
1167 			clk->rate, rate);
1168 
1169 	clk->rate = rate;
1170 
1171 	return 0;
1172 }
1173 
1174 static struct clk_ops s5pv210_epll_ops = {
1175 	.set_rate = s5pv210_epll_set_rate,
1176 	.get_rate = s5p_epll_get_rate,
1177 };
1178 
1179 static u32 vpll_div[][5] = {
1180 	{  54000000, 3, 53, 3, 0 },
1181 	{ 108000000, 3, 53, 2, 0 },
1182 };
1183 
s5pv210_vpll_get_rate(struct clk * clk)1184 static unsigned long s5pv210_vpll_get_rate(struct clk *clk)
1185 {
1186 	return clk->rate;
1187 }
1188 
s5pv210_vpll_set_rate(struct clk * clk,unsigned long rate)1189 static int s5pv210_vpll_set_rate(struct clk *clk, unsigned long rate)
1190 {
1191 	unsigned int vpll_con;
1192 	unsigned int i;
1193 
1194 	/* Return if nothing changed */
1195 	if (clk->rate == rate)
1196 		return 0;
1197 
1198 	vpll_con = __raw_readl(S5P_VPLL_CON);
1199 	vpll_con &= ~(0x1 << 27 |					\
1200 			PLL90XX_MDIV_MASK << PLL90XX_MDIV_SHIFT |	\
1201 			PLL90XX_PDIV_MASK << PLL90XX_PDIV_SHIFT |	\
1202 			PLL90XX_SDIV_MASK << PLL90XX_SDIV_SHIFT);
1203 
1204 	for (i = 0; i < ARRAY_SIZE(vpll_div); i++) {
1205 		if (vpll_div[i][0] == rate) {
1206 			vpll_con |= vpll_div[i][1] << PLL90XX_PDIV_SHIFT;
1207 			vpll_con |= vpll_div[i][2] << PLL90XX_MDIV_SHIFT;
1208 			vpll_con |= vpll_div[i][3] << PLL90XX_SDIV_SHIFT;
1209 			vpll_con |= vpll_div[i][4] << 27;
1210 			break;
1211 		}
1212 	}
1213 
1214 	if (i == ARRAY_SIZE(vpll_div)) {
1215 		printk(KERN_ERR "%s: Invalid Clock VPLL Frequency\n",
1216 				__func__);
1217 		return -EINVAL;
1218 	}
1219 
1220 	__raw_writel(vpll_con, S5P_VPLL_CON);
1221 
1222 	/* Wait for VPLL lock */
1223 	while (!(__raw_readl(S5P_VPLL_CON) & (1 << PLL90XX_LOCKED_SHIFT)))
1224 		continue;
1225 
1226 	clk->rate = rate;
1227 	return 0;
1228 }
1229 static struct clk_ops s5pv210_vpll_ops = {
1230 	.get_rate = s5pv210_vpll_get_rate,
1231 	.set_rate = s5pv210_vpll_set_rate,
1232 };
1233 
s5pv210_setup_clocks(void)1234 void __init_or_cpufreq s5pv210_setup_clocks(void)
1235 {
1236 	struct clk *xtal_clk;
1237 	unsigned long vpllsrc;
1238 	unsigned long armclk;
1239 	unsigned long hclk_msys;
1240 	unsigned long hclk_dsys;
1241 	unsigned long hclk_psys;
1242 	unsigned long pclk_msys;
1243 	unsigned long pclk_dsys;
1244 	unsigned long pclk_psys;
1245 	unsigned long apll;
1246 	unsigned long mpll;
1247 	unsigned long epll;
1248 	unsigned long vpll;
1249 	unsigned int ptr;
1250 	u32 clkdiv0, clkdiv1;
1251 
1252 	/* Set functions for clk_fout_epll */
1253 	clk_fout_epll.enable = s5p_epll_enable;
1254 	clk_fout_epll.ops = &s5pv210_epll_ops;
1255 
1256 	printk(KERN_DEBUG "%s: registering clocks\n", __func__);
1257 
1258 	clkdiv0 = __raw_readl(S5P_CLK_DIV0);
1259 	clkdiv1 = __raw_readl(S5P_CLK_DIV1);
1260 
1261 	printk(KERN_DEBUG "%s: clkdiv0 = %08x, clkdiv1 = %08x\n",
1262 				__func__, clkdiv0, clkdiv1);
1263 
1264 	xtal_clk = clk_get(NULL, "xtal");
1265 	BUG_ON(IS_ERR(xtal_clk));
1266 
1267 	xtal = clk_get_rate(xtal_clk);
1268 	clk_put(xtal_clk);
1269 
1270 	printk(KERN_DEBUG "%s: xtal is %ld\n", __func__, xtal);
1271 
1272 	apll = s5p_get_pll45xx(xtal, __raw_readl(S5P_APLL_CON), pll_4508);
1273 	mpll = s5p_get_pll45xx(xtal, __raw_readl(S5P_MPLL_CON), pll_4502);
1274 	epll = s5p_get_pll46xx(xtal, __raw_readl(S5P_EPLL_CON),
1275 				__raw_readl(S5P_EPLL_CON1), pll_4600);
1276 	vpllsrc = clk_get_rate(&clk_vpllsrc.clk);
1277 	vpll = s5p_get_pll45xx(vpllsrc, __raw_readl(S5P_VPLL_CON), pll_4502);
1278 
1279 	clk_fout_apll.ops = &clk_fout_apll_ops;
1280 	clk_fout_mpll.rate = mpll;
1281 	clk_fout_epll.rate = epll;
1282 	clk_fout_vpll.ops = &s5pv210_vpll_ops;
1283 	clk_fout_vpll.rate = vpll;
1284 
1285 	printk(KERN_INFO "S5PV210: PLL settings, A=%ld, M=%ld, E=%ld V=%ld",
1286 			apll, mpll, epll, vpll);
1287 
1288 	armclk = clk_get_rate(&clk_armclk.clk);
1289 	hclk_msys = clk_get_rate(&clk_hclk_msys.clk);
1290 	hclk_dsys = clk_get_rate(&clk_hclk_dsys.clk);
1291 	hclk_psys = clk_get_rate(&clk_hclk_psys.clk);
1292 	pclk_msys = clk_get_rate(&clk_pclk_msys.clk);
1293 	pclk_dsys = clk_get_rate(&clk_pclk_dsys.clk);
1294 	pclk_psys = clk_get_rate(&clk_pclk_psys.clk);
1295 
1296 	printk(KERN_INFO "S5PV210: ARMCLK=%ld, HCLKM=%ld, HCLKD=%ld\n"
1297 			 "HCLKP=%ld, PCLKM=%ld, PCLKD=%ld, PCLKP=%ld\n",
1298 			armclk, hclk_msys, hclk_dsys, hclk_psys,
1299 			pclk_msys, pclk_dsys, pclk_psys);
1300 
1301 	clk_f.rate = armclk;
1302 	clk_h.rate = hclk_psys;
1303 	clk_p.rate = pclk_psys;
1304 
1305 	for (ptr = 0; ptr < ARRAY_SIZE(clksrcs); ptr++)
1306 		s3c_set_clksrc(&clksrcs[ptr], true);
1307 }
1308 
1309 static struct clk *clks[] __initdata = {
1310 	&clk_sclk_hdmi27m,
1311 	&clk_sclk_hdmiphy,
1312 	&clk_sclk_usbphy0,
1313 	&clk_sclk_usbphy1,
1314 	&clk_pcmcdclk0,
1315 	&clk_pcmcdclk1,
1316 	&clk_pcmcdclk2,
1317 };
1318 
1319 static struct clk_lookup s5pv210_clk_lookup[] = {
1320 	CLKDEV_INIT(NULL, "clk_uart_baud0", &clk_p),
1321 	CLKDEV_INIT("s5pv210-uart.0", "clk_uart_baud1", &clk_sclk_uart0.clk),
1322 	CLKDEV_INIT("s5pv210-uart.1", "clk_uart_baud1", &clk_sclk_uart1.clk),
1323 	CLKDEV_INIT("s5pv210-uart.2", "clk_uart_baud1", &clk_sclk_uart2.clk),
1324 	CLKDEV_INIT("s5pv210-uart.3", "clk_uart_baud1", &clk_sclk_uart3.clk),
1325 	CLKDEV_INIT("s3c-sdhci.0", "mmc_busclk.0", &clk_hsmmc0),
1326 	CLKDEV_INIT("s3c-sdhci.1", "mmc_busclk.0", &clk_hsmmc1),
1327 	CLKDEV_INIT("s3c-sdhci.2", "mmc_busclk.0", &clk_hsmmc2),
1328 	CLKDEV_INIT("s3c-sdhci.3", "mmc_busclk.0", &clk_hsmmc3),
1329 	CLKDEV_INIT("s3c-sdhci.0", "mmc_busclk.2", &clk_sclk_mmc0.clk),
1330 	CLKDEV_INIT("s3c-sdhci.1", "mmc_busclk.2", &clk_sclk_mmc1.clk),
1331 	CLKDEV_INIT("s3c-sdhci.2", "mmc_busclk.2", &clk_sclk_mmc2.clk),
1332 	CLKDEV_INIT("s3c-sdhci.3", "mmc_busclk.2", &clk_sclk_mmc3.clk),
1333 	CLKDEV_INIT(NULL, "spi_busclk0", &clk_p),
1334 	CLKDEV_INIT("s3c64xx-spi.0", "spi_busclk1", &clk_sclk_spi0.clk),
1335 	CLKDEV_INIT("s3c64xx-spi.1", "spi_busclk1", &clk_sclk_spi1.clk),
1336 };
1337 
s5pv210_register_clocks(void)1338 void __init s5pv210_register_clocks(void)
1339 {
1340 	int ptr;
1341 
1342 	s3c24xx_register_clocks(clks, ARRAY_SIZE(clks));
1343 
1344 	for (ptr = 0; ptr < ARRAY_SIZE(sysclks); ptr++)
1345 		s3c_register_clksrc(sysclks[ptr], 1);
1346 
1347 	for (ptr = 0; ptr < ARRAY_SIZE(sclk_tv); ptr++)
1348 		s3c_register_clksrc(sclk_tv[ptr], 1);
1349 
1350 	for (ptr = 0; ptr < ARRAY_SIZE(clksrc_cdev); ptr++)
1351 		s3c_register_clksrc(clksrc_cdev[ptr], 1);
1352 
1353 	s3c_register_clksrc(clksrcs, ARRAY_SIZE(clksrcs));
1354 	s3c_register_clocks(init_clocks, ARRAY_SIZE(init_clocks));
1355 
1356 	s3c_register_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off));
1357 	s3c_disable_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off));
1358 	clkdev_add_table(s5pv210_clk_lookup, ARRAY_SIZE(s5pv210_clk_lookup));
1359 
1360 	s3c24xx_register_clocks(clk_cdev, ARRAY_SIZE(clk_cdev));
1361 	for (ptr = 0; ptr < ARRAY_SIZE(clk_cdev); ptr++)
1362 		s3c_disable_clocks(clk_cdev[ptr], 1);
1363 
1364 	s3c24xx_register_clock(&dummy_apb_pclk);
1365 	s3c_pwmclk_init();
1366 }
1367