aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm/mach-mxs/clock-mx28.c')
-rw-r--r--arch/arm/mach-mxs/clock-mx28.c76
1 files changed, 62 insertions, 14 deletions
diff --git a/arch/arm/mach-mxs/clock-mx28.c b/arch/arm/mach-mxs/clock-mx28.c
index 5dcc59d5b9ec..5d68e4152220 100644
--- a/arch/arm/mach-mxs/clock-mx28.c
+++ b/arch/arm/mach-mxs/clock-mx28.c
@@ -22,6 +22,7 @@
22#include <linux/io.h> 22#include <linux/io.h>
23#include <linux/jiffies.h> 23#include <linux/jiffies.h>
24#include <linux/clkdev.h> 24#include <linux/clkdev.h>
25#include <linux/spinlock.h>
25 26
26#include <asm/clkdev.h> 27#include <asm/clkdev.h>
27#include <asm/div64.h> 28#include <asm/div64.h>
@@ -29,6 +30,7 @@
29#include <mach/mx28.h> 30#include <mach/mx28.h>
30#include <mach/common.h> 31#include <mach/common.h>
31#include <mach/clock.h> 32#include <mach/clock.h>
33#include <mach/digctl.h>
32 34
33#include "regs-clkctrl-mx28.h" 35#include "regs-clkctrl-mx28.h"
34 36
@@ -43,6 +45,33 @@ static struct clk emi_clk;
43static struct clk saif0_clk; 45static struct clk saif0_clk;
44static struct clk saif1_clk; 46static struct clk saif1_clk;
45static struct clk clk32k_clk; 47static struct clk clk32k_clk;
48static DEFINE_SPINLOCK(clkmux_lock);
49
50/*
51 * HW_SAIF_CLKMUX_SEL:
52 * DIRECT(0x0): SAIF0 clock pins selected for SAIF0 input clocks, and SAIF1
53 * clock pins selected for SAIF1 input clocks.
54 * CROSSINPUT(0x1): SAIF1 clock inputs selected for SAIF0 input clocks, and
55 * SAIF0 clock inputs selected for SAIF1 input clocks.
56 * EXTMSTR0(0x2): SAIF0 clock pin selected for both SAIF0 and SAIF1 input
57 * clocks.
58 * EXTMSTR1(0x3): SAIF1 clock pin selected for both SAIF0 and SAIF1 input
59 * clocks.
60 */
61int mxs_saif_clkmux_select(unsigned int clkmux)
62{
63 if (clkmux > 0x3)
64 return -EINVAL;
65
66 spin_lock(&clkmux_lock);
67 __raw_writel(BM_DIGCTL_CTRL_SAIF_CLKMUX,
68 DIGCTRL_BASE_ADDR + HW_DIGCTL_CTRL + MXS_CLR_ADDR);
69 __raw_writel(clkmux << BP_DIGCTL_CTRL_SAIF_CLKMUX,
70 DIGCTRL_BASE_ADDR + HW_DIGCTL_CTRL + MXS_SET_ADDR);
71 spin_unlock(&clkmux_lock);
72
73 return 0;
74}
46 75
47static int _raw_clk_enable(struct clk *clk) 76static int _raw_clk_enable(struct clk *clk)
48{ 77{
@@ -349,7 +378,7 @@ static int name##_set_rate(struct clk *clk, unsigned long rate) \
349 \ 378 \
350 reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_##fr); \ 379 reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_##fr); \
351 reg &= ~BM_CLKCTRL_##fr##_##fs##FRAC; \ 380 reg &= ~BM_CLKCTRL_##fr##_##fs##FRAC; \
352 reg |= frac; \ 381 reg |= frac << BP_CLKCTRL_##fr##_##fs##FRAC; \
353 __raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_##fr); \ 382 __raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_##fr); \
354 } \ 383 } \
355 \ 384 \
@@ -404,7 +433,7 @@ static int name##_set_rate(struct clk *clk, unsigned long rate) \
404 reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_##dr); \ 433 reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_##dr); \
405 reg &= ~BM_CLKCTRL_##dr##_DIV; \ 434 reg &= ~BM_CLKCTRL_##dr##_DIV; \
406 reg |= div << BP_CLKCTRL_##dr##_DIV; \ 435 reg |= div << BP_CLKCTRL_##dr##_DIV; \
407 if (reg | (1 << clk->enable_shift)) { \ 436 if (reg & (1 << clk->enable_shift)) { \
408 pr_err("%s: clock is gated\n", __func__); \ 437 pr_err("%s: clock is gated\n", __func__); \
409 return -EINVAL; \ 438 return -EINVAL; \
410 } \ 439 } \
@@ -640,6 +669,8 @@ static struct clk_lookup lookups[] = {
640 _REGISTER_CLOCK(NULL, "lradc", lradc_clk) 669 _REGISTER_CLOCK(NULL, "lradc", lradc_clk)
641 _REGISTER_CLOCK(NULL, "spdif", spdif_clk) 670 _REGISTER_CLOCK(NULL, "spdif", spdif_clk)
642 _REGISTER_CLOCK("imx28-fb", NULL, lcdif_clk) 671 _REGISTER_CLOCK("imx28-fb", NULL, lcdif_clk)
672 _REGISTER_CLOCK("mxs-saif.0", NULL, saif0_clk)
673 _REGISTER_CLOCK("mxs-saif.1", NULL, saif1_clk)
643}; 674};
644 675
645static int clk_misc_init(void) 676static int clk_misc_init(void)
@@ -708,11 +739,11 @@ static int clk_misc_init(void)
708 739
709 /* SAIF has to use frac div for functional operation */ 740 /* SAIF has to use frac div for functional operation */
710 reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_SAIF0); 741 reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_SAIF0);
711 reg &= ~BM_CLKCTRL_SAIF0_DIV_FRAC_EN; 742 reg |= BM_CLKCTRL_SAIF0_DIV_FRAC_EN;
712 __raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_SAIF0); 743 __raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_SAIF0);
713 744
714 reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_SAIF1); 745 reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_SAIF1);
715 reg &= ~BM_CLKCTRL_SAIF1_DIV_FRAC_EN; 746 reg |= BM_CLKCTRL_SAIF1_DIV_FRAC_EN;
716 __raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_SAIF1); 747 __raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_SAIF1);
717 748
718 /* 749 /*
@@ -738,11 +769,17 @@ static int clk_misc_init(void)
738 __raw_writel(BM_CLKCTRL_CPU_INTERRUPT_WAIT, 769 __raw_writel(BM_CLKCTRL_CPU_INTERRUPT_WAIT,
739 CLKCTRL_BASE_ADDR + HW_CLKCTRL_CPU_SET); 770 CLKCTRL_BASE_ADDR + HW_CLKCTRL_CPU_SET);
740 771
741 /* Extra fec clock setting */ 772 /*
742 reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_ENET); 773 * Extra fec clock setting
743 reg &= ~BM_CLKCTRL_ENET_SLEEP; 774 * The DENX M28 uses an external clock source
744 reg |= BM_CLKCTRL_ENET_CLK_OUT_EN; 775 * and the clock output must not be enabled
745 __raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_ENET); 776 */
777 if (!machine_is_m28evk()) {
778 reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_ENET);
779 reg &= ~BM_CLKCTRL_ENET_SLEEP;
780 reg |= BM_CLKCTRL_ENET_CLK_OUT_EN;
781 __raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_ENET);
782 }
746 783
747 /* 784 /*
748 * 480 MHz seems too high to be ssp clock source directly, 785 * 480 MHz seems too high to be ssp clock source directly,
@@ -767,13 +804,24 @@ int __init mx28_clocks_init(void)
767 clk_set_parent(&ssp0_clk, &ref_io0_clk); 804 clk_set_parent(&ssp0_clk, &ref_io0_clk);
768 clk_set_parent(&ssp1_clk, &ref_io0_clk); 805 clk_set_parent(&ssp1_clk, &ref_io0_clk);
769 806
770 clk_enable(&cpu_clk); 807 clk_prepare_enable(&cpu_clk);
771 clk_enable(&hbus_clk); 808 clk_prepare_enable(&hbus_clk);
772 clk_enable(&xbus_clk); 809 clk_prepare_enable(&xbus_clk);
773 clk_enable(&emi_clk); 810 clk_prepare_enable(&emi_clk);
774 clk_enable(&uart_clk); 811 clk_prepare_enable(&uart_clk);
775 812
776 clk_set_parent(&lcdif_clk, &ref_pix_clk); 813 clk_set_parent(&lcdif_clk, &ref_pix_clk);
814 clk_set_parent(&saif0_clk, &pll0_clk);
815 clk_set_parent(&saif1_clk, &pll0_clk);
816
817 /*
818 * Set an initial clock rate for the saif internal logic to work
819 * properly. This is important when working in EXTMASTER mode that
820 * uses the other saif's BITCLK&LRCLK but it still needs a basic
821 * clock which should be fast enough for the internal logic.
822 */
823 clk_set_rate(&saif0_clk, 24000000);
824 clk_set_rate(&saif1_clk, 24000000);
777 825
778 clkdev_add_table(lookups, ARRAY_SIZE(lookups)); 826 clkdev_add_table(lookups, ARRAY_SIZE(lookups));
779 827