diff options
author | Sylwester Nawrocki <s.nawrocki@samsung.com> | 2013-02-21 21:23:42 +0100 |
---|---|---|
committer | Chanho Park <chanho61.park@samsung.com> | 2014-11-18 11:42:48 +0900 |
commit | 19c9efc10f1215b1ce5a319e154019ce13e6aec2 (patch) | |
tree | 9516f0e5721edacdc969a453ddddd0d460a185bb /drivers/clk | |
parent | 508848b0415b521cdf3d0d1a3a98f88b86371c1f (diff) | |
download | linux-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/Makefile | 1 | ||||
-rw-r--r-- | drivers/clk/samsung/clk-exynos4-audss.c | 118 | ||||
-rw-r--r-- | drivers/clk/samsung/clk-exynos4.c | 4 |
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, |