summaryrefslogtreecommitdiff
path: root/drivers/clk
diff options
context:
space:
mode:
authorSylwester Nawrocki <s.nawrocki@samsung.com>2013-02-21 21:23:42 +0100
committerChanho Park <chanho61.park@samsung.com>2014-11-18 11:42:48 +0900
commit19c9efc10f1215b1ce5a319e154019ce13e6aec2 (patch)
tree9516f0e5721edacdc969a453ddddd0d460a185bb /drivers/clk
parent508848b0415b521cdf3d0d1a3a98f88b86371c1f (diff)
downloadlinux-3.10-19c9efc10f1215b1ce5a319e154019ce13e6aec2.tar.gz
linux-3.10-19c9efc10f1215b1ce5a319e154019ce13e6aec2.tar.bz2
linux-3.10-19c9efc10f1215b1ce5a319e154019ce13e6aec2.zip
clk: Add Exynos Audio Subsystem clocks driver
TODO: gate clocks. Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com> Signed-off-by: Tomasz Figa <t.figa@samsung.com>
Diffstat (limited to 'drivers/clk')
-rw-r--r--drivers/clk/samsung/Makefile1
-rw-r--r--drivers/clk/samsung/clk-exynos4-audss.c118
-rw-r--r--drivers/clk/samsung/clk-exynos4.c4
3 files changed, 119 insertions, 4 deletions
diff --git a/drivers/clk/samsung/Makefile b/drivers/clk/samsung/Makefile
index b7c232e6742..ec86c3390f7 100644
--- a/drivers/clk/samsung/Makefile
+++ b/drivers/clk/samsung/Makefile
@@ -6,3 +6,4 @@ obj-$(CONFIG_COMMON_CLK) += clk.o clk-pll.o
obj-$(CONFIG_ARCH_EXYNOS4) += clk-exynos4.o
obj-$(CONFIG_SOC_EXYNOS5250) += clk-exynos5250.o
obj-$(CONFIG_SOC_EXYNOS5440) += clk-exynos5440.o
+obj-$(CONFIG_PLAT_SAMSUNG) += clk-exynos4-audss.o
diff --git a/drivers/clk/samsung/clk-exynos4-audss.c b/drivers/clk/samsung/clk-exynos4-audss.c
new file mode 100644
index 00000000000..978c5de30bf
--- /dev/null
+++ b/drivers/clk/samsung/clk-exynos4-audss.c
@@ -0,0 +1,118 @@
+/*
+ * Copyright (c) 2013 Samsung Electronics Co., Ltd.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * Driver for Exynos4 SoC Audio Subsystem clocks.
+*/
+#include <linux/kernel.h>
+#include <linux/clk.h>
+#include <linux/clkdev.h>
+#include <linux/clk-provider.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/syscore_ops.h>
+
+#include "clk.h"
+
+#define AUDSS_CLKSRC 0x00
+#define AUDSS_CLKDIV 0x04
+#define AUDSS_CLKGATE 0x08
+
+/* IP Clock Gate 0 Registers */
+#define EXYNOS_AUDSS_CLKGATE_RP (1 << 0)
+#define EXYNOS_AUDSS_CLKGATE_I2SBUS (1 << 2)
+#define EXYNOS_AUDSS_CLKGATE_I2S_SPEC (1 << 3)
+#define EXYNOS_AUDSS_CLKGATE_PCMBUS (1 << 4)
+#define EXYNOS_AUDSS_CLKGATE_PCM_SPEC (1 << 5)
+#define EXYNOS_AUDSS_CLKGATE_GPIO (1 << 6)
+#define EXYNOS_AUDSS_CLKGATE_UART (1 << 7)
+#define EXYNOS_AUDSS_CLKGATE_TIMER (1 << 8)
+
+#define CLK_MOUT_AUDSS 0
+#define CLK_DOUT_RP 1
+#define CLK_DOUT_AUD_BUS 2
+#define CLK_MOUT_I2S 3
+#define CLK_DOUT_I2SCLK0 4
+#define CLK_I2S0 5
+#define CLK_PCM0 6
+#define AUDSS_CLK_MAX 7
+
+static const char *mux_audss_p[] __initconst = {
+ "xxti", "fout_epll"
+};
+static const char *mux_i2s_p[] __initconst = {
+ "mout_audss", "iiscdclk0", "sclk_audio0"
+};
+
+static struct clk_onecell_data clk_data;
+static void __iomem *io_base;
+static struct clk *clks[AUDSS_CLK_MAX];
+
+static int samsung_audss_clk_suspend(void)
+{
+ /* TODO: */
+ return 0;
+}
+
+static void samsung_audss_clk_resume(void)
+{
+ /* TODO: */
+}
+
+static struct syscore_ops samsung_audss_clk_syscore_ops = {
+ .suspend = samsung_audss_clk_suspend,
+ .resume = samsung_audss_clk_resume,
+};
+
+
+#ifdef CONFIG_OF
+static struct of_device_id audss_of_match[] __initdata = {
+ { .compatible = "samsung,exynos4-audss-clock" },
+ { },
+};
+#endif
+
+static DEFINE_SPINLOCK(audss_clk_lock);
+
+static int samsung_audss_clk_init(void)
+{
+ struct device_node *node;
+
+ node = of_find_matching_node(NULL, audss_of_match);
+ if (!node)
+ return -ENODEV;
+
+ io_base = of_iomap(node, 0);
+ if (WARN_ON(!io_base))
+ return -ENOMEM;
+
+ clks[CLK_MOUT_AUDSS] = clk_register_mux(NULL, "mout_audss",
+ mux_audss_p, ARRAY_SIZE(mux_audss_p), CLK_SET_RATE_PARENT,
+ io_base + AUDSS_CLKSRC, 0, 1, 0, &audss_clk_lock);
+ clks[CLK_MOUT_I2S] = clk_register_mux(NULL, "mout_i2s0",
+ mux_i2s_p, ARRAY_SIZE(mux_i2s_p), CLK_SET_RATE_PARENT,
+ io_base + AUDSS_CLKSRC, 2, 2, 0, &audss_clk_lock);
+
+ clks[CLK_DOUT_RP] = clk_register_divider(NULL, "dout_rp",
+ "mout_audss", CLK_SET_RATE_PARENT, io_base + AUDSS_CLKDIV,
+ 0, 4, 0, &audss_clk_lock);
+ clks[CLK_DOUT_AUD_BUS] = clk_register_divider(NULL, "dout_aud_bus",
+ "dout_rp", CLK_SET_RATE_PARENT, io_base + AUDSS_CLKDIV,
+ 4, 4, 0, &audss_clk_lock);
+ clks[CLK_DOUT_I2SCLK0] = clk_register_divider(NULL, "dout_i2s0",
+ "mout_i2s0", CLK_SET_RATE_PARENT, io_base + AUDSS_CLKDIV,
+ 8, 4, 0, &audss_clk_lock);
+
+ /* TODO: Add gate clocks */
+
+ clk_data.clks = clks;
+ clk_data.clk_num = ARRAY_SIZE(clks);
+ of_clk_add_provider(node, of_clk_src_onecell_get, &clk_data);
+
+ register_syscore_ops(&samsung_audss_clk_syscore_ops);
+ return 0;
+}
+postcore_initcall(samsung_audss_clk_init);
diff --git a/drivers/clk/samsung/clk-exynos4.c b/drivers/clk/samsung/clk-exynos4.c
index c7a7bc7c156..3495237da40 100644
--- a/drivers/clk/samsung/clk-exynos4.c
+++ b/drivers/clk/samsung/clk-exynos4.c
@@ -856,10 +856,6 @@ struct samsung_gate_clock exynos4x12_gate_clks[] __initdata = {
E4X12_GATE_IP_ISP, 3, 0, 0),
GATE_A(wdt, "watchdog", "aclk100",
E4X12_GATE_IP_PERIR, 14, 0, 0, "watchdog"),
- GATE_DA(pcm0, "samsung-pcm.0", "pcm0", "aclk100",
- E4X12_GATE_IP_MAUDIO, 2, 0, 0, "pcm"),
- GATE_DA(i2s0, "samsung-i2s.0", "i2s0", "aclk100",
- E4X12_GATE_IP_MAUDIO, 3, 0, 0, "iis"),
GATE(fimc_isp, "isp", "aclk200", E4X12_GATE_ISP0, 0,
CLK_IGNORE_UNUSED, 0),
GATE(fimc_drc, "drc", "aclk200", E4X12_GATE_ISP0, 1,