1 /* linux/arch/arm/mach-s3c2443/clock.c
3 * Copyright (c) 2007, 2010 Simtec Electronics
4 * Ben Dooks <ben@simtec.co.uk>
6 * S3C2443 Clock control support
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23 #include <linux/init.h>
24 #include <linux/module.h>
25 #include <linux/kernel.h>
26 #include <linux/list.h>
27 #include <linux/errno.h>
28 #include <linux/err.h>
29 #include <linux/sysdev.h>
30 #include <linux/clk.h>
31 #include <linux/mutex.h>
32 #include <linux/serial_core.h>
35 #include <asm/mach/map.h>
37 #include <mach/hardware.h>
39 #include <mach/regs-s3c2443-clock.h>
41 #include <plat/cpu-freq.h>
43 #include <plat/s3c2443.h>
44 #include <plat/clock.h>
45 #include <plat/clock-clksrc.h>
48 /* We currently have to assume that the system is running
49 * from the XTPll input, and that all ***REFCLKs are being
50 * fed from it, as we cannot read the state of OM[4] from
53 * It would be possible for each board initialisation to
54 * set the correct muxing at initialisation
57 static int s3c2443_gate(void __iomem *reg, struct clk *clk, int enable)
59 u32 ctrlbit = clk->ctrlbit;
60 u32 con = __raw_readl(reg);
67 __raw_writel(con, reg);
71 static int s3c2443_clkcon_enable_h(struct clk *clk, int enable)
73 return s3c2443_gate(S3C2443_HCLKCON, clk, enable);
76 static int s3c2443_clkcon_enable_p(struct clk *clk, int enable)
78 return s3c2443_gate(S3C2443_PCLKCON, clk, enable);
81 static int s3c2443_clkcon_enable_s(struct clk *clk, int enable)
83 return s3c2443_gate(S3C2443_SCLKCON, clk, enable);
86 /* s3c2443_roundate_clksrc is close enough to s3c_roundate_clksrc */
88 /* clock selections */
90 static struct clk clk_mpllref = {
97 static struct clk clk_mpll = {
99 .parent = &clk_mpllref,
104 static struct clk clk_i2s_ext = {
109 static struct clk *clk_epllref_sources[] = {
116 static struct clksrc_clk clk_epllref = {
121 .sources = &(struct clksrc_sources) {
122 .sources = clk_epllref_sources,
123 .nr_sources = ARRAY_SIZE(clk_epllref_sources),
125 .reg_src = { .reg = S3C2443_CLKSRC, .size = 2, .shift = 7 },
128 static unsigned long s3c2443_getrate_mdivclk(struct clk *clk)
130 unsigned long parent_rate = clk_get_rate(clk->parent);
131 unsigned long div = __raw_readl(S3C2443_CLKDIV0);
133 div &= S3C2443_CLKDIV0_EXTDIV_MASK;
134 div >>= (S3C2443_CLKDIV0_EXTDIV_SHIFT-1); /* x2 */
136 return parent_rate / (div + 1);
139 static struct clk clk_mdivclk = {
141 .parent = &clk_mpllref,
143 .ops = &(struct clk_ops) {
144 .get_rate = s3c2443_getrate_mdivclk,
148 static struct clk *clk_msysclk_sources[] = {
155 static struct clksrc_clk clk_msysclk = {
161 .sources = &(struct clksrc_sources) {
162 .sources = clk_msysclk_sources,
163 .nr_sources = ARRAY_SIZE(clk_msysclk_sources),
165 .reg_src = { .reg = S3C2443_CLKSRC, .size = 2, .shift = 3 },
170 * this clock is sourced from msysclk and can have a number of
171 * divider values applied to it to then be fed into armclk.
174 static struct clk clk_armdiv = {
177 .parent = &clk_msysclk.clk,
182 * this is the clock fed into the ARM core itself, from armdiv or from hclk.
185 static struct clk *clk_arm_sources[] = {
190 static struct clksrc_clk clk_arm = {
195 .sources = &(struct clksrc_sources) {
196 .sources = clk_arm_sources,
197 .nr_sources = ARRAY_SIZE(clk_arm_sources),
199 .reg_src = { .reg = S3C2443_CLKDIV0, .size = 1, .shift = 13 },
204 * this is sourced from either the EPLL or the EPLLref clock
207 static struct clk *clk_sysclk_sources[] = {
208 [0] = &clk_epllref.clk,
212 static struct clksrc_clk clk_esysclk = {
218 .sources = &(struct clksrc_sources) {
219 .sources = clk_sysclk_sources,
220 .nr_sources = ARRAY_SIZE(clk_sysclk_sources),
222 .reg_src = { .reg = S3C2443_CLKSRC, .size = 1, .shift = 6 },
227 * UART baud-rate clock sourced from esysclk via a divisor
230 static struct clksrc_clk clk_uart = {
234 .parent = &clk_esysclk.clk,
236 .reg_div = { .reg = S3C2443_CLKDIV1, .size = 4, .shift = 8 },
242 * high-speed spi clock, sourced from esysclk
245 static struct clksrc_clk clk_hsspi = {
249 .parent = &clk_esysclk.clk,
250 .ctrlbit = S3C2443_SCLKCON_HSSPICLK,
251 .enable = s3c2443_clkcon_enable_s,
253 .reg_div = { .reg = S3C2443_CLKDIV1, .size = 2, .shift = 4 },
258 * usb host bus-clock, usually 48MHz to provide USB bus clock timing
261 static struct clksrc_clk clk_usb_bus_host = {
263 .name = "usb-bus-host-parent",
265 .parent = &clk_esysclk.clk,
266 .ctrlbit = S3C2443_SCLKCON_USBHOST,
267 .enable = s3c2443_clkcon_enable_s,
269 .reg_div = { .reg = S3C2443_CLKDIV1, .size = 2, .shift = 4 },
274 * this clock is sourced from epll, and is fed through a divider,
275 * to a mux controlled by sclkcon where either it or a extclk can
276 * be fed to the hsmmc block
279 static struct clksrc_clk clk_hsmmc_div = {
283 .parent = &clk_esysclk.clk,
285 .reg_div = { .reg = S3C2443_CLKDIV1, .size = 2, .shift = 6 },
288 static int s3c2443_setparent_hsmmc(struct clk *clk, struct clk *parent)
290 unsigned long clksrc = __raw_readl(S3C2443_SCLKCON);
292 clksrc &= ~(S3C2443_SCLKCON_HSMMCCLK_EXT |
293 S3C2443_SCLKCON_HSMMCCLK_EPLL);
295 if (parent == &clk_epll)
296 clksrc |= S3C2443_SCLKCON_HSMMCCLK_EPLL;
297 else if (parent == &clk_ext)
298 clksrc |= S3C2443_SCLKCON_HSMMCCLK_EXT;
302 if (clk->usage > 0) {
303 __raw_writel(clksrc, S3C2443_SCLKCON);
306 clk->parent = parent;
310 static int s3c2443_enable_hsmmc(struct clk *clk, int enable)
312 return s3c2443_setparent_hsmmc(clk, clk->parent);
315 static struct clk clk_hsmmc = {
318 .parent = &clk_hsmmc_div.clk,
319 .enable = s3c2443_enable_hsmmc,
320 .ops = &(struct clk_ops) {
321 .set_parent = s3c2443_setparent_hsmmc,
327 * This clock is the output from the I2S divisor of ESYSCLK, and is seperate
328 * from the mux that comes after it (cannot merge into one single clock)
331 static struct clksrc_clk clk_i2s_eplldiv = {
333 .name = "i2s-eplldiv",
335 .parent = &clk_esysclk.clk,
337 .reg_div = { .reg = S3C2443_CLKDIV1, .size = 4, .shift = 12, },
342 * i2s bus reference clock, selectable from external, esysclk or epllref
344 * Note, this used to be two clocks, but was compressed into one.
347 struct clk *clk_i2s_srclist[] = {
348 [0] = &clk_i2s_eplldiv.clk,
350 [2] = &clk_epllref.clk,
351 [3] = &clk_epllref.clk,
354 static struct clksrc_clk clk_i2s = {
358 .ctrlbit = S3C2443_SCLKCON_I2SCLK,
359 .enable = s3c2443_clkcon_enable_s,
362 .sources = &(struct clksrc_sources) {
363 .sources = clk_i2s_srclist,
364 .nr_sources = ARRAY_SIZE(clk_i2s_srclist),
366 .reg_src = { .reg = S3C2443_CLKSRC, .size = 2, .shift = 14 },
371 * camera interface bus-clock, divided down from esysclk
374 static struct clksrc_clk clk_cam = {
376 .name = "camif-upll", /* same as 2440 name */
378 .parent = &clk_esysclk.clk,
379 .ctrlbit = S3C2443_SCLKCON_CAMCLK,
380 .enable = s3c2443_clkcon_enable_s,
382 .reg_div = { .reg = S3C2443_CLKDIV1, .size = 4, .shift = 26 },
387 * display interface clock, divided from esysclk
390 static struct clksrc_clk clk_display = {
392 .name = "display-if",
394 .parent = &clk_esysclk.clk,
395 .ctrlbit = S3C2443_SCLKCON_DISPCLK,
396 .enable = s3c2443_clkcon_enable_s,
398 .reg_div = { .reg = S3C2443_CLKDIV1, .size = 8, .shift = 16 },
403 * this divides the msysclk down to pass to h/p/etc.
406 static unsigned long s3c2443_prediv_getrate(struct clk *clk)
408 unsigned long rate = clk_get_rate(clk->parent);
409 unsigned long clkdiv0 = __raw_readl(S3C2443_CLKDIV0);
411 clkdiv0 &= S3C2443_CLKDIV0_PREDIV_MASK;
412 clkdiv0 >>= S3C2443_CLKDIV0_PREDIV_SHIFT;
414 return rate / (clkdiv0 + 1);
417 static struct clk clk_prediv = {
420 .parent = &clk_msysclk.clk,
421 .ops = &(struct clk_ops) {
422 .get_rate = s3c2443_prediv_getrate,
426 /* standard clock definitions */
428 static struct clk init_clocks_disable[] = {
437 .enable = s3c2443_clkcon_enable_p,
438 .ctrlbit = S3C2443_PCLKCON_SDI,
443 .enable = s3c2443_clkcon_enable_p,
444 .ctrlbit = S3C2443_PCLKCON_ADC,
449 .enable = s3c2443_clkcon_enable_p,
450 .ctrlbit = S3C2443_PCLKCON_IIC,
455 .enable = s3c2443_clkcon_enable_p,
456 .ctrlbit = S3C2443_PCLKCON_IIS,
461 .enable = s3c2443_clkcon_enable_p,
462 .ctrlbit = S3C2443_PCLKCON_SPI0,
467 .enable = s3c2443_clkcon_enable_p,
468 .ctrlbit = S3C2443_PCLKCON_SPI1,
472 static struct clk init_clocks[] = {
477 .enable = s3c2443_clkcon_enable_h,
478 .ctrlbit = S3C2443_HCLKCON_DMA0,
483 .enable = s3c2443_clkcon_enable_h,
484 .ctrlbit = S3C2443_HCLKCON_DMA1,
489 .enable = s3c2443_clkcon_enable_h,
490 .ctrlbit = S3C2443_HCLKCON_DMA2,
495 .enable = s3c2443_clkcon_enable_h,
496 .ctrlbit = S3C2443_HCLKCON_DMA3,
501 .enable = s3c2443_clkcon_enable_h,
502 .ctrlbit = S3C2443_HCLKCON_DMA4,
507 .enable = s3c2443_clkcon_enable_h,
508 .ctrlbit = S3C2443_HCLKCON_DMA5,
513 .enable = s3c2443_clkcon_enable_h,
514 .ctrlbit = S3C2443_HCLKCON_LCDC,
519 .enable = s3c2443_clkcon_enable_p,
520 .ctrlbit = S3C2443_PCLKCON_GPIO,
525 .enable = s3c2443_clkcon_enable_h,
526 .ctrlbit = S3C2443_HCLKCON_USBH,
528 .name = "usb-device",
531 .enable = s3c2443_clkcon_enable_h,
532 .ctrlbit = S3C2443_HCLKCON_USBD,
537 .enable = s3c2443_clkcon_enable_h,
538 .ctrlbit = S3C2443_HCLKCON_HSMMC,
543 .enable = s3c2443_clkcon_enable_h,
544 .ctrlbit = S3C2443_HCLKCON_CFC,
549 .enable = s3c2443_clkcon_enable_h,
550 .ctrlbit = S3C2443_HCLKCON_SSMC,
555 .enable = s3c2443_clkcon_enable_p,
556 .ctrlbit = S3C2443_PCLKCON_PWMT,
561 .enable = s3c2443_clkcon_enable_p,
562 .ctrlbit = S3C2443_PCLKCON_UART0,
567 .enable = s3c2443_clkcon_enable_p,
568 .ctrlbit = S3C2443_PCLKCON_UART1,
573 .enable = s3c2443_clkcon_enable_p,
574 .ctrlbit = S3C2443_PCLKCON_UART2,
579 .enable = s3c2443_clkcon_enable_p,
580 .ctrlbit = S3C2443_PCLKCON_UART3,
585 .enable = s3c2443_clkcon_enable_p,
586 .ctrlbit = S3C2443_PCLKCON_RTC,
591 .ctrlbit = S3C2443_PCLKCON_WDT,
593 .name = "usb-bus-host",
595 .parent = &clk_usb_bus_host.clk,
600 .ctrlbit = S3C2443_PCLKCON_AC97,
604 /* clocks to add where we need to check their parentage */
606 static struct clksrc_clk __initdata *init_list[] = {
607 &clk_epllref, /* should be first */
620 static void __init s3c2443_clk_initparents(void)
624 for (ptr = 0; ptr < ARRAY_SIZE(init_list); ptr++)
625 s3c_set_clksrc(init_list[ptr], true);
628 /* armdiv divisor table */
630 static unsigned int armdiv[16] = {
631 [S3C2443_CLKDIV0_ARMDIV_1 >> S3C2443_CLKDIV0_ARMDIV_SHIFT] = 1,
632 [S3C2443_CLKDIV0_ARMDIV_2 >> S3C2443_CLKDIV0_ARMDIV_SHIFT] = 2,
633 [S3C2443_CLKDIV0_ARMDIV_3 >> S3C2443_CLKDIV0_ARMDIV_SHIFT] = 3,
634 [S3C2443_CLKDIV0_ARMDIV_4 >> S3C2443_CLKDIV0_ARMDIV_SHIFT] = 4,
635 [S3C2443_CLKDIV0_ARMDIV_6 >> S3C2443_CLKDIV0_ARMDIV_SHIFT] = 6,
636 [S3C2443_CLKDIV0_ARMDIV_8 >> S3C2443_CLKDIV0_ARMDIV_SHIFT] = 8,
637 [S3C2443_CLKDIV0_ARMDIV_12 >> S3C2443_CLKDIV0_ARMDIV_SHIFT] = 12,
638 [S3C2443_CLKDIV0_ARMDIV_16 >> S3C2443_CLKDIV0_ARMDIV_SHIFT] = 16,
641 static inline unsigned int s3c2443_fclk_div(unsigned long clkcon0)
643 clkcon0 &= S3C2443_CLKDIV0_ARMDIV_MASK;
645 return armdiv[clkcon0 >> S3C2443_CLKDIV0_ARMDIV_SHIFT];
648 static inline unsigned long s3c2443_get_hdiv(unsigned long clkcon0)
650 clkcon0 &= S3C2443_CLKDIV0_HCLKDIV_MASK;
655 /* clocks to add straight away */
657 static struct clksrc_clk *clksrcs[] __initdata = {
672 static struct clk *clks[] __initdata = {
682 void __init_or_cpufreq s3c2443_setup_clocks(void)
684 unsigned long mpllcon = __raw_readl(S3C2443_MPLLCON);
685 unsigned long clkdiv0 = __raw_readl(S3C2443_CLKDIV0);
686 struct clk *xtal_clk;
693 xtal_clk = clk_get(NULL, "xtal");
694 xtal = clk_get_rate(xtal_clk);
697 pll = s3c2443_get_mpll(mpllcon, xtal);
698 clk_msysclk.clk.rate = pll;
700 fclk = pll / s3c2443_fclk_div(clkdiv0);
701 hclk = s3c2443_prediv_getrate(&clk_prediv);
702 hclk /= s3c2443_get_hdiv(clkdiv0);
703 pclk = hclk / ((clkdiv0 & S3C2443_CLKDIV0_HALF_PCLK) ? 2 : 1);
705 s3c24xx_setup_clocks(fclk, hclk, pclk);
707 printk("S3C2443: mpll %s %ld.%03ld MHz, cpu %ld.%03ld MHz, mem %ld.%03ld MHz, pclk %ld.%03ld MHz\n",
708 (mpllcon & S3C2443_PLLCON_OFF) ? "off":"on",
709 print_mhz(pll), print_mhz(fclk),
710 print_mhz(hclk), print_mhz(pclk));
712 s3c24xx_setup_clocks(fclk, hclk, pclk);
715 void __init s3c2443_init_clocks(int xtal)
718 unsigned long epllcon = __raw_readl(S3C2443_EPLLCON);
722 /* s3c2443 parents h and p clocks from prediv */
723 clk_h.parent = &clk_prediv;
724 clk_p.parent = &clk_prediv;
726 s3c24xx_register_baseclocks(xtal);
727 s3c2443_setup_clocks();
728 s3c2443_clk_initparents();
730 for (ptr = 0; ptr < ARRAY_SIZE(clks); ptr++) {
733 ret = s3c24xx_register_clock(clkp);
735 printk(KERN_ERR "Failed to register clock %s (%d)\n",
740 for (ptr = 0; ptr < ARRAY_SIZE(clksrcs); ptr++)
741 s3c_register_clksrc(clksrcs[ptr], 1);
743 clk_epll.rate = s3c2443_get_epll(epllcon, xtal);
744 clk_epll.parent = &clk_epllref.clk;
745 clk_usb_bus.parent = &clk_usb_bus_host.clk;
747 /* ensure usb bus clock is within correct rate of 48MHz */
749 if (clk_get_rate(&clk_usb_bus_host.clk) != (48 * 1000 * 1000)) {
750 printk(KERN_INFO "Warning: USB host bus not at 48MHz\n");
751 clk_set_rate(&clk_usb_bus_host.clk, 48*1000*1000);
754 printk("S3C2443: epll %s %ld.%03ld MHz, usb-bus %ld.%03ld MHz\n",
755 (epllcon & S3C2443_PLLCON_OFF) ? "off":"on",
756 print_mhz(clk_get_rate(&clk_epll)),
757 print_mhz(clk_get_rate(&clk_usb_bus)));
759 /* register clocks from clock array */
761 s3c_register_clocks(init_clocks, ARRAY_SIZE(init_clocks));
763 /* We must be careful disabling the clocks we are not intending to
764 * be using at boot time, as subsystems such as the LCD which do
765 * their own DMA requests to the bus can cause the system to lockup
766 * if they where in the middle of requesting bus access.
768 * Disabling the LCD clock if the LCD is active is very dangerous,
769 * and therefore the bootloader should be careful to not enable
770 * the LCD clock if it is not needed.
773 /* install (and disable) the clocks we do not need immediately */
775 clkp = init_clocks_disable;
776 for (ptr = 0; ptr < ARRAY_SIZE(init_clocks_disable); ptr++, clkp++) {
778 ret = s3c24xx_register_clock(clkp);
780 printk(KERN_ERR "Failed to register clock %s (%d)\n",
784 (clkp->enable)(clkp, 0);