summaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-mxs/clock-mx28.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2012-01-09 23:39:22 +0100
committerLinus Torvalds <torvalds@linux-foundation.org>2012-01-09 23:39:22 +0100
commit2ac9d7aaccbd598b5bd19ac40761b723bb675442 (patch)
tree09132a44e33798aaa5e80f10bf025b510015cab3 /arch/arm/mach-mxs/clock-mx28.c
parentMerge tag 'devel' of git://git.kernel.org/pub/scm/linux/kernel/git/arm/arm-soc (diff)
parentMerge branch 'samsung/driver' into next/drivers (diff)
downloadlinux-2ac9d7aaccbd598b5bd19ac40761b723bb675442.tar.xz
linux-2ac9d7aaccbd598b5bd19ac40761b723bb675442.zip
Merge tag 'drivers' of git://git.kernel.org/pub/scm/linux/kernel/git/arm/arm-soc
Driver specific changes Again, a lot of platforms have changes in here: pxa, samsung, omap, at91, imx, ... * tag 'drivers' of git://git.kernel.org/pub/scm/linux/kernel/git/arm/arm-soc: (54 commits) ARM: sa1100: clean up of the clock support ARM: pxa: add dummy clock for sa1100-rtc RTC: sa1100: support sa1100, pxa and mmp soc families RTC: sa1100: remove redundant code of setting alarm RTC: sa1100: Clean out ost register Input: zylonite-wm97xx - replace IRQ_GPIO() with gpio_to_irq() pcmcia: pxa: replace IRQ_GPIO() with gpio_to_irq() ARM: EXYNOS: Modified files for SPI consolidation work ARM: S5P64X0: Enable SDHCI support ARM: S5P64X0: Add lookup of sdhci-s3c clocks using generic names ARM: S5P64X0: Add HSMMC setup for host Controller ARM: EXYNOS: Add USB OHCI support to ORIGEN board USB: Add Samsung Exynos OHCI diver ARM: EXYNOS: Add USB OHCI support to SMDKV310 board ARM: EXYNOS: Add USB OHCI device net: macb: fix build break with !CONFIG_OF i2c: tegra: Support DVC controller in device tree i2c: tegra: Add __devinit/exit to probe/remove net/at91_ether: use gpio_is_valid for phy IRQ line ARM: at91/net: add macb ethernet controller in 9g45/9g20 DT ...
Diffstat (limited to 'arch/arm/mach-mxs/clock-mx28.c')
-rw-r--r--arch/arm/mach-mxs/clock-mx28.c38
1 files changed, 38 insertions, 0 deletions
diff --git a/arch/arm/mach-mxs/clock-mx28.c b/arch/arm/mach-mxs/clock-mx28.c
index da6e4aad177c..df0ad3ce234b 100644
--- a/arch/arm/mach-mxs/clock-mx28.c
+++ b/arch/arm/mach-mxs/clock-mx28.c
@@ -22,6 +22,7 @@
#include <linux/io.h>
#include <linux/jiffies.h>
#include <linux/clkdev.h>
+#include <linux/spinlock.h>
#include <asm/clkdev.h>
#include <asm/div64.h>
@@ -29,6 +30,7 @@
#include <mach/mx28.h>
#include <mach/common.h>
#include <mach/clock.h>
+#include <mach/digctl.h>
#include "regs-clkctrl-mx28.h"
@@ -43,6 +45,33 @@ static struct clk emi_clk;
static struct clk saif0_clk;
static struct clk saif1_clk;
static struct clk clk32k_clk;
+static DEFINE_SPINLOCK(clkmux_lock);
+
+/*
+ * HW_SAIF_CLKMUX_SEL:
+ * DIRECT(0x0): SAIF0 clock pins selected for SAIF0 input clocks, and SAIF1
+ * clock pins selected for SAIF1 input clocks.
+ * CROSSINPUT(0x1): SAIF1 clock inputs selected for SAIF0 input clocks, and
+ * SAIF0 clock inputs selected for SAIF1 input clocks.
+ * EXTMSTR0(0x2): SAIF0 clock pin selected for both SAIF0 and SAIF1 input
+ * clocks.
+ * EXTMSTR1(0x3): SAIF1 clock pin selected for both SAIF0 and SAIF1 input
+ * clocks.
+ */
+int mxs_saif_clkmux_select(unsigned int clkmux)
+{
+ if (clkmux > 0x3)
+ return -EINVAL;
+
+ spin_lock(&clkmux_lock);
+ __raw_writel(BM_DIGCTL_CTRL_SAIF_CLKMUX,
+ DIGCTRL_BASE_ADDR + HW_DIGCTL_CTRL + MXS_CLR_ADDR);
+ __raw_writel(clkmux << BP_DIGCTL_CTRL_SAIF_CLKMUX,
+ DIGCTRL_BASE_ADDR + HW_DIGCTL_CTRL + MXS_SET_ADDR);
+ spin_unlock(&clkmux_lock);
+
+ return 0;
+}
static int _raw_clk_enable(struct clk *clk)
{
@@ -785,6 +814,15 @@ int __init mx28_clocks_init(void)
clk_set_parent(&saif0_clk, &pll0_clk);
clk_set_parent(&saif1_clk, &pll0_clk);
+ /*
+ * Set an initial clock rate for the saif internal logic to work
+ * properly. This is important when working in EXTMASTER mode that
+ * uses the other saif's BITCLK&LRCLK but it still needs a basic
+ * clock which should be fast enough for the internal logic.
+ */
+ clk_set_rate(&saif0_clk, 24000000);
+ clk_set_rate(&saif1_clk, 24000000);
+
clkdev_add_table(lookups, ARRAY_SIZE(lookups));
mxs_timer_init(&clk32k_clk, MX28_INT_TIMER0);