From 721c42a351b113a9633d2447d9131fe620f2d805 Mon Sep 17 00:00:00 2001 From: Thomas Abraham Date: Sat, 9 Mar 2013 17:02:44 +0900 Subject: clk: samsung: add common clock framework helper functions for Samsung platforms All Samsung platforms include different types of clock including fixed-rate, mux, divider and gate clock types. There are typically hundreds of such clocks on each of the Samsung platforms. To enable Samsung platforms to register these clocks using the common clock framework, a bunch of utility functions are introduced here which simplify the clock registration process. The clocks are usually statically instantiated and registered with common clock framework. Reviewed-by: Sylwester Nawrocki Tested-by: Sylwester Nawrocki Reviewed-by: Tomasz Figa Tested-by: Tomasz Figa Tested-by: Heiko Stuebner Signed-off-by: Thomas Abraham Acked-by: Mike Turquette Signed-off-by: Kukjin Kim --- drivers/clk/Makefile | 1 + drivers/clk/samsung/Makefile | 5 + drivers/clk/samsung/clk.c | 273 +++++++++++++++++++++++++++++++++++++++++++ drivers/clk/samsung/clk.h | 262 +++++++++++++++++++++++++++++++++++++++++ 4 files changed, 541 insertions(+) create mode 100644 drivers/clk/samsung/Makefile create mode 100644 drivers/clk/samsung/clk.c create mode 100644 drivers/clk/samsung/clk.h (limited to 'drivers/clk') diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile index 300d4775d926..0147022b9813 100644 --- a/drivers/clk/Makefile +++ b/drivers/clk/Makefile @@ -27,6 +27,7 @@ obj-$(CONFIG_ARCH_U8500) += ux500/ obj-$(CONFIG_ARCH_VT8500) += clk-vt8500.o obj-$(CONFIG_ARCH_ZYNQ) += clk-zynq.o obj-$(CONFIG_ARCH_TEGRA) += tegra/ +obj-$(CONFIG_PLAT_SAMSUNG) += samsung/ obj-$(CONFIG_X86) += x86/ diff --git a/drivers/clk/samsung/Makefile b/drivers/clk/samsung/Makefile new file mode 100644 index 000000000000..bd920b43f6e7 --- /dev/null +++ b/drivers/clk/samsung/Makefile @@ -0,0 +1,5 @@ +# +# Samsung Clock specific Makefile +# + +obj-$(CONFIG_COMMON_CLK) += clk.o diff --git a/drivers/clk/samsung/clk.c b/drivers/clk/samsung/clk.c new file mode 100644 index 000000000000..91d12f397f5d --- /dev/null +++ b/drivers/clk/samsung/clk.c @@ -0,0 +1,273 @@ +/* + * Copyright (c) 2013 Samsung Electronics Co., Ltd. + * Copyright (c) 2013 Linaro Ltd. + * Author: Thomas Abraham + * + * 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. + * + * This file includes utility functions to register clocks to common + * clock framework for Samsung platforms. +*/ + +#include +#include "clk.h" + +static DEFINE_SPINLOCK(lock); +static struct clk **clk_table; +static void __iomem *reg_base; +#ifdef CONFIG_OF +static struct clk_onecell_data clk_data; +#endif + +#ifdef CONFIG_PM_SLEEP +static struct samsung_clk_reg_dump *reg_dump; +static unsigned long nr_reg_dump; + +static int samsung_clk_suspend(void) +{ + struct samsung_clk_reg_dump *rd = reg_dump; + unsigned long i; + + for (i = 0; i < nr_reg_dump; i++, rd++) + rd->value = __raw_readl(reg_base + rd->offset); + + return 0; +} + +static void samsung_clk_resume(void) +{ + struct samsung_clk_reg_dump *rd = reg_dump; + unsigned long i; + + for (i = 0; i < nr_reg_dump; i++, rd++) + __raw_writel(rd->value, reg_base + rd->offset); +} + +static struct syscore_ops samsung_clk_syscore_ops = { + .suspend = samsung_clk_suspend, + .resume = samsung_clk_resume, +}; +#endif /* CONFIG_PM_SLEEP */ + +/* setup the essentials required to support clock lookup using ccf */ +void __init samsung_clk_init(struct device_node *np, void __iomem *base, + unsigned long nr_clks, unsigned long *rdump, + unsigned long nr_rdump) +{ + reg_base = base; + if (!np) + return; + +#ifdef CONFIG_OF + clk_table = kzalloc(sizeof(struct clk *) * nr_clks, GFP_KERNEL); + if (!clk_table) + panic("could not allocate clock lookup table\n"); + + clk_data.clks = clk_table; + clk_data.clk_num = nr_clks; + of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data); +#endif + +#ifdef CONFIG_PM_SLEEP + if (rdump && nr_rdump) { + unsigned int idx; + reg_dump = kzalloc(sizeof(struct samsung_clk_reg_dump) + * nr_rdump, GFP_KERNEL); + if (!reg_dump) { + pr_err("%s: memory alloc for register dump failed\n", + __func__); + return; + } + + for (idx = 0; idx < nr_rdump; idx++) + reg_dump[idx].offset = rdump[idx]; + nr_reg_dump = nr_rdump; + register_syscore_ops(&samsung_clk_syscore_ops); + } +#endif +} + +/* add a clock instance to the clock lookup table used for dt based lookup */ +void samsung_clk_add_lookup(struct clk *clk, unsigned int id) +{ + if (clk_table && id) + clk_table[id] = clk; +} + +/* register a list of fixed clocks */ +void __init samsung_clk_register_fixed_rate( + struct samsung_fixed_rate_clock *list, unsigned int nr_clk) +{ + struct clk *clk; + unsigned int idx, ret; + + for (idx = 0; idx < nr_clk; idx++, list++) { + clk = clk_register_fixed_rate(NULL, list->name, + list->parent_name, list->flags, list->fixed_rate); + if (IS_ERR(clk)) { + pr_err("%s: failed to register clock %s\n", __func__, + list->name); + continue; + } + + samsung_clk_add_lookup(clk, list->id); + + /* + * Unconditionally add a clock lookup for the fixed rate clocks. + * There are not many of these on any of Samsung platforms. + */ + ret = clk_register_clkdev(clk, list->name, NULL); + if (ret) + pr_err("%s: failed to register clock lookup for %s", + __func__, list->name); + } +} + +/* register a list of fixed factor clocks */ +void __init samsung_clk_register_fixed_factor( + struct samsung_fixed_factor_clock *list, unsigned int nr_clk) +{ + struct clk *clk; + unsigned int idx; + + for (idx = 0; idx < nr_clk; idx++, list++) { + clk = clk_register_fixed_factor(NULL, list->name, + list->parent_name, list->flags, list->mult, list->div); + if (IS_ERR(clk)) { + pr_err("%s: failed to register clock %s\n", __func__, + list->name); + continue; + } + + samsung_clk_add_lookup(clk, list->id); + } +} + +/* register a list of mux clocks */ +void __init samsung_clk_register_mux(struct samsung_mux_clock *list, + unsigned int nr_clk) +{ + struct clk *clk; + unsigned int idx, ret; + + for (idx = 0; idx < nr_clk; idx++, list++) { + clk = clk_register_mux(NULL, list->name, list->parent_names, + list->num_parents, list->flags, reg_base + list->offset, + list->shift, list->width, list->mux_flags, &lock); + if (IS_ERR(clk)) { + pr_err("%s: failed to register clock %s\n", __func__, + list->name); + continue; + } + + samsung_clk_add_lookup(clk, list->id); + + /* register a clock lookup only if a clock alias is specified */ + if (list->alias) { + ret = clk_register_clkdev(clk, list->alias, + list->dev_name); + if (ret) + pr_err("%s: failed to register lookup %s\n", + __func__, list->alias); + } + } +} + +/* register a list of div clocks */ +void __init samsung_clk_register_div(struct samsung_div_clock *list, + unsigned int nr_clk) +{ + struct clk *clk; + unsigned int idx, ret; + + for (idx = 0; idx < nr_clk; idx++, list++) { + clk = clk_register_divider(NULL, list->name, list->parent_name, + list->flags, reg_base + list->offset, list->shift, + list->width, list->div_flags, &lock); + if (IS_ERR(clk)) { + pr_err("%s: failed to register clock %s\n", __func__, + list->name); + continue; + } + + samsung_clk_add_lookup(clk, list->id); + + /* register a clock lookup only if a clock alias is specified */ + if (list->alias) { + ret = clk_register_clkdev(clk, list->alias, + list->dev_name); + if (ret) + pr_err("%s: failed to register lookup %s\n", + __func__, list->alias); + } + } +} + +/* register a list of gate clocks */ +void __init samsung_clk_register_gate(struct samsung_gate_clock *list, + unsigned int nr_clk) +{ + struct clk *clk; + unsigned int idx, ret; + + for (idx = 0; idx < nr_clk; idx++, list++) { + clk = clk_register_gate(NULL, list->name, list->parent_name, + list->flags, reg_base + list->offset, + list->bit_idx, list->gate_flags, &lock); + if (IS_ERR(clk)) { + pr_err("%s: failed to register clock %s\n", __func__, + list->name); + continue; + } + + /* register a clock lookup only if a clock alias is specified */ + if (list->alias) { + ret = clk_register_clkdev(clk, list->alias, + list->dev_name); + if (ret) + pr_err("%s: failed to register lookup %s\n", + __func__, list->alias); + } + + samsung_clk_add_lookup(clk, list->id); + } +} + +/* + * obtain the clock speed of all external fixed clock sources from device + * tree and register it + */ +void __init samsung_clk_of_register_fixed_ext( + struct samsung_fixed_rate_clock *fixed_rate_clk, + unsigned int nr_fixed_rate_clk, + struct of_device_id *clk_matches) +{ + const struct of_device_id *match; + struct device_node *np; + u32 freq; + + for_each_matching_node_and_match(np, clk_matches, &match) { + if (of_property_read_u32(np, "clock-frequency", &freq)) + continue; + fixed_rate_clk[(u32)match->data].fixed_rate = freq; + } + samsung_clk_register_fixed_rate(fixed_rate_clk, nr_fixed_rate_clk); +} + +/* utility function to get the rate of a specified clock */ +unsigned long _get_rate(const char *clk_name) +{ + struct clk *clk; + unsigned long rate; + + clk = clk_get(NULL, clk_name); + if (IS_ERR(clk)) { + pr_err("%s: could not find clock %s\n", __func__, clk_name); + return 0; + } + rate = clk_get_rate(clk); + clk_put(clk); + return rate; +} diff --git a/drivers/clk/samsung/clk.h b/drivers/clk/samsung/clk.h new file mode 100644 index 000000000000..961192ffd696 --- /dev/null +++ b/drivers/clk/samsung/clk.h @@ -0,0 +1,262 @@ +/* + * Copyright (c) 2013 Samsung Electronics Co., Ltd. + * Copyright (c) 2013 Linaro Ltd. + * Author: Thomas Abraham + * + * 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. + * + * Common Clock Framework support for all Samsung platforms +*/ + +#ifndef __SAMSUNG_CLK_H +#define __SAMSUNG_CLK_H + +#include +#include +#include +#include +#include +#include + +#include + +/** + * struct samsung_fixed_rate_clock: information about fixed-rate clock + * @id: platform specific id of the clock. + * @name: name of this fixed-rate clock. + * @parent_name: optional parent clock name. + * @flags: optional fixed-rate clock flags. + * @fixed-rate: fixed clock rate of this clock. + */ +struct samsung_fixed_rate_clock { + unsigned int id; + char *name; + const char *parent_name; + unsigned long flags; + unsigned long fixed_rate; +}; + +#define FRATE(_id, cname, pname, f, frate) \ + { \ + .id = _id, \ + .name = cname, \ + .parent_name = pname, \ + .flags = f, \ + .fixed_rate = frate, \ + } + +/* + * struct samsung_fixed_factor_clock: information about fixed-factor clock + * @id: platform specific id of the clock. + * @name: name of this fixed-factor clock. + * @parent_name: parent clock name. + * @mult: fixed multiplication factor. + * @div: fixed division factor. + * @flags: optional fixed-factor clock flags. + */ +struct samsung_fixed_factor_clock { + unsigned int id; + char *name; + const char *parent_name; + unsigned long mult; + unsigned long div; + unsigned long flags; +}; + +#define FFACTOR(_id, cname, pname, m, d, f) \ + { \ + .id = _id, \ + .name = cname, \ + .parent_name = pname, \ + .mult = m, \ + .div = d, \ + .flags = f, \ + } + +/** + * struct samsung_mux_clock: information about mux clock + * @id: platform specific id of the clock. + * @dev_name: name of the device to which this clock belongs. + * @name: name of this mux clock. + * @parent_names: array of pointer to parent clock names. + * @num_parents: number of parents listed in @parent_names. + * @flags: optional flags for basic clock. + * @offset: offset of the register for configuring the mux. + * @shift: starting bit location of the mux control bit-field in @reg. + * @width: width of the mux control bit-field in @reg. + * @mux_flags: flags for mux-type clock. + * @alias: optional clock alias name to be assigned to this clock. + */ +struct samsung_mux_clock { + unsigned int id; + const char *dev_name; + const char *name; + const char **parent_names; + u8 num_parents; + unsigned long flags; + unsigned long offset; + u8 shift; + u8 width; + u8 mux_flags; + const char *alias; +}; + +#define __MUX(_id, dname, cname, pnames, o, s, w, f, mf, a) \ + { \ + .id = _id, \ + .dev_name = dname, \ + .name = cname, \ + .parent_names = pnames, \ + .num_parents = ARRAY_SIZE(pnames), \ + .flags = f, \ + .offset = o, \ + .shift = s, \ + .width = w, \ + .mux_flags = mf, \ + .alias = a, \ + } + +#define MUX(_id, cname, pnames, o, s, w) \ + __MUX(_id, NULL, cname, pnames, o, s, w, 0, 0, NULL) + +#define MUX_A(_id, cname, pnames, o, s, w, a) \ + __MUX(_id, NULL, cname, pnames, o, s, w, 0, 0, a) + +#define MUX_F(_id, cname, pnames, o, s, w, f, mf) \ + __MUX(_id, NULL, cname, pnames, o, s, w, f, mf, NULL) + +/** + * @id: platform specific id of the clock. + * struct samsung_div_clock: information about div clock + * @dev_name: name of the device to which this clock belongs. + * @name: name of this div clock. + * @parent_name: name of the parent clock. + * @flags: optional flags for basic clock. + * @offset: offset of the register for configuring the div. + * @shift: starting bit location of the div control bit-field in @reg. + * @div_flags: flags for div-type clock. + * @alias: optional clock alias name to be assigned to this clock. + */ +struct samsung_div_clock { + unsigned int id; + const char *dev_name; + const char *name; + const char *parent_name; + unsigned long flags; + unsigned long offset; + u8 shift; + u8 width; + u8 div_flags; + const char *alias; +}; + +#define __DIV(_id, dname, cname, pname, o, s, w, f, df, a) \ + { \ + .id = _id, \ + .dev_name = dname, \ + .name = cname, \ + .parent_name = pname, \ + .flags = f, \ + .offset = o, \ + .shift = s, \ + .width = w, \ + .div_flags = df, \ + .alias = a, \ + } + +#define DIV(_id, cname, pname, o, s, w) \ + __DIV(_id, NULL, cname, pname, o, s, w, 0, 0, NULL) + +#define DIV_A(_id, cname, pname, o, s, w, a) \ + __DIV(_id, NULL, cname, pname, o, s, w, 0, 0, a) + +#define DIV_F(_id, cname, pname, o, s, w, f, df) \ + __DIV(_id, NULL, cname, pname, o, s, w, f, df, NULL) + +/** + * struct samsung_gate_clock: information about gate clock + * @id: platform specific id of the clock. + * @dev_name: name of the device to which this clock belongs. + * @name: name of this gate clock. + * @parent_name: name of the parent clock. + * @flags: optional flags for basic clock. + * @offset: offset of the register for configuring the gate. + * @bit_idx: bit index of the gate control bit-field in @reg. + * @gate_flags: flags for gate-type clock. + * @alias: optional clock alias name to be assigned to this clock. + */ +struct samsung_gate_clock { + unsigned int id; + const char *dev_name; + const char *name; + const char *parent_name; + unsigned long flags; + unsigned long offset; + u8 bit_idx; + u8 gate_flags; + const char *alias; +}; + +#define __GATE(_id, dname, cname, pname, o, b, f, gf, a) \ + { \ + .id = _id, \ + .dev_name = dname, \ + .name = cname, \ + .parent_name = pname, \ + .flags = f, \ + .offset = o, \ + .bit_idx = b, \ + .gate_flags = gf, \ + .alias = a, \ + } + +#define GATE(_id, cname, pname, o, b, f, gf) \ + __GATE(_id, NULL, cname, pname, o, b, f, gf, NULL) + +#define GATE_A(_id, cname, pname, o, b, f, gf, a) \ + __GATE(_id, NULL, cname, pname, o, b, f, gf, a) + +#define GATE_D(_id, dname, cname, pname, o, b, f, gf) \ + __GATE(_id, dname, cname, pname, o, b, f, gf, NULL) + +#define GATE_DA(_id, dname, cname, pname, o, b, f, gf, a) \ + __GATE(_id, dname, cname, pname, o, b, f, gf, a) + +#define PNAME(x) static const char *x[] __initdata + +/** + * struct samsung_clk_reg_dump: register dump of clock controller registers. + * @offset: clock register offset from the controller base address. + * @value: the value to be register at offset. + */ +struct samsung_clk_reg_dump { + u32 offset; + u32 value; +}; + +extern void __init samsung_clk_init(struct device_node *np, void __iomem *base, + unsigned long nr_clks, unsigned long *rdump, + unsigned long nr_rdump); +extern void __init samsung_clk_of_register_fixed_ext( + struct samsung_fixed_rate_clock *fixed_rate_clk, + unsigned int nr_fixed_rate_clk, + struct of_device_id *clk_matches); + +extern void samsung_clk_add_lookup(struct clk *clk, unsigned int id); + +extern void __init samsung_clk_register_fixed_rate( + struct samsung_fixed_rate_clock *clk_list, unsigned int nr_clk); +extern void __init samsung_clk_register_fixed_factor( + struct samsung_fixed_factor_clock *list, unsigned int nr_clk); +extern void __init samsung_clk_register_mux(struct samsung_mux_clock *clk_list, + unsigned int nr_clk); +extern void __init samsung_clk_register_div(struct samsung_div_clock *clk_list, + unsigned int nr_clk); +extern void __init samsung_clk_register_gate( + struct samsung_gate_clock *clk_list, unsigned int nr_clk); + +extern unsigned long _get_rate(const char *clk_name); + +#endif /* __SAMSUNG_CLK_H */ -- cgit v1.2.3 From 1c4c5fe0b787ab02bf7c01b091e82e8d09ee1d64 Mon Sep 17 00:00:00 2001 From: Thomas Abraham Date: Sat, 9 Mar 2013 17:02:48 +0900 Subject: clk: samsung: add pll clock registration helper functions There are several types of pll clocks used in Samsung SoC's and these pll clocks can be represented as Samsung specific pll clock types and registered with the common clock framework. Add support for pll35xx, pll36xx, pll45xx, pll46xx and pll2550x clock types and helper functions to register them. Reviewed-by: Sylwester Nawrocki Tested-by: Sylwester Nawrocki Reviewed-by: Tomasz Figa Tested-by: Tomasz Figa Signed-off-by: Thomas Abraham Acked-by: Mike Turquette Signed-off-by: Kukjin Kim --- drivers/clk/samsung/Makefile | 2 +- drivers/clk/samsung/clk-pll.c | 499 ++++++++++++++++++++++++++++++++++++++++++ drivers/clk/samsung/clk-pll.h | 41 ++++ 3 files changed, 541 insertions(+), 1 deletion(-) create mode 100644 drivers/clk/samsung/clk-pll.c create mode 100644 drivers/clk/samsung/clk-pll.h (limited to 'drivers/clk') diff --git a/drivers/clk/samsung/Makefile b/drivers/clk/samsung/Makefile index bd920b43f6e7..78e5aaa55b40 100644 --- a/drivers/clk/samsung/Makefile +++ b/drivers/clk/samsung/Makefile @@ -2,4 +2,4 @@ # Samsung Clock specific Makefile # -obj-$(CONFIG_COMMON_CLK) += clk.o +obj-$(CONFIG_COMMON_CLK) += clk.o clk-pll.o diff --git a/drivers/clk/samsung/clk-pll.c b/drivers/clk/samsung/clk-pll.c new file mode 100644 index 000000000000..4b2451129d44 --- /dev/null +++ b/drivers/clk/samsung/clk-pll.c @@ -0,0 +1,499 @@ +/* + * Copyright (c) 2013 Samsung Electronics Co., Ltd. + * Copyright (c) 2013 Linaro 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. + * + * This file contains the utility functions to register the pll clocks. +*/ + +#include +#include "clk.h" +#include "clk-pll.h" + +/* + * PLL35xx Clock Type + */ + +#define PLL35XX_MDIV_MASK (0x3FF) +#define PLL35XX_PDIV_MASK (0x3F) +#define PLL35XX_SDIV_MASK (0x7) +#define PLL35XX_MDIV_SHIFT (16) +#define PLL35XX_PDIV_SHIFT (8) +#define PLL35XX_SDIV_SHIFT (0) + +struct samsung_clk_pll35xx { + struct clk_hw hw; + const void __iomem *con_reg; +}; + +#define to_clk_pll35xx(_hw) container_of(_hw, struct samsung_clk_pll35xx, hw) + +static unsigned long samsung_pll35xx_recalc_rate(struct clk_hw *hw, + unsigned long parent_rate) +{ + struct samsung_clk_pll35xx *pll = to_clk_pll35xx(hw); + u32 mdiv, pdiv, sdiv, pll_con; + u64 fvco = parent_rate; + + pll_con = __raw_readl(pll->con_reg); + mdiv = (pll_con >> PLL35XX_MDIV_SHIFT) & PLL35XX_MDIV_MASK; + pdiv = (pll_con >> PLL35XX_PDIV_SHIFT) & PLL35XX_PDIV_MASK; + sdiv = (pll_con >> PLL35XX_SDIV_SHIFT) & PLL35XX_SDIV_MASK; + + fvco *= mdiv; + do_div(fvco, (pdiv << sdiv)); + + return (unsigned long)fvco; +} + +/* todo: implement pl35xx clock round rate operation */ +static long samsung_pll35xx_round_rate(struct clk_hw *hw, + unsigned long drate, unsigned long *prate) +{ + return -ENOTSUPP; +} + +/* todo: implement pl35xx clock set rate */ +static int samsung_pll35xx_set_rate(struct clk_hw *hw, unsigned long drate, + unsigned long prate) +{ + return -ENOTSUPP; +} + +static const struct clk_ops samsung_pll35xx_clk_ops = { + .recalc_rate = samsung_pll35xx_recalc_rate, + .round_rate = samsung_pll35xx_round_rate, + .set_rate = samsung_pll35xx_set_rate, +}; + +struct clk * __init samsung_clk_register_pll35xx(const char *name, + const char *pname, const void __iomem *con_reg) +{ + struct samsung_clk_pll35xx *pll; + struct clk *clk; + struct clk_init_data init; + + pll = kzalloc(sizeof(*pll), GFP_KERNEL); + if (!pll) { + pr_err("%s: could not allocate pll clk %s\n", __func__, name); + return NULL; + } + + init.name = name; + init.ops = &samsung_pll35xx_clk_ops; + init.flags = CLK_GET_RATE_NOCACHE; + init.parent_names = &pname; + init.num_parents = 1; + + pll->hw.init = &init; + pll->con_reg = con_reg; + + clk = clk_register(NULL, &pll->hw); + if (IS_ERR(clk)) { + pr_err("%s: failed to register pll clock %s\n", __func__, + name); + kfree(pll); + } + + if (clk_register_clkdev(clk, name, NULL)) + pr_err("%s: failed to register lookup for %s", __func__, name); + + return clk; +} + +/* + * PLL36xx Clock Type + */ + +#define PLL36XX_KDIV_MASK (0xFFFF) +#define PLL36XX_MDIV_MASK (0x1FF) +#define PLL36XX_PDIV_MASK (0x3F) +#define PLL36XX_SDIV_MASK (0x7) +#define PLL36XX_MDIV_SHIFT (16) +#define PLL36XX_PDIV_SHIFT (8) +#define PLL36XX_SDIV_SHIFT (0) + +struct samsung_clk_pll36xx { + struct clk_hw hw; + const void __iomem *con_reg; +}; + +#define to_clk_pll36xx(_hw) container_of(_hw, struct samsung_clk_pll36xx, hw) + +static unsigned long samsung_pll36xx_recalc_rate(struct clk_hw *hw, + unsigned long parent_rate) +{ + struct samsung_clk_pll36xx *pll = to_clk_pll36xx(hw); + u32 mdiv, pdiv, sdiv, kdiv, pll_con0, pll_con1; + u64 fvco = parent_rate; + + pll_con0 = __raw_readl(pll->con_reg); + pll_con1 = __raw_readl(pll->con_reg + 4); + mdiv = (pll_con0 >> PLL36XX_MDIV_SHIFT) & PLL36XX_MDIV_MASK; + pdiv = (pll_con0 >> PLL36XX_PDIV_SHIFT) & PLL36XX_PDIV_MASK; + sdiv = (pll_con0 >> PLL36XX_SDIV_SHIFT) & PLL36XX_SDIV_MASK; + kdiv = pll_con1 & PLL36XX_KDIV_MASK; + + fvco *= (mdiv << 16) + kdiv; + do_div(fvco, (pdiv << sdiv)); + fvco >>= 16; + + return (unsigned long)fvco; +} + +/* todo: implement pl36xx clock round rate operation */ +static long samsung_pll36xx_round_rate(struct clk_hw *hw, + unsigned long drate, unsigned long *prate) +{ + return -ENOTSUPP; +} + +/* todo: implement pl36xx clock set rate */ +static int samsung_pll36xx_set_rate(struct clk_hw *hw, unsigned long drate, + unsigned long prate) +{ + return -ENOTSUPP; +} + +static const struct clk_ops samsung_pll36xx_clk_ops = { + .recalc_rate = samsung_pll36xx_recalc_rate, + .round_rate = samsung_pll36xx_round_rate, + .set_rate = samsung_pll36xx_set_rate, +}; + +struct clk * __init samsung_clk_register_pll36xx(const char *name, + const char *pname, const void __iomem *con_reg) +{ + struct samsung_clk_pll36xx *pll; + struct clk *clk; + struct clk_init_data init; + + pll = kzalloc(sizeof(*pll), GFP_KERNEL); + if (!pll) { + pr_err("%s: could not allocate pll clk %s\n", __func__, name); + return NULL; + } + + init.name = name; + init.ops = &samsung_pll36xx_clk_ops; + init.flags = CLK_GET_RATE_NOCACHE; + init.parent_names = &pname; + init.num_parents = 1; + + pll->hw.init = &init; + pll->con_reg = con_reg; + + clk = clk_register(NULL, &pll->hw); + if (IS_ERR(clk)) { + pr_err("%s: failed to register pll clock %s\n", __func__, + name); + kfree(pll); + } + + if (clk_register_clkdev(clk, name, NULL)) + pr_err("%s: failed to register lookup for %s", __func__, name); + + return clk; +} + +/* + * PLL45xx Clock Type + */ + +#define PLL45XX_MDIV_MASK (0x3FF) +#define PLL45XX_PDIV_MASK (0x3F) +#define PLL45XX_SDIV_MASK (0x7) +#define PLL45XX_MDIV_SHIFT (16) +#define PLL45XX_PDIV_SHIFT (8) +#define PLL45XX_SDIV_SHIFT (0) + +struct samsung_clk_pll45xx { + struct clk_hw hw; + enum pll45xx_type type; + const void __iomem *con_reg; +}; + +#define to_clk_pll45xx(_hw) container_of(_hw, struct samsung_clk_pll45xx, hw) + +static unsigned long samsung_pll45xx_recalc_rate(struct clk_hw *hw, + unsigned long parent_rate) +{ + struct samsung_clk_pll45xx *pll = to_clk_pll45xx(hw); + u32 mdiv, pdiv, sdiv, pll_con; + u64 fvco = parent_rate; + + pll_con = __raw_readl(pll->con_reg); + mdiv = (pll_con >> PLL45XX_MDIV_SHIFT) & PLL45XX_MDIV_MASK; + pdiv = (pll_con >> PLL45XX_PDIV_SHIFT) & PLL45XX_PDIV_MASK; + sdiv = (pll_con >> PLL45XX_SDIV_SHIFT) & PLL45XX_SDIV_MASK; + + if (pll->type == pll_4508) + sdiv = sdiv - 1; + + fvco *= mdiv; + do_div(fvco, (pdiv << sdiv)); + + return (unsigned long)fvco; +} + +/* todo: implement pl45xx clock round rate operation */ +static long samsung_pll45xx_round_rate(struct clk_hw *hw, + unsigned long drate, unsigned long *prate) +{ + return -ENOTSUPP; +} + +/* todo: implement pl45xx clock set rate */ +static int samsung_pll45xx_set_rate(struct clk_hw *hw, unsigned long drate, + unsigned long prate) +{ + return -ENOTSUPP; +} + +static const struct clk_ops samsung_pll45xx_clk_ops = { + .recalc_rate = samsung_pll45xx_recalc_rate, + .round_rate = samsung_pll45xx_round_rate, + .set_rate = samsung_pll45xx_set_rate, +}; + +struct clk * __init samsung_clk_register_pll45xx(const char *name, + const char *pname, const void __iomem *con_reg, + enum pll45xx_type type) +{ + struct samsung_clk_pll45xx *pll; + struct clk *clk; + struct clk_init_data init; + + pll = kzalloc(sizeof(*pll), GFP_KERNEL); + if (!pll) { + pr_err("%s: could not allocate pll clk %s\n", __func__, name); + return NULL; + } + + init.name = name; + init.ops = &samsung_pll45xx_clk_ops; + init.flags = CLK_GET_RATE_NOCACHE; + init.parent_names = &pname; + init.num_parents = 1; + + pll->hw.init = &init; + pll->con_reg = con_reg; + pll->type = type; + + clk = clk_register(NULL, &pll->hw); + if (IS_ERR(clk)) { + pr_err("%s: failed to register pll clock %s\n", __func__, + name); + kfree(pll); + } + + if (clk_register_clkdev(clk, name, NULL)) + pr_err("%s: failed to register lookup for %s", __func__, name); + + return clk; +} + +/* + * PLL46xx Clock Type + */ + +#define PLL46XX_MDIV_MASK (0x1FF) +#define PLL46XX_PDIV_MASK (0x3F) +#define PLL46XX_SDIV_MASK (0x7) +#define PLL46XX_MDIV_SHIFT (16) +#define PLL46XX_PDIV_SHIFT (8) +#define PLL46XX_SDIV_SHIFT (0) + +#define PLL46XX_KDIV_MASK (0xFFFF) +#define PLL4650C_KDIV_MASK (0xFFF) +#define PLL46XX_KDIV_SHIFT (0) + +struct samsung_clk_pll46xx { + struct clk_hw hw; + enum pll46xx_type type; + const void __iomem *con_reg; +}; + +#define to_clk_pll46xx(_hw) container_of(_hw, struct samsung_clk_pll46xx, hw) + +static unsigned long samsung_pll46xx_recalc_rate(struct clk_hw *hw, + unsigned long parent_rate) +{ + struct samsung_clk_pll46xx *pll = to_clk_pll46xx(hw); + u32 mdiv, pdiv, sdiv, kdiv, pll_con0, pll_con1, shift; + u64 fvco = parent_rate; + + pll_con0 = __raw_readl(pll->con_reg); + pll_con1 = __raw_readl(pll->con_reg + 4); + mdiv = (pll_con0 >> PLL46XX_MDIV_SHIFT) & PLL46XX_MDIV_MASK; + pdiv = (pll_con0 >> PLL46XX_PDIV_SHIFT) & PLL46XX_PDIV_MASK; + sdiv = (pll_con0 >> PLL46XX_SDIV_SHIFT) & PLL46XX_SDIV_MASK; + kdiv = pll->type == pll_4650c ? pll_con1 & PLL4650C_KDIV_MASK : + pll_con1 & PLL46XX_KDIV_MASK; + + shift = pll->type == pll_4600 ? 16 : 10; + fvco *= (mdiv << shift) + kdiv; + do_div(fvco, (pdiv << sdiv)); + fvco >>= shift; + + return (unsigned long)fvco; +} + +/* todo: implement pl46xx clock round rate operation */ +static long samsung_pll46xx_round_rate(struct clk_hw *hw, + unsigned long drate, unsigned long *prate) +{ + return -ENOTSUPP; +} + +/* todo: implement pl46xx clock set rate */ +static int samsung_pll46xx_set_rate(struct clk_hw *hw, unsigned long drate, + unsigned long prate) +{ + return -ENOTSUPP; +} + +static const struct clk_ops samsung_pll46xx_clk_ops = { + .recalc_rate = samsung_pll46xx_recalc_rate, + .round_rate = samsung_pll46xx_round_rate, + .set_rate = samsung_pll46xx_set_rate, +}; + +struct clk * __init samsung_clk_register_pll46xx(const char *name, + const char *pname, const void __iomem *con_reg, + enum pll46xx_type type) +{ + struct samsung_clk_pll46xx *pll; + struct clk *clk; + struct clk_init_data init; + + pll = kzalloc(sizeof(*pll), GFP_KERNEL); + if (!pll) { + pr_err("%s: could not allocate pll clk %s\n", __func__, name); + return NULL; + } + + init.name = name; + init.ops = &samsung_pll46xx_clk_ops; + init.flags = CLK_GET_RATE_NOCACHE; + init.parent_names = &pname; + init.num_parents = 1; + + pll->hw.init = &init; + pll->con_reg = con_reg; + pll->type = type; + + clk = clk_register(NULL, &pll->hw); + if (IS_ERR(clk)) { + pr_err("%s: failed to register pll clock %s\n", __func__, + name); + kfree(pll); + } + + if (clk_register_clkdev(clk, name, NULL)) + pr_err("%s: failed to register lookup for %s", __func__, name); + + return clk; +} + +/* + * PLL2550x Clock Type + */ + +#define PLL2550X_R_MASK (0x1) +#define PLL2550X_P_MASK (0x3F) +#define PLL2550X_M_MASK (0x3FF) +#define PLL2550X_S_MASK (0x7) +#define PLL2550X_R_SHIFT (20) +#define PLL2550X_P_SHIFT (14) +#define PLL2550X_M_SHIFT (4) +#define PLL2550X_S_SHIFT (0) + +struct samsung_clk_pll2550x { + struct clk_hw hw; + const void __iomem *reg_base; + unsigned long offset; +}; + +#define to_clk_pll2550x(_hw) container_of(_hw, struct samsung_clk_pll2550x, hw) + +static unsigned long samsung_pll2550x_recalc_rate(struct clk_hw *hw, + unsigned long parent_rate) +{ + struct samsung_clk_pll2550x *pll = to_clk_pll2550x(hw); + u32 r, p, m, s, pll_stat; + u64 fvco = parent_rate; + + pll_stat = __raw_readl(pll->reg_base + pll->offset * 3); + r = (pll_stat >> PLL2550X_R_SHIFT) & PLL2550X_R_MASK; + if (!r) + return 0; + p = (pll_stat >> PLL2550X_P_SHIFT) & PLL2550X_P_MASK; + m = (pll_stat >> PLL2550X_M_SHIFT) & PLL2550X_M_MASK; + s = (pll_stat >> PLL2550X_S_SHIFT) & PLL2550X_S_MASK; + + fvco *= m; + do_div(fvco, (p << s)); + + return (unsigned long)fvco; +} + +/* todo: implement pl2550x clock round rate operation */ +static long samsung_pll2550x_round_rate(struct clk_hw *hw, + unsigned long drate, unsigned long *prate) +{ + return -ENOTSUPP; +} + +/* todo: implement pl2550x clock set rate */ +static int samsung_pll2550x_set_rate(struct clk_hw *hw, unsigned long drate, + unsigned long prate) +{ + return -ENOTSUPP; +} + +static const struct clk_ops samsung_pll2550x_clk_ops = { + .recalc_rate = samsung_pll2550x_recalc_rate, + .round_rate = samsung_pll2550x_round_rate, + .set_rate = samsung_pll2550x_set_rate, +}; + +struct clk * __init samsung_clk_register_pll2550x(const char *name, + const char *pname, const void __iomem *reg_base, + const unsigned long offset) +{ + struct samsung_clk_pll2550x *pll; + struct clk *clk; + struct clk_init_data init; + + pll = kzalloc(sizeof(*pll), GFP_KERNEL); + if (!pll) { + pr_err("%s: could not allocate pll clk %s\n", __func__, name); + return NULL; + } + + init.name = name; + init.ops = &samsung_pll2550x_clk_ops; + init.flags = CLK_GET_RATE_NOCACHE; + init.parent_names = &pname; + init.num_parents = 1; + + pll->hw.init = &init; + pll->reg_base = reg_base; + pll->offset = offset; + + clk = clk_register(NULL, &pll->hw); + if (IS_ERR(clk)) { + pr_err("%s: failed to register pll clock %s\n", __func__, + name); + kfree(pll); + } + + if (clk_register_clkdev(clk, name, NULL)) + pr_err("%s: failed to register lookup for %s", __func__, name); + + return clk; +} diff --git a/drivers/clk/samsung/clk-pll.h b/drivers/clk/samsung/clk-pll.h new file mode 100644 index 000000000000..f33786e9a78b --- /dev/null +++ b/drivers/clk/samsung/clk-pll.h @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2013 Samsung Electronics Co., Ltd. + * Copyright (c) 2013 Linaro 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. + * + * Common Clock Framework support for all PLL's in Samsung platforms +*/ + +#ifndef __SAMSUNG_CLK_PLL_H +#define __SAMSUNG_CLK_PLL_H + +enum pll45xx_type { + pll_4500, + pll_4502, + pll_4508 +}; + +enum pll46xx_type { + pll_4600, + pll_4650, + pll_4650c, +}; + +extern struct clk * __init samsung_clk_register_pll35xx(const char *name, + const char *pname, const void __iomem *con_reg); +extern struct clk * __init samsung_clk_register_pll36xx(const char *name, + const char *pname, const void __iomem *con_reg); +extern struct clk * __init samsung_clk_register_pll45xx(const char *name, + const char *pname, const void __iomem *con_reg, + enum pll45xx_type type); +extern struct clk * __init samsung_clk_register_pll46xx(const char *name, + const char *pname, const void __iomem *con_reg, + enum pll46xx_type type); +extern struct clk * __init samsung_clk_register_pll2550x(const char *name, + const char *pname, const void __iomem *reg_base, + const unsigned long offset); + +#endif /* __SAMSUNG_CLK_PLL_H */ -- cgit v1.2.3 From e062b571777f52dfbfc15f9edc2d36a45664bb3a Mon Sep 17 00:00:00 2001 From: Thomas Abraham Date: Sat, 9 Mar 2013 17:02:52 +0900 Subject: clk: exynos4: register clocks using common clock framework The Exynos4 clocks are statically listed and registered using the Samsung specific common clock helper functions. Both device tree based clock lookup and clkdev based clock lookups are supported. Reviewed-by: Sylwester Nawrocki Tested-by: Sylwester Nawrocki Reviewed-by: Tomasz Figa Tested-by: Tomasz Figa Signed-off-by: Thomas Abraham Acked-by: Mike Turquette Signed-off-by: Kukjin Kim --- drivers/clk/samsung/Makefile | 1 + drivers/clk/samsung/clk-exynos4.c | 843 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 844 insertions(+) create mode 100644 drivers/clk/samsung/clk-exynos4.c (limited to 'drivers/clk') diff --git a/drivers/clk/samsung/Makefile b/drivers/clk/samsung/Makefile index 78e5aaa55b40..8862f0db82b7 100644 --- a/drivers/clk/samsung/Makefile +++ b/drivers/clk/samsung/Makefile @@ -3,3 +3,4 @@ # obj-$(CONFIG_COMMON_CLK) += clk.o clk-pll.o +obj-$(CONFIG_ARCH_EXYNOS4) += clk-exynos4.o diff --git a/drivers/clk/samsung/clk-exynos4.c b/drivers/clk/samsung/clk-exynos4.c new file mode 100644 index 000000000000..e1bb81a1c264 --- /dev/null +++ b/drivers/clk/samsung/clk-exynos4.c @@ -0,0 +1,843 @@ +/* + * Copyright (c) 2013 Samsung Electronics Co., Ltd. + * Copyright (c) 2013 Linaro Ltd. + * Author: Thomas Abraham + * + * 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. + * + * Common Clock Framework support for all Exynos4 SoCs. +*/ + +#include +#include +#include +#include +#include + +#include +#include "clk.h" +#include "clk-pll.h" + +/* Exynos4 clock controller register offsets */ +#define SRC_LEFTBUS 0x4200 +#define E4X12_GATE_IP_IMAGE 0x4930 +#define GATE_IP_RIGHTBUS 0x8800 +#define E4X12_GATE_IP_PERIR 0x8960 +#define SRC_TOP0 0xc210 +#define SRC_TOP1 0xc214 +#define SRC_CAM 0xc220 +#define SRC_TV 0xc224 +#define SRC_MFC 0xcc28 +#define SRC_G3D 0xc22c +#define E4210_SRC_IMAGE 0xc230 +#define SRC_LCD0 0xc234 +#define SRC_LCD1 0xc238 +#define SRC_MAUDIO 0xc23c +#define SRC_FSYS 0xc240 +#define SRC_PERIL0 0xc250 +#define SRC_PERIL1 0xc254 +#define E4X12_SRC_CAM1 0xc258 +#define SRC_MASK_CAM 0xc320 +#define SRC_MASK_TV 0xc324 +#define SRC_MASK_LCD0 0xc334 +#define SRC_MASK_LCD1 0xc338 +#define SRC_MASK_MAUDIO 0xc33c +#define SRC_MASK_FSYS 0xc340 +#define SRC_MASK_PERIL0 0xc350 +#define SRC_MASK_PERIL1 0xc354 +#define DIV_TOP 0xc510 +#define DIV_CAM 0xc520 +#define DIV_TV 0xc524 +#define DIV_MFC 0xc528 +#define DIV_G3D 0xc52c +#define DIV_IMAGE 0xc530 +#define DIV_LCD0 0xc534 +#define E4210_DIV_LCD1 0xc538 +#define E4X12_DIV_ISP 0xc538 +#define DIV_MAUDIO 0xc53c +#define DIV_FSYS0 0xc540 +#define DIV_FSYS1 0xc544 +#define DIV_FSYS2 0xc548 +#define DIV_FSYS3 0xc54c +#define DIV_PERIL0 0xc550 +#define DIV_PERIL1 0xc554 +#define DIV_PERIL2 0xc558 +#define DIV_PERIL3 0xc55c +#define DIV_PERIL4 0xc560 +#define DIV_PERIL5 0xc564 +#define E4X12_DIV_CAM1 0xc568 +#define GATE_SCLK_CAM 0xc820 +#define GATE_IP_CAM 0xc920 +#define GATE_IP_TV 0xc924 +#define GATE_IP_MFC 0xc928 +#define GATE_IP_G3D 0xc92c +#define E4210_GATE_IP_IMAGE 0xc930 +#define GATE_IP_LCD0 0xc934 +#define GATE_IP_LCD1 0xc938 +#define E4X12_GATE_IP_MAUDIO 0xc93c +#define GATE_IP_FSYS 0xc940 +#define GATE_IP_GPS 0xc94c +#define GATE_IP_PERIL 0xc950 +#define GATE_IP_PERIR 0xc960 +#define E4X12_MPLL_CON0 0x10108 +#define E4X12_SRC_DMC 0x10200 +#define APLL_CON0 0x14100 +#define E4210_MPLL_CON0 0x14108 +#define SRC_CPU 0x14200 +#define DIV_CPU0 0x14500 + +/* the exynos4 soc type */ +enum exynos4_soc { + EXYNOS4210, + EXYNOS4X12, +}; + +/* + * Let each supported clock get a unique id. This id is used to lookup the clock + * for device tree based platforms. The clocks are categorized into three + * sections: core, sclk gate and bus interface gate clocks. + * + * When adding a new clock to this list, it is advised to choose a clock + * category and add it to the end of that category. That is because the the + * device tree source file is referring to these ids and any change in the + * sequence number of existing clocks will require corresponding change in the + * device tree files. This limitation would go away when pre-processor support + * for dtc would be available. + */ +enum exynos4_clks { + none, + + /* core clocks */ + xxti, xusbxti, fin_pll, fout_apll, fout_mpll, fout_epll, fout_vpll, + sclk_apll, sclk_mpll, sclk_epll, sclk_vpll, arm_clk, aclk200, aclk100, + aclk160, aclk133, + + /* gate for special clocks (sclk) */ + sclk_fimc0 = 128, sclk_fimc1, sclk_fimc2, sclk_fimc3, sclk_cam0, + sclk_cam1, sclk_csis0, sclk_csis1, sclk_hdmi, sclk_mixer, sclk_dac, + sclk_pixel, sclk_fimd0, sclk_mdnie0, sclk_mdnie_pwm0, sclk_mipi0, + sclk_audio0, sclk_mmc0, sclk_mmc1, sclk_mmc2, sclk_mmc3, sclk_mmc4, + sclk_sata, sclk_uart0, sclk_uart1, sclk_uart2, sclk_uart3, sclk_uart4, + sclk_audio1, sclk_audio2, sclk_spdif, sclk_spi0, sclk_spi1, sclk_spi2, + sclk_slimbus, sclk_fimd1, sclk_mipi1, sclk_pcm1, sclk_pcm2, sclk_i2s1, + sclk_i2s2, sclk_mipihsi, + + /* gate clocks */ + fimc0 = 256, fimc1, fimc2, fimc3, csis0, csis1, jpeg, smmu_fimc0, + smmu_fimc1, smmu_fimc2, smmu_fimc3, smmu_jpeg, vp, mixer, tvenc, hdmi, + smmu_tv, mfc, smmu_mfcl, smmu_mfcr, g3d, g2d, rotator, mdma, smmu_g2d, + smmu_rotator, smmu_mdma, fimd0, mie0, mdnie0, dsim0, smmu_fimd0, fimd1, + mie1, dsim1, smmu_fimd1, pdma0, pdma1, pcie_phy, sata_phy, tsi, sdmmc0, + sdmmc1, sdmmc2, sdmmc3, sdmmc4, sata, sromc, usb_host, usb_device, pcie, + onenand, nfcon, smmu_pcie, gps, smmu_gps, uart0, uart1, uart2, uart3, + uart4, i2c0, i2c1, i2c2, i2c3, i2c4, i2c5, i2c6, i2c7, i2c_hdmi, tsadc, + spi0, spi1, spi2, i2s1, i2s2, pcm0, i2s0, pcm1, pcm2, pwm, slimbus, + spdif, ac97, modemif, chipid, sysreg, hdmi_cec, mct, wdt, rtc, keyif, + audss, mipi_hsi, mdma2, + + nr_clks, +}; + +/* + * list of controller registers to be saved and restored during a + * suspend/resume cycle. + */ +static __initdata unsigned long exynos4_clk_regs[] = { + SRC_LEFTBUS, + E4X12_GATE_IP_IMAGE, + GATE_IP_RIGHTBUS, + E4X12_GATE_IP_PERIR, + SRC_TOP0, + SRC_TOP1, + SRC_CAM, + SRC_TV, + SRC_MFC, + SRC_G3D, + E4210_SRC_IMAGE, + SRC_LCD0, + SRC_LCD1, + SRC_MAUDIO, + SRC_FSYS, + SRC_PERIL0, + SRC_PERIL1, + E4X12_SRC_CAM1, + SRC_MASK_CAM, + SRC_MASK_TV, + SRC_MASK_LCD0, + SRC_MASK_LCD1, + SRC_MASK_MAUDIO, + SRC_MASK_FSYS, + SRC_MASK_PERIL0, + SRC_MASK_PERIL1, + DIV_TOP, + DIV_CAM, + DIV_TV, + DIV_MFC, + DIV_G3D, + DIV_IMAGE, + DIV_LCD0, + E4210_DIV_LCD1, + E4X12_DIV_ISP, + DIV_MAUDIO, + DIV_FSYS0, + DIV_FSYS1, + DIV_FSYS2, + DIV_FSYS3, + DIV_PERIL0, + DIV_PERIL1, + DIV_PERIL2, + DIV_PERIL3, + DIV_PERIL4, + DIV_PERIL5, + E4X12_DIV_CAM1, + GATE_SCLK_CAM, + GATE_IP_CAM, + GATE_IP_TV, + GATE_IP_MFC, + GATE_IP_G3D, + E4210_GATE_IP_IMAGE, + GATE_IP_LCD0, + GATE_IP_LCD1, + E4X12_GATE_IP_MAUDIO, + GATE_IP_FSYS, + GATE_IP_GPS, + GATE_IP_PERIL, + GATE_IP_PERIR, + E4X12_MPLL_CON0, + E4X12_SRC_DMC, + APLL_CON0, + E4210_MPLL_CON0, + SRC_CPU, + DIV_CPU0, +}; + +/* list of all parent clock list */ +PNAME(mout_apll_p) = { "fin_pll", "fout_apll", }; +PNAME(mout_mpll_p) = { "fin_pll", "fout_mpll", }; +PNAME(mout_epll_p) = { "fin_pll", "fout_epll", }; +PNAME(mout_vpllsrc_p) = { "fin_pll", "sclk_hdmi24m", }; +PNAME(sclk_vpll_p4210) = { "mout_vpllsrc", "fout_vpll", }; +PNAME(mout_vpll_p) = { "fin_pll", "fout_vpll", }; +PNAME(mout_core_p) = { "mout_apll", "sclk_mpll", }; +PNAME(sclk_ampll_p) = { "sclk_mpll", "sclk_apll", }; +PNAME(mout_mpll_user_p) = { "fin_pll", "sclk_mpll", }; +PNAME(aclk_p4412) = { "mout_mpll_user", "sclk_apll", }; +PNAME(sclk_evpll_p) = { "sclk_epll", "sclk_vpll", }; +PNAME(mout_mfc_p) = { "mout_mfc0", "mout_mfc1", }; +PNAME(mout_g3d_p) = { "mout_g3d0", "mout_g3d1", }; +PNAME(mout_g2d_p) = { "mout_g2d0", "mout_g2d1", }; +PNAME(mout_mixer_p4210) = { "sclk_dac", "sclk_hdmi", }; +PNAME(mout_dac_p4210) = { "sclk_vpll", "sclk_hdmiphy", }; +PNAME(mout_hdmi_p) = { "sclk_pixel", "sclk_hdmiphy", }; +PNAME(mout_jpeg_p) = { "mout_jpeg0", "mout_jpeg1", }; +PNAME(group1_p) = { "xxti", "xusbxti", "sclk_hdmi24m", "sclk_usbphy0", + "none", "sclk_hdmiphy", "sclk_mpll", + "sclk_epll", "sclk_vpll", }; +PNAME(mout_audio0_p) = { "cdclk0", "none", "sclk_hdmi24m", "sclk_usbphy0", + "xxti", "xusbxti", "sclk_mpll", "sclk_epll", + "sclk_vpll" }; +PNAME(mout_audio1_p) = { "cdclk1", "none", "sclk_hdmi24m", "sclk_usbphy0", + "xxti", "xusbxti", "sclk_mpll", "sclk_epll", + "sclk_vpll", }; +PNAME(mout_audio2_p) = { "cdclk2", "none", "sclk_hdmi24m", "sclk_usbphy0", + "xxti", "xusbxti", "sclk_mpll", "sclk_epll", + "sclk_vpll", }; +PNAME(mout_spdif_p) = { "sclk_audio0", "sclk_audio1", "sclk_audio2", + "spdif_extclk", }; + +/* fixed rate clocks generated outside the soc */ +struct samsung_fixed_rate_clock exynos4_fixed_rate_ext_clks[] __initdata = { + FRATE(xxti, "xxti", NULL, CLK_IS_ROOT, 0), + FRATE(xusbxti, "xusbxti", NULL, CLK_IS_ROOT, 0), +}; + +/* fixed rate clocks generated inside the soc */ +struct samsung_fixed_rate_clock exynos4_fixed_rate_clks[] __initdata = { + FRATE(none, "sclk_hdmi24m", NULL, CLK_IS_ROOT, 24000000), + FRATE(none, "sclk_hdmiphy", NULL, CLK_IS_ROOT, 27000000), + FRATE(none, "sclk_usbphy0", NULL, CLK_IS_ROOT, 48000000), +}; + +struct samsung_fixed_rate_clock exynos4210_fixed_rate_clks[] __initdata = { + FRATE(none, "sclk_usbphy1", NULL, CLK_IS_ROOT, 48000000), +}; + +/* list of mux clocks supported in all exynos4 soc's */ +struct samsung_mux_clock exynos4_mux_clks[] __initdata = { + MUX(none, "mout_apll", mout_apll_p, SRC_CPU, 0, 1), + MUX(none, "mout_core", mout_core_p, SRC_CPU, 16, 1), + MUX(none, "mout_fimc0", group1_p, SRC_CAM, 0, 4), + MUX(none, "mout_fimc1", group1_p, SRC_CAM, 4, 4), + MUX(none, "mout_fimc2", group1_p, SRC_CAM, 8, 4), + MUX(none, "mout_fimc3", group1_p, SRC_CAM, 12, 4), + MUX(none, "mout_cam0", group1_p, SRC_CAM, 16, 4), + MUX(none, "mout_cam1", group1_p, SRC_CAM, 20, 4), + MUX(none, "mout_csis0", group1_p, SRC_CAM, 24, 4), + MUX(none, "mout_csis1", group1_p, SRC_CAM, 28, 4), + MUX(none, "mout_hdmi", mout_hdmi_p, SRC_TV, 0, 1), + MUX(none, "mout_mfc0", sclk_ampll_p, SRC_MFC, 0, 1), + MUX(none, "mout_mfc1", sclk_evpll_p, SRC_MFC, 4, 1), + MUX(none, "mout_mfc", mout_mfc_p, SRC_MFC, 8, 1), + MUX(none, "mout_g3d0", sclk_ampll_p, SRC_G3D, 0, 1), + MUX(none, "mout_g3d1", sclk_evpll_p, SRC_G3D, 4, 1), + MUX(none, "mout_g3d", mout_g3d_p, SRC_G3D, 8, 1), + MUX(none, "mout_fimd0", group1_p, SRC_LCD0, 0, 4), + MUX(none, "mout_mipi0", group1_p, SRC_LCD0, 12, 4), + MUX(none, "mout_audio0", mout_audio0_p, SRC_MAUDIO, 0, 4), + MUX(none, "mout_mmc0", group1_p, SRC_FSYS, 0, 4), + MUX(none, "mout_mmc1", group1_p, SRC_FSYS, 4, 4), + MUX(none, "mout_mmc2", group1_p, SRC_FSYS, 8, 4), + MUX(none, "mout_mmc3", group1_p, SRC_FSYS, 12, 4), + MUX(none, "mout_mmc4", group1_p, SRC_FSYS, 16, 4), + MUX(none, "mout_uart0", group1_p, SRC_PERIL0, 0, 4), + MUX(none, "mout_uart1", group1_p, SRC_PERIL0, 4, 4), + MUX(none, "mout_uart2", group1_p, SRC_PERIL0, 8, 4), + MUX(none, "mout_uart3", group1_p, SRC_PERIL0, 12, 4), + MUX(none, "mout_uart4", group1_p, SRC_PERIL0, 16, 4), + MUX(none, "mout_audio1", mout_audio1_p, SRC_PERIL1, 0, 4), + MUX(none, "mout_audio2", mout_audio2_p, SRC_PERIL1, 4, 4), + MUX(none, "mout_spdif", mout_spdif_p, SRC_PERIL1, 8, 2), + MUX(none, "mout_spi0", group1_p, SRC_PERIL1, 16, 4), + MUX(none, "mout_spi1", group1_p, SRC_PERIL1, 20, 4), + MUX(none, "mout_spi2", group1_p, SRC_PERIL1, 24, 4), + MUX_A(sclk_epll, "sclk_epll", mout_epll_p, SRC_TOP0, 4, 1, "sclk_epll"), +}; + +/* list of mux clocks supported in exynos4210 soc */ +struct samsung_mux_clock exynos4210_mux_clks[] __initdata = { + MUX(none, "mout_aclk200", sclk_ampll_p, SRC_TOP0, 12, 1), + MUX(none, "mout_aclk100", sclk_ampll_p, SRC_TOP0, 16, 1), + MUX(none, "mout_aclk160", sclk_ampll_p, SRC_TOP0, 20, 1), + MUX(none, "mout_aclk133", sclk_ampll_p, SRC_TOP0, 24, 1), + MUX(none, "mout_vpllsrc", mout_vpllsrc_p, SRC_TOP1, 0, 1), + MUX(none, "mout_mixer", mout_mixer_p4210, SRC_TV, 4, 1), + MUX(none, "mout_dac", mout_dac_p4210, SRC_TV, 8, 1), + MUX(none, "mout_g2d0", sclk_ampll_p, E4210_SRC_IMAGE, 0, 1), + MUX(none, "mout_g2d1", sclk_evpll_p, E4210_SRC_IMAGE, 4, 1), + MUX(none, "mout_g2d", mout_g2d_p, E4210_SRC_IMAGE, 8, 1), + MUX(none, "mout_fimd1", group1_p, SRC_LCD1, 0, 4), + MUX(none, "mout_mipi1", group1_p, SRC_LCD1, 12, 4), + MUX_A(sclk_mpll, "sclk_mpll", mout_mpll_p, SRC_CPU, 8, 1, "sclk_mpll"), + MUX_A(sclk_vpll, "sclk_vpll", sclk_vpll_p4210, + SRC_TOP0, 8, 1, "sclk_vpll"), +}; + +/* list of mux clocks supported in exynos4x12 soc */ +struct samsung_mux_clock exynos4x12_mux_clks[] __initdata = { + MUX(none, "mout_mpll_user", mout_mpll_user_p, SRC_LEFTBUS, 4, 1), + MUX(none, "mout_aclk200", aclk_p4412, SRC_TOP0, 12, 1), + MUX(none, "mout_aclk100", aclk_p4412, SRC_TOP0, 16, 1), + MUX(none, "mout_aclk160", aclk_p4412, SRC_TOP0, 20, 1), + MUX(none, "mout_aclk133", aclk_p4412, SRC_TOP0, 24, 1), + MUX(none, "mout_mdnie0", group1_p, SRC_LCD0, 4, 4), + MUX(none, "mout_mdnie_pwm0", group1_p, SRC_LCD0, 8, 4), + MUX(none, "mout_sata", sclk_ampll_p, SRC_FSYS, 24, 1), + MUX(none, "mout_jpeg0", sclk_ampll_p, E4X12_SRC_CAM1, 0, 1), + MUX(none, "mout_jpeg1", sclk_evpll_p, E4X12_SRC_CAM1, 4, 1), + MUX(none, "mout_jpeg", mout_jpeg_p, E4X12_SRC_CAM1, 8, 1), + MUX_A(sclk_mpll, "sclk_mpll", mout_mpll_p, + E4X12_SRC_DMC, 12, 1, "sclk_mpll"), + MUX_A(sclk_vpll, "sclk_vpll", mout_vpll_p, + SRC_TOP0, 8, 1, "sclk_vpll"), +}; + +/* list of divider clocks supported in all exynos4 soc's */ +struct samsung_div_clock exynos4_div_clks[] __initdata = { + DIV(none, "div_core", "mout_core", DIV_CPU0, 0, 3), + DIV(none, "div_core2", "div_core", DIV_CPU0, 28, 3), + DIV(none, "div_fimc0", "mout_fimc0", DIV_CAM, 0, 4), + DIV(none, "div_fimc1", "mout_fimc1", DIV_CAM, 4, 4), + DIV(none, "div_fimc2", "mout_fimc2", DIV_CAM, 8, 4), + DIV(none, "div_fimc3", "mout_fimc3", DIV_CAM, 12, 4), + DIV(none, "div_cam0", "mout_cam0", DIV_CAM, 16, 4), + DIV(none, "div_cam1", "mout_cam1", DIV_CAM, 20, 4), + DIV(none, "div_csis0", "mout_csis0", DIV_CAM, 24, 4), + DIV(none, "div_csis1", "mout_csis1", DIV_CAM, 28, 4), + DIV(none, "div_mfc", "mout_mfc", DIV_MFC, 0, 4), + DIV(none, "div_g3d", "mout_g3d", DIV_G3D, 0, 4), + DIV(none, "div_fimd0", "mout_fimd0", DIV_LCD0, 0, 4), + DIV(none, "div_mipi0", "mout_mipi0", DIV_LCD0, 16, 4), + DIV(none, "div_audio0", "mout_audio0", DIV_MAUDIO, 0, 4), + DIV(none, "div_pcm0", "sclk_audio0", DIV_MAUDIO, 4, 8), + DIV(none, "div_mmc0", "mout_mmc0", DIV_FSYS1, 0, 4), + DIV(none, "div_mmc1", "mout_mmc1", DIV_FSYS1, 16, 4), + DIV(none, "div_mmc2", "mout_mmc2", DIV_FSYS2, 0, 4), + DIV(none, "div_mmc3", "mout_mmc3", DIV_FSYS2, 16, 4), + DIV(sclk_pixel, "sclk_pixel", "sclk_vpll", DIV_TV, 0, 4), + DIV(aclk200, "aclk200", "mout_aclk200", DIV_TOP, 0, 3), + DIV(aclk100, "aclk100", "mout_aclk100", DIV_TOP, 4, 4), + DIV(aclk160, "aclk160", "mout_aclk160", DIV_TOP, 8, 3), + DIV(aclk133, "aclk133", "mout_aclk133", DIV_TOP, 12, 3), + DIV(sclk_slimbus, "sclk_slimbus", "sclk_epll", DIV_PERIL3, 4, 4), + DIV(sclk_pcm1, "sclk_pcm1", "sclk_audio1", DIV_PERIL4, 4, 8), + DIV(sclk_pcm2, "sclk_pcm2", "sclk_audio2", DIV_PERIL4, 20, 8), + DIV(sclk_i2s1, "sclk_i2s1", "sclk_audio1", DIV_PERIL5, 0, 6), + DIV(sclk_i2s2, "sclk_i2s2", "sclk_audio2", DIV_PERIL5, 8, 6), + DIV(none, "div_mmc4", "mout_mmc4", DIV_FSYS3, 0, 4), + DIV(none, "div_mmc_pre4", "div_mmc4", DIV_FSYS3, 8, 8), + DIV(none, "div_uart0", "mout_uart0", DIV_PERIL0, 0, 4), + DIV(none, "div_uart1", "mout_uart1", DIV_PERIL0, 4, 4), + DIV(none, "div_uart2", "mout_uart2", DIV_PERIL0, 8, 4), + DIV(none, "div_uart3", "mout_uart3", DIV_PERIL0, 12, 4), + DIV(none, "div_uart4", "mout_uart4", DIV_PERIL0, 16, 4), + DIV(none, "div_spi0", "mout_spi0", DIV_PERIL1, 0, 4), + DIV(none, "div_spi_pre0", "div_spi0", DIV_PERIL1, 8, 8), + DIV(none, "div_spi1", "mout_spi1", DIV_PERIL1, 16, 4), + DIV(none, "div_spi_pre1", "div_spi1", DIV_PERIL1, 24, 8), + DIV(none, "div_spi2", "mout_spi2", DIV_PERIL2, 0, 4), + DIV(none, "div_spi_pre2", "div_spi2", DIV_PERIL2, 8, 8), + DIV(none, "div_audio1", "mout_audio1", DIV_PERIL4, 0, 4), + DIV(none, "div_audio2", "mout_audio2", DIV_PERIL4, 16, 4), + DIV_A(arm_clk, "arm_clk", "div_core2", DIV_CPU0, 28, 3, "arm_clk"), + DIV_A(sclk_apll, "sclk_apll", "mout_apll", + DIV_CPU0, 24, 3, "sclk_apll"), + DIV_F(none, "div_mipi_pre0", "div_mipi0", DIV_LCD0, 20, 4, + CLK_SET_RATE_PARENT, 0), + DIV_F(none, "div_mmc_pre0", "div_mmc0", DIV_FSYS1, 8, 8, + CLK_SET_RATE_PARENT, 0), + DIV_F(none, "div_mmc_pre1", "div_mmc1", DIV_FSYS1, 24, 8, + CLK_SET_RATE_PARENT, 0), + DIV_F(none, "div_mmc_pre2", "div_mmc2", DIV_FSYS2, 8, 8, + CLK_SET_RATE_PARENT, 0), + DIV_F(none, "div_mmc_pre3", "div_mmc3", DIV_FSYS2, 24, 8, + CLK_SET_RATE_PARENT, 0), +}; + +/* list of divider clocks supported in exynos4210 soc */ +struct samsung_div_clock exynos4210_div_clks[] __initdata = { + DIV(none, "div_g2d", "mout_g2d", DIV_IMAGE, 0, 4), + DIV(none, "div_fimd1", "mout_fimd1", E4210_DIV_LCD1, 0, 4), + DIV(none, "div_mipi1", "mout_mipi1", E4210_DIV_LCD1, 16, 4), + DIV(none, "div_sata", "mout_sata", DIV_FSYS0, 20, 4), + DIV_F(none, "div_mipi_pre1", "div_mipi1", E4210_DIV_LCD1, 20, 4, + CLK_SET_RATE_PARENT, 0), +}; + +/* list of divider clocks supported in exynos4x12 soc */ +struct samsung_div_clock exynos4x12_div_clks[] __initdata = { + DIV(none, "div_mdnie0", "mout_mdnie0", DIV_LCD0, 4, 4), + DIV(none, "div_mdnie_pwm0", "mout_mdnie_pwm0", DIV_LCD0, 8, 4), + DIV(none, "div_mdnie_pwm_pre0", "div_mdnie_pwm0", DIV_LCD0, 12, 4), + DIV(none, "div_mipihsi", "mout_mipihsi", DIV_FSYS0, 20, 4), + DIV(none, "div_jpeg", "mout_jpeg", E4X12_DIV_CAM1, 0, 4), +}; + +/* list of gate clocks supported in all exynos4 soc's */ +struct samsung_gate_clock exynos4_gate_clks[] __initdata = { + /* + * After all Exynos4 based platforms are migrated to use device tree, + * the device name and clock alias names specified below for some + * of the clocks can be removed. + */ + GATE(sclk_hdmi, "sclk_hdmi", "mout_hdmi", SRC_MASK_TV, 0, 0, 0), + GATE(sclk_mixer, "sclk_mixer", "mout_mixer", SRC_MASK_TV, 4, 0, 0), + GATE(sclk_dac, "sclk_dac", "mout_dac", SRC_MASK_TV, 8, 0, 0), + GATE(sclk_spdif, "sclk_spdif", "mout_spdif", 0xc354, 8, 0, 0), + GATE(jpeg, "jpeg", "aclk160", GATE_IP_CAM, 6, 0, 0), + GATE(mie0, "mie0", "aclk160", GATE_IP_LCD0, 1, 0, 0), + GATE(dsim0, "dsim0", "aclk160", GATE_IP_LCD0, 3, 0, 0), + GATE(fimd1, "fimd1", "aclk160", GATE_IP_LCD1, 0, 0, 0), + GATE(mie1, "mie1", "aclk160", GATE_IP_LCD1, 1, 0, 0), + GATE(dsim1, "dsim1", "aclk160", GATE_IP_LCD1, 3, 0, 0), + GATE(smmu_fimd1, "smmu_fimd1", "aclk160", GATE_IP_LCD1, 4, 0, 0), + GATE(tsi, "tsi", "aclk133", GATE_IP_FSYS, 4, 0, 0), + GATE(sromc, "sromc", "aclk133", GATE_IP_FSYS, 11, 0, 0), + GATE(g3d, "g3d", "aclk200", GATE_IP_G3D, 0, 0, 0), + GATE(usb_device, "usb_device", "aclk133", GATE_IP_FSYS, 13, 0, 0), + GATE(onenand, "onenand", "aclk133", GATE_IP_FSYS, 15, 0, 0), + GATE(nfcon, "nfcon", "aclk133", GATE_IP_FSYS, 16, 0, 0), + GATE(gps, "gps", "aclk133", GATE_IP_GPS, 0, 0, 0), + GATE(smmu_gps, "smmu_gps", "aclk133", GATE_IP_GPS, 1, 0, 0), + GATE(slimbus, "slimbus", "aclk100", GATE_IP_PERIL, 25, 0, 0), + GATE(sclk_cam0, "sclk_cam0", "div_cam0", GATE_SCLK_CAM, 4, + CLK_SET_RATE_PARENT, 0), + GATE(sclk_cam1, "sclk_cam1", "div_cam1", GATE_SCLK_CAM, 5, + CLK_SET_RATE_PARENT, 0), + GATE(sclk_mipi0, "sclk_mipi0", "div_mipi_pre0", + SRC_MASK_LCD0, 12, CLK_SET_RATE_PARENT, 0), + GATE(sclk_audio1, "sclk_audio1", "div_audio1", 0xc354, 0, + CLK_SET_RATE_PARENT, 0), + GATE_D(vp, "s5p-mixer", "vp", "aclk160", GATE_IP_TV, 0, 0, 0), + GATE_D(mixer, "s5p-mixer", "mixer", "aclk160", GATE_IP_TV, 1, 0, 0), + GATE_D(hdmi, "exynos4-hdmi", "hdmi", "aclk160", GATE_IP_TV, 3, 0, 0), + GATE_A(pwm, "pwm", "aclk100", GATE_IP_PERIL, 24, 0, 0, "timers"), + GATE_A(sdmmc4, "sdmmc4", "aclk133", GATE_IP_FSYS, 9, 0, 0, "biu"), + GATE_A(usb_host, "usb_host", "aclk133", + GATE_IP_FSYS, 12, 0, 0, "usbhost"), + GATE_DA(sclk_fimc0, "exynos4-fimc.0", "sclk_fimc0", "div_fimc0", + SRC_MASK_CAM, 0, CLK_SET_RATE_PARENT, 0, "sclk_fimc"), + GATE_DA(sclk_fimc1, "exynos4-fimc.1", "sclk_fimc1", "div_fimc1", + SRC_MASK_CAM, 4, CLK_SET_RATE_PARENT, 0, "sclk_fimc"), + GATE_DA(sclk_fimc2, "exynos4-fimc.2", "sclk_fimc2", "div_fimc2", + SRC_MASK_CAM, 8, CLK_SET_RATE_PARENT, 0, "sclk_fimc"), + GATE_DA(sclk_fimc3, "exynos4-fimc.3", "sclk_fimc3", "div_fimc3", + SRC_MASK_CAM, 12, CLK_SET_RATE_PARENT, 0, "sclk_fimc"), + GATE_DA(sclk_csis0, "s5p-mipi-csis.0", "sclk_csis0", "div_csis0", + SRC_MASK_CAM, 24, CLK_SET_RATE_PARENT, 0, "sclk_csis"), + GATE_DA(sclk_csis1, "s5p-mipi-csis.1", "sclk_csis1", "div_csis1", + SRC_MASK_CAM, 28, CLK_SET_RATE_PARENT, 0, "sclk_csis"), + GATE_DA(sclk_fimd0, "exynos4-fb.0", "sclk_fimd0", "div_fimd0", + SRC_MASK_LCD0, 0, CLK_SET_RATE_PARENT, 0, "sclk_fimd"), + GATE_DA(sclk_mmc0, "exynos4-sdhci.0", "sclk_mmc0", "div_mmc_pre0", + SRC_MASK_FSYS, 0, CLK_SET_RATE_PARENT, 0, + "mmc_busclk.2"), + GATE_DA(sclk_mmc1, "exynos4-sdhci.1", "sclk_mmc1", "div_mmc_pre1", + SRC_MASK_FSYS, 4, CLK_SET_RATE_PARENT, 0, + "mmc_busclk.2"), + GATE_DA(sclk_mmc2, "exynos4-sdhci.2", "sclk_mmc2", "div_mmc_pre2", + SRC_MASK_FSYS, 8, CLK_SET_RATE_PARENT, 0, + "mmc_busclk.2"), + GATE_DA(sclk_mmc3, "exynos4-sdhci.3", "sclk_mmc3", "div_mmc_pre3", + SRC_MASK_FSYS, 12, CLK_SET_RATE_PARENT, 0, + "mmc_busclk.2"), + GATE_DA(sclk_mmc4, NULL, "sclk_mmc4", "div_mmc_pre4", + SRC_MASK_FSYS, 16, CLK_SET_RATE_PARENT, 0, "ciu"), + GATE_DA(sclk_uart0, "exynos4210-uart.0", "uclk0", "div_uart0", + 0xc350, 0, CLK_SET_RATE_PARENT, 0, "clk_uart_baud0"), + GATE_DA(sclk_uart1, "exynos4210-uart.1", "uclk1", "div_uart1", + 0xc350, 4, CLK_SET_RATE_PARENT, 0, "clk_uart_baud0"), + GATE_DA(sclk_uart2, "exynos4210-uart.2", "uclk2", "div_uart2", + 0xc350, 8, CLK_SET_RATE_PARENT, 0, "clk_uart_baud0"), + GATE_DA(sclk_uart3, "exynos4210-uart.3", "uclk3", "div_uart3", + 0xc350, 12, CLK_SET_RATE_PARENT, 0, "clk_uart_baud0"), + GATE_DA(sclk_uart4, "exynos4210-uart.4", "uclk4", "div_uart4", + 0xc350, 16, CLK_SET_RATE_PARENT, 0, "clk_uart_baud0"), + GATE(sclk_audio2, "sclk_audio2", "div_audio2", 0xc354, 4, + CLK_SET_RATE_PARENT, 0), + GATE_DA(sclk_spi0, "exynos4210-spi.0", "sclk_spi0", "div_spi_pre0", + 0xc354, 16, CLK_SET_RATE_PARENT, 0, "spi_busclk0"), + GATE_DA(sclk_spi1, "exynos4210-spi.1", "sclk_spi1", "div_spi_pre1", + 0xc354, 20, CLK_SET_RATE_PARENT, 0, "spi_busclk0"), + GATE_DA(sclk_spi2, "exynos4210-spi.2", "sclk_spi2", "div_spi_pre2", + 0xc354, 24, CLK_SET_RATE_PARENT, 0, "spi_busclk0"), + GATE_DA(fimc0, "exynos4-fimc.0", "fimc0", "aclk160", + GATE_IP_CAM, 0, 0, 0, "fimc"), + GATE_DA(fimc1, "exynos4-fimc.1", "fimc1", "aclk160", + GATE_IP_CAM, 1, 0, 0, "fimc"), + GATE_DA(fimc2, "exynos4-fimc.2", "fimc2", "aclk160", + GATE_IP_CAM, 2, 0, 0, "fimc"), + GATE_DA(fimc3, "exynos4-fimc.3", "fimc3", "aclk160", + GATE_IP_CAM, 3, 0, 0, "fimc"), + GATE_DA(csis0, "s5p-mipi-csis.0", "csis0", "aclk160", + GATE_IP_CAM, 4, 0, 0, "fimc"), + GATE_DA(csis1, "s5p-mipi-csis.1", "csis1", "aclk160", + GATE_IP_CAM, 5, 0, 0, "fimc"), + GATE_DA(smmu_fimc0, "exynos-sysmmu.5", "smmu_fimc0", "aclk160", + GATE_IP_CAM, 7, 0, 0, "sysmmu"), + GATE_DA(smmu_fimc1, "exynos-sysmmu.6", "smmu_fimc1", "aclk160", + GATE_IP_CAM, 8, 0, 0, "sysmmu"), + GATE_DA(smmu_fimc2, "exynos-sysmmu.7", "smmu_fimc2", "aclk160", + GATE_IP_CAM, 9, 0, 0, "sysmmu"), + GATE_DA(smmu_fimc3, "exynos-sysmmu.8", "smmu_fimc3", "aclk160", + GATE_IP_CAM, 10, 0, 0, "sysmmu"), + GATE_DA(smmu_jpeg, "exynos-sysmmu.3", "smmu_jpeg", "aclk160", + GATE_IP_CAM, 11, 0, 0, "sysmmu"), + GATE_DA(smmu_tv, "exynos-sysmmu.2", "smmu_tv", "aclk160", + GATE_IP_TV, 4, 0, 0, "sysmmu"), + GATE_DA(mfc, "s5p-mfc", "mfc", "aclk100", GATE_IP_MFC, 0, 0, 0, "mfc"), + GATE_DA(smmu_mfcl, "exynos-sysmmu.0", "smmu_mfcl", "aclk100", + GATE_IP_MFC, 1, 0, 0, "sysmmu"), + GATE_DA(smmu_mfcr, "exynos-sysmmu.1", "smmu_mfcr", "aclk100", + GATE_IP_MFC, 2, 0, 0, "sysmmu"), + GATE_DA(fimd0, "exynos4-fb.0", "fimd0", "aclk160", + GATE_IP_LCD0, 0, 0, 0, "fimd"), + GATE_DA(smmu_fimd0, "exynos-sysmmu.10", "smmu_fimd0", "aclk160", + GATE_IP_LCD0, 4, 0, 0, "sysmmu"), + GATE_DA(pdma0, "dma-pl330.0", "pdma0", "aclk133", + GATE_IP_FSYS, 0, 0, 0, "dma"), + GATE_DA(pdma1, "dma-pl330.1", "pdma1", "aclk133", + GATE_IP_FSYS, 1, 0, 0, "dma"), + GATE_DA(sdmmc0, "exynos4-sdhci.0", "sdmmc0", "aclk133", + GATE_IP_FSYS, 5, 0, 0, "hsmmc"), + GATE_DA(sdmmc1, "exynos4-sdhci.1", "sdmmc1", "aclk133", + GATE_IP_FSYS, 6, 0, 0, "hsmmc"), + GATE_DA(sdmmc2, "exynos4-sdhci.2", "sdmmc2", "aclk133", + GATE_IP_FSYS, 7, 0, 0, "hsmmc"), + GATE_DA(sdmmc3, "exynos4-sdhci.3", "sdmmc3", "aclk133", + GATE_IP_FSYS, 8, 0, 0, "hsmmc"), + GATE_DA(uart0, "exynos4210-uart.0", "uart0", "aclk100", + GATE_IP_PERIL, 0, 0, 0, "uart"), + GATE_DA(uart1, "exynos4210-uart.1", "uart1", "aclk100", + GATE_IP_PERIL, 1, 0, 0, "uart"), + GATE_DA(uart2, "exynos4210-uart.2", "uart2", "aclk100", + GATE_IP_PERIL, 2, 0, 0, "uart"), + GATE_DA(uart3, "exynos4210-uart.3", "uart3", "aclk100", + GATE_IP_PERIL, 3, 0, 0, "uart"), + GATE_DA(uart4, "exynos4210-uart.4", "uart4", "aclk100", + GATE_IP_PERIL, 4, 0, 0, "uart"), + GATE_DA(i2c0, "s3c2440-i2c.0", "i2c0", "aclk100", + GATE_IP_PERIL, 6, 0, 0, "i2c"), + GATE_DA(i2c1, "s3c2440-i2c.1", "i2c1", "aclk100", + GATE_IP_PERIL, 7, 0, 0, "i2c"), + GATE_DA(i2c2, "s3c2440-i2c.2", "i2c2", "aclk100", + GATE_IP_PERIL, 8, 0, 0, "i2c"), + GATE_DA(i2c3, "s3c2440-i2c.3", "i2c3", "aclk100", + GATE_IP_PERIL, 9, 0, 0, "i2c"), + GATE_DA(i2c4, "s3c2440-i2c.4", "i2c4", "aclk100", + GATE_IP_PERIL, 10, 0, 0, "i2c"), + GATE_DA(i2c5, "s3c2440-i2c.5", "i2c5", "aclk100", + GATE_IP_PERIL, 11, 0, 0, "i2c"), + GATE_DA(i2c6, "s3c2440-i2c.6", "i2c6", "aclk100", + GATE_IP_PERIL, 12, 0, 0, "i2c"), + GATE_DA(i2c7, "s3c2440-i2c.7", "i2c7", "aclk100", + GATE_IP_PERIL, 13, 0, 0, "i2c"), + GATE_DA(i2c_hdmi, "s3c2440-hdmiphy-i2c", "i2c-hdmi", "aclk100", + GATE_IP_PERIL, 14, 0, 0, "i2c"), + GATE_DA(spi0, "exynos4210-spi.0", "spi0", "aclk100", + GATE_IP_PERIL, 16, 0, 0, "spi"), + GATE_DA(spi1, "exynos4210-spi.1", "spi1", "aclk100", + GATE_IP_PERIL, 17, 0, 0, "spi"), + GATE_DA(spi2, "exynos4210-spi.2", "spi2", "aclk100", + GATE_IP_PERIL, 18, 0, 0, "spi"), + GATE_DA(i2s1, "samsung-i2s.1", "i2s1", "aclk100", + GATE_IP_PERIL, 20, 0, 0, "iis"), + GATE_DA(i2s2, "samsung-i2s.2", "i2s2", "aclk100", + GATE_IP_PERIL, 21, 0, 0, "iis"), + GATE_DA(pcm1, "samsung-pcm.1", "pcm1", "aclk100", + GATE_IP_PERIL, 22, 0, 0, "pcm"), + GATE_DA(pcm2, "samsung-pcm.2", "pcm2", "aclk100", + GATE_IP_PERIL, 23, 0, 0, "pcm"), + GATE_DA(spdif, "samsung-spdif", "spdif", "aclk100", + GATE_IP_PERIL, 26, 0, 0, "spdif"), + GATE_DA(ac97, "samsung-ac97", "ac97", "aclk100", + GATE_IP_PERIL, 27, 0, 0, "ac97"), +}; + +/* list of gate clocks supported in exynos4210 soc */ +struct samsung_gate_clock exynos4210_gate_clks[] __initdata = { + GATE(tvenc, "tvenc", "aclk160", GATE_IP_TV, 2, 0, 0), + GATE(g2d, "g2d", "aclk200", E4210_GATE_IP_IMAGE, 0, 0, 0), + GATE(rotator, "rotator", "aclk200", E4210_GATE_IP_IMAGE, 1, 0, 0), + GATE(mdma, "mdma", "aclk200", E4210_GATE_IP_IMAGE, 2, 0, 0), + GATE(smmu_g2d, "smmu_g2d", "aclk200", E4210_GATE_IP_IMAGE, 3, 0, 0), + GATE(smmu_mdma, "smmu_mdma", "aclk200", E4210_GATE_IP_IMAGE, 5, 0, 0), + GATE(pcie_phy, "pcie_phy", "aclk133", GATE_IP_FSYS, 2, 0, 0), + GATE(sata_phy, "sata_phy", "aclk133", GATE_IP_FSYS, 3, 0, 0), + GATE(sata, "sata", "aclk133", GATE_IP_FSYS, 10, 0, 0), + GATE(pcie, "pcie", "aclk133", GATE_IP_FSYS, 14, 0, 0), + GATE(smmu_pcie, "smmu_pcie", "aclk133", GATE_IP_FSYS, 18, 0, 0), + GATE(modemif, "modemif", "aclk100", GATE_IP_PERIL, 28, 0, 0), + GATE(chipid, "chipid", "aclk100", GATE_IP_PERIR, 0, 0, 0), + GATE(sysreg, "sysreg", "aclk100", GATE_IP_PERIR, 0, 0, 0), + GATE(hdmi_cec, "hdmi_cec", "aclk100", GATE_IP_PERIR, 11, 0, 0), + GATE(smmu_rotator, "smmu_rotator", "aclk200", + E4210_GATE_IP_IMAGE, 4, 0, 0), + GATE(sclk_mipi1, "sclk_mipi1", "div_mipi_pre1", + SRC_MASK_LCD1, 12, CLK_SET_RATE_PARENT, 0), + GATE(sclk_sata, "sclk_sata", "div_sata", + SRC_MASK_FSYS, 24, CLK_SET_RATE_PARENT, 0), + GATE_A(tsadc, "tsadc", "aclk100", GATE_IP_PERIL, 15, 0, 0, "adc"), + GATE_A(mct, "mct", "aclk100", GATE_IP_PERIR, 13, 0, 0, "mct"), + GATE_A(wdt, "watchdog", "aclk100", GATE_IP_PERIR, 14, 0, 0, "watchdog"), + GATE_A(rtc, "rtc", "aclk100", GATE_IP_PERIR, 15, 0, 0, "rtc"), + GATE_A(keyif, "keyif", "aclk100", GATE_IP_PERIR, 16, 0, 0, "keypad"), + GATE_DA(sclk_fimd1, "exynos4-fb.1", "sclk_fimd1", "div_fimd1", + SRC_MASK_LCD1, 0, CLK_SET_RATE_PARENT, 0, "sclk_fimd"), +}; + +/* list of gate clocks supported in exynos4x12 soc */ +struct samsung_gate_clock exynos4x12_gate_clks[] __initdata = { + GATE(audss, "audss", "sclk_epll", E4X12_GATE_IP_MAUDIO, 0, 0, 0), + GATE(mdnie0, "mdnie0", "aclk160", GATE_IP_LCD0, 2, 0, 0), + GATE(rotator, "rotator", "aclk200", E4X12_GATE_IP_IMAGE, 1, 0, 0), + GATE(mdma2, "mdma2", "aclk200", E4X12_GATE_IP_IMAGE, 2, 0, 0), + GATE(smmu_mdma, "smmu_mdma", "aclk200", E4X12_GATE_IP_IMAGE, 5, 0, 0), + GATE(mipi_hsi, "mipi_hsi", "aclk133", GATE_IP_FSYS, 10, 0, 0), + GATE(chipid, "chipid", "aclk100", E4X12_GATE_IP_PERIR, 0, 0, 0), + GATE(sysreg, "sysreg", "aclk100", E4X12_GATE_IP_PERIR, 1, 0, 0), + GATE(hdmi_cec, "hdmi_cec", "aclk100", E4X12_GATE_IP_PERIR, 11, 0, 0), + GATE(sclk_mdnie0, "sclk_mdnie0", "div_mdnie0", + SRC_MASK_LCD0, 4, CLK_SET_RATE_PARENT, 0), + GATE(sclk_mdnie_pwm0, "sclk_mdnie_pwm0", "div_mdnie_pwm_pre0", + SRC_MASK_LCD0, 8, CLK_SET_RATE_PARENT, 0), + GATE(sclk_mipihsi, "sclk_mipihsi", "div_mipihsi", + SRC_MASK_FSYS, 24, CLK_SET_RATE_PARENT, 0), + GATE(smmu_rotator, "smmu_rotator", "aclk200", + E4X12_GATE_IP_IMAGE, 4, 0, 0), + GATE_A(mct, "mct", "aclk100", E4X12_GATE_IP_PERIR, 13, 0, 0, "mct"), + GATE_A(rtc, "rtc", "aclk100", E4X12_GATE_IP_PERIR, 15, 0, 0, "rtc"), + GATE_A(keyif, "keyif", "aclk100", + E4X12_GATE_IP_PERIR, 16, 0, 0, "keypad"), + 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"), +}; + +#ifdef CONFIG_OF +static struct of_device_id exynos4_clk_ids[] __initdata = { + { .compatible = "samsung,exynos4210-clock", + .data = (void *)EXYNOS4210, }, + { .compatible = "samsung,exynos4412-clock", + .data = (void *)EXYNOS4X12, }, + { }, +}; +#endif + +/* + * The parent of the fin_pll clock is selected by the XOM[0] bit. This bit + * resides in chipid register space, outside of the clock controller memory + * mapped space. So to determine the parent of fin_pll clock, the chipid + * controller is first remapped and the value of XOM[0] bit is read to + * determine the parent clock. + */ +static void __init exynos4_clk_register_finpll(void) +{ + struct samsung_fixed_rate_clock fclk; + struct device_node *np; + struct clk *clk; + void __iomem *chipid_base = S5P_VA_CHIPID; + unsigned long xom, finpll_f = 24000000; + char *parent_name; + + np = of_find_compatible_node(NULL, NULL, "samsung,exynos4210-chipid"); + if (np) + chipid_base = of_iomap(np, 0); + + if (chipid_base) { + xom = readl(chipid_base + 8); + parent_name = xom & 1 ? "xusbxti" : "xxti"; + clk = clk_get(NULL, parent_name); + if (IS_ERR(clk)) { + pr_err("%s: failed to lookup parent clock %s, assuming " + "fin_pll clock frequency is 24MHz\n", __func__, + parent_name); + } else { + finpll_f = clk_get_rate(clk); + } + } else { + pr_err("%s: failed to map chipid registers, assuming " + "fin_pll clock frequency is 24MHz\n", __func__); + } + + fclk.id = fin_pll; + fclk.name = "fin_pll"; + fclk.parent_name = NULL; + fclk.flags = CLK_IS_ROOT; + fclk.fixed_rate = finpll_f; + samsung_clk_register_fixed_rate(&fclk, 1); + + if (np) + iounmap(chipid_base); +} + +/* + * This function allows non-dt platforms to specify the clock speed of the + * xxti and xusbxti clocks. These clocks are then registered with the specified + * clock speed. + */ +void __init exynos4_clk_register_fixed_ext(unsigned long xxti_f, + unsigned long xusbxti_f) +{ + exynos4_fixed_rate_ext_clks[0].fixed_rate = xxti_f; + exynos4_fixed_rate_ext_clks[1].fixed_rate = xusbxti_f; + samsung_clk_register_fixed_rate(exynos4_fixed_rate_ext_clks, + ARRAY_SIZE(exynos4_fixed_rate_ext_clks)); +} + +static __initdata struct of_device_id ext_clk_match[] = { + { .compatible = "samsung,clock-xxti", .data = (void *)0, }, + { .compatible = "samsung,clock-xusbxti", .data = (void *)1, }, + {}, +}; + +/* register exynos4 clocks */ +void __init exynos4_clk_init(struct device_node *np) +{ + void __iomem *reg_base; + struct clk *apll, *mpll, *epll, *vpll; + u32 exynos4_soc; + + if (np) { + const struct of_device_id *match; + match = of_match_node(exynos4_clk_ids, np); + exynos4_soc = (u32)match->data; + + reg_base = of_iomap(np, 0); + if (!reg_base) + panic("%s: failed to map registers\n", __func__); + } else { + reg_base = S5P_VA_CMU; + if (soc_is_exynos4210()) + exynos4_soc = EXYNOS4210; + else if (soc_is_exynos4212() || soc_is_exynos4412()) + exynos4_soc = EXYNOS4X12; + else + panic("%s: unable to determine soc\n", __func__); + } + + samsung_clk_init(np, reg_base, nr_clks, + exynos4_clk_regs, ARRAY_SIZE(exynos4_clk_regs)); + + if (np) + samsung_clk_of_register_fixed_ext(exynos4_fixed_rate_ext_clks, + ARRAY_SIZE(exynos4_fixed_rate_ext_clks), + ext_clk_match); + + exynos4_clk_register_finpll(); + + if (exynos4_soc == EXYNOS4210) { + apll = samsung_clk_register_pll45xx("fout_apll", "fin_pll", + reg_base + APLL_CON0, pll_4508); + mpll = samsung_clk_register_pll45xx("fout_mpll", "fin_pll", + reg_base + E4210_MPLL_CON0, pll_4508); + epll = samsung_clk_register_pll46xx("fout_epll", "fin_pll", + reg_base + 0xc110, pll_4600); + vpll = samsung_clk_register_pll46xx("fout_vpll", "mout_vpllsrc", + reg_base + 0xc120, pll_4650c); + } else { + apll = samsung_clk_register_pll35xx("fout_apll", "fin_pll", + reg_base + APLL_CON0); + mpll = samsung_clk_register_pll35xx("fout_mpll", "fin_pll", + reg_base + E4X12_MPLL_CON0); + epll = samsung_clk_register_pll36xx("fout_epll", "fin_pll", + reg_base + 0xc110); + vpll = samsung_clk_register_pll36xx("fout_vpll", "fin_pll", + reg_base + 0xc120); + } + + samsung_clk_add_lookup(apll, fout_apll); + samsung_clk_add_lookup(mpll, fout_mpll); + samsung_clk_add_lookup(epll, fout_epll); + samsung_clk_add_lookup(vpll, fout_vpll); + + samsung_clk_register_fixed_rate(exynos4_fixed_rate_clks, + ARRAY_SIZE(exynos4_fixed_rate_clks)); + samsung_clk_register_mux(exynos4_mux_clks, + ARRAY_SIZE(exynos4_mux_clks)); + samsung_clk_register_div(exynos4_div_clks, + ARRAY_SIZE(exynos4_div_clks)); + samsung_clk_register_gate(exynos4_gate_clks, + ARRAY_SIZE(exynos4_gate_clks)); + + if (exynos4_soc == EXYNOS4210) { + samsung_clk_register_fixed_rate(exynos4210_fixed_rate_clks, + ARRAY_SIZE(exynos4210_fixed_rate_clks)); + samsung_clk_register_mux(exynos4210_mux_clks, + ARRAY_SIZE(exynos4210_mux_clks)); + samsung_clk_register_div(exynos4210_div_clks, + ARRAY_SIZE(exynos4210_div_clks)); + samsung_clk_register_gate(exynos4210_gate_clks, + ARRAY_SIZE(exynos4210_gate_clks)); + } else { + samsung_clk_register_mux(exynos4x12_mux_clks, + ARRAY_SIZE(exynos4x12_mux_clks)); + samsung_clk_register_div(exynos4x12_div_clks, + ARRAY_SIZE(exynos4x12_div_clks)); + samsung_clk_register_gate(exynos4x12_gate_clks, + ARRAY_SIZE(exynos4x12_gate_clks)); + } + + pr_info("%s clocks: sclk_apll = %ld, sclk_mpll = %ld\n" + "\tsclk_epll = %ld, sclk_vpll = %ld, arm_clk = %ld\n", + exynos4_soc == EXYNOS4210 ? "Exynos4210" : "Exynos4x12", + _get_rate("sclk_apll"), _get_rate("sclk_mpll"), + _get_rate("sclk_epll"), _get_rate("sclk_vpll"), + _get_rate("arm_clk")); +} +CLK_OF_DECLARE(exynos4210_clk, "samsung,exynos4210-clock", exynos4_clk_init); +CLK_OF_DECLARE(exynos4412_clk, "samsung,exynos4412-clock", exynos4_clk_init); -- cgit v1.2.3 From 6e3ad26816b7281ce3b51296180aeba5d1528d1c Mon Sep 17 00:00:00 2001 From: Thomas Abraham Date: Sat, 9 Mar 2013 17:02:57 +0900 Subject: clk: exynos5250: register clocks using common clock framework The Exynos5250 clocks are statically listed and registered using the Samsung specific common clock helper functions. Both device tree based clock lookup and clkdev based clock lookups are supported. Signed-off-by: Thomas Abraham Acked-by: Mike Turquette Signed-off-by: Kukjin Kim --- drivers/clk/samsung/Makefile | 1 + drivers/clk/samsung/clk-exynos5250.c | 514 +++++++++++++++++++++++++++++++++++ 2 files changed, 515 insertions(+) create mode 100644 drivers/clk/samsung/clk-exynos5250.c (limited to 'drivers/clk') diff --git a/drivers/clk/samsung/Makefile b/drivers/clk/samsung/Makefile index 8862f0db82b7..f18fb0718157 100644 --- a/drivers/clk/samsung/Makefile +++ b/drivers/clk/samsung/Makefile @@ -4,3 +4,4 @@ obj-$(CONFIG_COMMON_CLK) += clk.o clk-pll.o obj-$(CONFIG_ARCH_EXYNOS4) += clk-exynos4.o +obj-$(CONFIG_SOC_EXYNOS5250) += clk-exynos5250.o diff --git a/drivers/clk/samsung/clk-exynos5250.c b/drivers/clk/samsung/clk-exynos5250.c new file mode 100644 index 000000000000..115212525dd2 --- /dev/null +++ b/drivers/clk/samsung/clk-exynos5250.c @@ -0,0 +1,514 @@ +/* + * Copyright (c) 2013 Samsung Electronics Co., Ltd. + * Copyright (c) 2013 Linaro Ltd. + * Author: Thomas Abraham + * + * 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. + * + * Common Clock Framework support for Exynos5250 SoC. +*/ + +#include +#include +#include +#include +#include + +#include +#include "clk.h" +#include "clk-pll.h" + +#define SRC_CPU 0x200 +#define DIV_CPU0 0x500 +#define SRC_CORE1 0x4204 +#define SRC_TOP0 0x10210 +#define SRC_TOP2 0x10218 +#define SRC_GSCL 0x10220 +#define SRC_DISP1_0 0x1022c +#define SRC_MAU 0x10240 +#define SRC_FSYS 0x10244 +#define SRC_GEN 0x10248 +#define SRC_PERIC0 0x10250 +#define SRC_PERIC1 0x10254 +#define SRC_MASK_GSCL 0x10320 +#define SRC_MASK_DISP1_0 0x1032c +#define SRC_MASK_MAU 0x10334 +#define SRC_MASK_FSYS 0x10340 +#define SRC_MASK_GEN 0x10344 +#define SRC_MASK_PERIC0 0x10350 +#define SRC_MASK_PERIC1 0x10354 +#define DIV_TOP0 0x10510 +#define DIV_TOP1 0x10514 +#define DIV_GSCL 0x10520 +#define DIV_DISP1_0 0x1052c +#define DIV_GEN 0x1053c +#define DIV_MAU 0x10544 +#define DIV_FSYS0 0x10548 +#define DIV_FSYS1 0x1054c +#define DIV_FSYS2 0x10550 +#define DIV_PERIC0 0x10558 +#define DIV_PERIC1 0x1055c +#define DIV_PERIC2 0x10560 +#define DIV_PERIC3 0x10564 +#define DIV_PERIC4 0x10568 +#define DIV_PERIC5 0x1056c +#define GATE_IP_GSCL 0x10920 +#define GATE_IP_MFC 0x1092c +#define GATE_IP_GEN 0x10934 +#define GATE_IP_FSYS 0x10944 +#define GATE_IP_PERIC 0x10950 +#define GATE_IP_PERIS 0x10960 +#define SRC_CDREX 0x20200 +#define PLL_DIV2_SEL 0x20a24 + +/* + * Let each supported clock get a unique id. This id is used to lookup the clock + * for device tree based platforms. The clocks are categorized into three + * sections: core, sclk gate and bus interface gate clocks. + * + * When adding a new clock to this list, it is advised to choose a clock + * category and add it to the end of that category. That is because the the + * device tree source file is referring to these ids and any change in the + * sequence number of existing clocks will require corresponding change in the + * device tree files. This limitation would go away when pre-processor support + * for dtc would be available. + */ +enum exynos5250_clks { + none, + + /* core clocks */ + fin_pll, + + /* gate for special clocks (sclk) */ + sclk_cam_bayer = 128, sclk_cam0, sclk_cam1, sclk_gscl_wa, sclk_gscl_wb, + sclk_fimd1, sclk_mipi1, sclk_dp, sclk_hdmi, sclk_pixel, sclk_audio0, + sclk_mmc0, sclk_mmc1, sclk_mmc2, sclk_mmc3, sclk_sata, sclk_usb3, + sclk_jpeg, sclk_uart0, sclk_uart1, sclk_uart2, sclk_uart3, sclk_pwm, + sclk_audio1, sclk_audio2, sclk_spdif, sclk_spi0, sclk_spi1, sclk_spi2, + + /* gate clocks */ + gscl0 = 256, gscl1, gscl2, gscl3, gscl_wa, gscl_wb, smmu_gscl0, + smmu_gscl1, smmu_gscl2, smmu_gscl3, mfc, smmu_mfcl, smmu_mfcr, rotator, + jpeg, mdma1, smmu_rotator, smmu_jpeg, smmu_mdma1, pdma0, pdma1, sata, + usbotg, mipi_hsi, sdmmc0, sdmmc1, sdmmc2, sdmmc3, sromc, usb2, usb3, + sata_phyctrl, sata_phyi2c, uart0, uart1, uart2, uart3, uart4, i2c0, + i2c1, i2c2, i2c3, i2c4, i2c5, i2c6, i2c7, i2c_hdmi, adc, spi0, spi1, + spi2, i2s1, i2s2, pcm1, pcm2, pwm, spdif, ac97, hsi2c0, hsi2c1, hsi2c2, + hsi2c3, chipid, sysreg, pmu, cmu_top, cmu_core, cmu_mem, tzpc0, tzpc1, + tzpc2, tzpc3, tzpc4, tzpc5, tzpc6, tzpc7, tzpc8, tzpc9, hdmi_cec, mct, + wdt, rtc, tmu, + + nr_clks, +}; + +/* + * list of controller registers to be saved and restored during a + * suspend/resume cycle. + */ +static __initdata unsigned long exynos5250_clk_regs[] = { + SRC_CPU, + DIV_CPU0, + SRC_CORE1, + SRC_TOP0, + SRC_TOP2, + SRC_GSCL, + SRC_DISP1_0, + SRC_MAU, + SRC_FSYS, + SRC_GEN, + SRC_PERIC0, + SRC_PERIC1, + SRC_MASK_GSCL, + SRC_MASK_DISP1_0, + SRC_MASK_MAU, + SRC_MASK_FSYS, + SRC_MASK_GEN, + SRC_MASK_PERIC0, + SRC_MASK_PERIC1, + DIV_TOP0, + DIV_TOP1, + DIV_GSCL, + DIV_DISP1_0, + DIV_GEN, + DIV_MAU, + DIV_FSYS0, + DIV_FSYS1, + DIV_FSYS2, + DIV_PERIC0, + DIV_PERIC1, + DIV_PERIC2, + DIV_PERIC3, + DIV_PERIC4, + DIV_PERIC5, + GATE_IP_GSCL, + GATE_IP_MFC, + GATE_IP_GEN, + GATE_IP_FSYS, + GATE_IP_PERIC, + GATE_IP_PERIS, + SRC_CDREX, + PLL_DIV2_SEL, +}; + +/* list of all parent clock list */ +PNAME(mout_apll_p) = { "fin_pll", "fout_apll", }; +PNAME(mout_cpu_p) = { "mout_apll", "mout_mpll", }; +PNAME(mout_mpll_fout_p) = { "fout_mplldiv2", "fout_mpll" }; +PNAME(mout_mpll_p) = { "fin_pll", "mout_mpll_fout" }; +PNAME(mout_bpll_fout_p) = { "fout_bplldiv2", "fout_bpll" }; +PNAME(mout_bpll_p) = { "fin_pll", "mout_bpll_fout" }; +PNAME(mout_vpllsrc_p) = { "fin_pll", "sclk_hdmi27m" }; +PNAME(mout_vpll_p) = { "mout_vpllsrc", "fout_vpll" }; +PNAME(mout_cpll_p) = { "fin_pll", "fout_cpll" }; +PNAME(mout_epll_p) = { "fin_pll", "fout_epll" }; +PNAME(mout_mpll_user_p) = { "fin_pll", "sclk_mpll" }; +PNAME(mout_bpll_user_p) = { "fin_pll", "sclk_bpll" }; +PNAME(mout_aclk166_p) = { "sclk_cpll", "sclk_mpll_user" }; +PNAME(mout_aclk200_p) = { "sclk_mpll_user", "sclk_bpll_user" }; +PNAME(mout_hdmi_p) = { "div_hdmi_pixel", "sclk_hdmiphy" }; +PNAME(mout_usb3_p) = { "sclk_mpll_user", "sclk_cpll" }; +PNAME(mout_group1_p) = { "fin_pll", "fin_pll", "sclk_hdmi27m", + "sclk_dptxphy", "sclk_uhostphy", "sclk_hdmiphy", + "sclk_mpll_user", "sclk_epll", "sclk_vpll", + "sclk_cpll" }; +PNAME(mout_audio0_p) = { "cdclk0", "fin_pll", "sclk_hdmi27m", "sclk_dptxphy", + "sclk_uhostphy", "sclk_hdmiphy", + "sclk_mpll_user", "sclk_epll", "sclk_vpll", + "sclk_cpll" }; +PNAME(mout_audio1_p) = { "cdclk1", "fin_pll", "sclk_hdmi27m", "sclk_dptxphy", + "sclk_uhostphy", "sclk_hdmiphy", + "sclk_mpll_user", "sclk_epll", "sclk_vpll", + "sclk_cpll" }; +PNAME(mout_audio2_p) = { "cdclk2", "fin_pll", "sclk_hdmi27m", "sclk_dptxphy", + "sclk_uhostphy", "sclk_hdmiphy", + "sclk_mpll_user", "sclk_epll", "sclk_vpll", + "sclk_cpll" }; +PNAME(mout_spdif_p) = { "sclk_audio0", "sclk_audio1", "sclk_audio2", + "spdif_extclk" }; + +/* fixed rate clocks generated outside the soc */ +struct samsung_fixed_rate_clock exynos5250_fixed_rate_ext_clks[] __initdata = { + FRATE(fin_pll, "fin_pll", NULL, CLK_IS_ROOT, 0), +}; + +/* fixed rate clocks generated inside the soc */ +struct samsung_fixed_rate_clock exynos5250_fixed_rate_clks[] __initdata = { + FRATE(none, "sclk_hdmiphy", NULL, CLK_IS_ROOT, 24000000), + FRATE(none, "sclk_hdmi27m", NULL, CLK_IS_ROOT, 27000000), + FRATE(none, "sclk_dptxphy", NULL, CLK_IS_ROOT, 24000000), + FRATE(none, "sclk_uhostphy", NULL, CLK_IS_ROOT, 48000000), +}; + +struct samsung_fixed_factor_clock exynos5250_fixed_factor_clks[] __initdata = { + FFACTOR(none, "fout_mplldiv2", "fout_mpll", 1, 2, 0), + FFACTOR(none, "fout_bplldiv2", "fout_bpll", 1, 2, 0), +}; + +struct samsung_mux_clock exynos5250_mux_clks[] __initdata = { + MUX(none, "mout_apll", mout_apll_p, SRC_CPU, 0, 1), + MUX(none, "mout_cpu", mout_cpu_p, SRC_CPU, 16, 1), + MUX(none, "mout_mpll_fout", mout_mpll_fout_p, PLL_DIV2_SEL, 4, 1), + MUX(none, "sclk_mpll", mout_mpll_p, SRC_CORE1, 8, 1), + MUX(none, "mout_bpll_fout", mout_bpll_fout_p, PLL_DIV2_SEL, 0, 1), + MUX(none, "sclk_bpll", mout_bpll_p, SRC_CDREX, 0, 1), + MUX(none, "mout_vpllsrc", mout_vpllsrc_p, SRC_TOP2, 0, 1), + MUX(none, "sclk_vpll", mout_vpll_p, SRC_TOP2, 16, 1), + MUX(none, "sclk_epll", mout_epll_p, SRC_TOP2, 12, 1), + MUX(none, "sclk_cpll", mout_cpll_p, SRC_TOP2, 8, 1), + MUX(none, "sclk_mpll_user", mout_mpll_user_p, SRC_TOP2, 20, 1), + MUX(none, "sclk_bpll_user", mout_bpll_user_p, SRC_TOP2, 24, 1), + MUX(none, "mout_aclk166", mout_aclk166_p, SRC_TOP0, 8, 1), + MUX(none, "mout_aclk333", mout_aclk166_p, SRC_TOP0, 16, 1), + MUX(none, "mout_aclk200", mout_aclk200_p, SRC_TOP0, 12, 1), + MUX(none, "mout_cam_bayer", mout_group1_p, SRC_GSCL, 12, 4), + MUX(none, "mout_cam0", mout_group1_p, SRC_GSCL, 16, 4), + MUX(none, "mout_cam1", mout_group1_p, SRC_GSCL, 20, 4), + MUX(none, "mout_gscl_wa", mout_group1_p, SRC_GSCL, 24, 4), + MUX(none, "mout_gscl_wb", mout_group1_p, SRC_GSCL, 28, 4), + MUX(none, "mout_fimd1", mout_group1_p, SRC_DISP1_0, 0, 4), + MUX(none, "mout_mipi1", mout_group1_p, SRC_DISP1_0, 12, 4), + MUX(none, "mout_dp", mout_group1_p, SRC_DISP1_0, 16, 4), + MUX(none, "mout_hdmi", mout_hdmi_p, SRC_DISP1_0, 20, 1), + MUX(none, "mout_audio0", mout_audio0_p, SRC_MAU, 0, 4), + MUX(none, "mout_mmc0", mout_group1_p, SRC_FSYS, 0, 4), + MUX(none, "mout_mmc1", mout_group1_p, SRC_FSYS, 4, 4), + MUX(none, "mout_mmc2", mout_group1_p, SRC_FSYS, 8, 4), + MUX(none, "mout_mmc3", mout_group1_p, SRC_FSYS, 12, 4), + MUX(none, "mout_sata", mout_aclk200_p, SRC_FSYS, 24, 1), + MUX(none, "mout_usb3", mout_usb3_p, SRC_FSYS, 28, 1), + MUX(none, "mout_jpeg", mout_group1_p, SRC_GEN, 0, 4), + MUX(none, "mout_uart0", mout_group1_p, SRC_PERIC0, 0, 4), + MUX(none, "mout_uart1", mout_group1_p, SRC_PERIC0, 4, 4), + MUX(none, "mout_uart2", mout_group1_p, SRC_PERIC0, 8, 4), + MUX(none, "mout_uart3", mout_group1_p, SRC_PERIC0, 12, 4), + MUX(none, "mout_pwm", mout_group1_p, SRC_PERIC0, 24, 4), + MUX(none, "mout_audio1", mout_audio1_p, SRC_PERIC1, 0, 4), + MUX(none, "mout_audio2", mout_audio2_p, SRC_PERIC1, 4, 4), + MUX(none, "mout_spdif", mout_spdif_p, SRC_PERIC1, 8, 2), + MUX(none, "mout_spi0", mout_group1_p, SRC_PERIC1, 16, 4), + MUX(none, "mout_spi1", mout_group1_p, SRC_PERIC1, 20, 4), + MUX(none, "mout_spi2", mout_group1_p, SRC_PERIC1, 24, 4), +}; + +struct samsung_div_clock exynos5250_div_clks[] __initdata = { + DIV(none, "div_arm", "mout_cpu", DIV_CPU0, 0, 3), + DIV(none, "sclk_apll", "mout_apll", DIV_CPU0, 24, 3), + DIV(none, "aclk66_pre", "sclk_mpll_user", DIV_TOP1, 24, 3), + DIV(none, "aclk66", "aclk66_pre", DIV_TOP0, 0, 3), + DIV(none, "aclk266", "sclk_mpll_user", DIV_TOP0, 16, 3), + DIV(none, "aclk166", "mout_aclk166", DIV_TOP0, 8, 3), + DIV(none, "aclk333", "mout_aclk333", DIV_TOP0, 20, 3), + DIV(none, "aclk200", "mout_aclk200", DIV_TOP0, 12, 3), + DIV(none, "div_cam_bayer", "mout_cam_bayer", DIV_GSCL, 12, 4), + DIV(none, "div_cam0", "mout_cam0", DIV_GSCL, 16, 4), + DIV(none, "div_cam1", "mout_cam1", DIV_GSCL, 20, 4), + DIV(none, "div_gscl_wa", "mout_gscl_wa", DIV_GSCL, 24, 4), + DIV(none, "div_gscl_wb", "mout_gscl_wb", DIV_GSCL, 28, 4), + DIV(none, "div_fimd1", "mout_fimd1", DIV_DISP1_0, 0, 4), + DIV(none, "div_mipi1", "mout_mipi1", DIV_DISP1_0, 16, 4), + DIV(none, "div_dp", "mout_dp", DIV_DISP1_0, 24, 4), + DIV(none, "div_jpeg", "mout_jpeg", DIV_GEN, 4, 4), + DIV(none, "div_audio0", "mout_audio0", DIV_MAU, 0, 4), + DIV(none, "div_pcm0", "sclk_audio0", DIV_MAU, 4, 8), + DIV(none, "div_sata", "mout_sata", DIV_FSYS0, 20, 4), + DIV(none, "div_usb3", "mout_usb3", DIV_FSYS0, 24, 4), + DIV(none, "div_mmc0", "mout_mmc0", DIV_FSYS1, 0, 4), + DIV(none, "div_mmc1", "mout_mmc1", DIV_FSYS1, 16, 4), + DIV(none, "div_mmc2", "mout_mmc2", DIV_FSYS2, 0, 4), + DIV(none, "div_mmc3", "mout_mmc3", DIV_FSYS2, 16, 4), + DIV(none, "div_uart0", "mout_uart0", DIV_PERIC0, 0, 4), + DIV(none, "div_uart1", "mout_uart1", DIV_PERIC0, 4, 4), + DIV(none, "div_uart2", "mout_uart2", DIV_PERIC0, 8, 4), + DIV(none, "div_uart3", "mout_uart3", DIV_PERIC0, 12, 4), + DIV(none, "div_spi0", "mout_spi0", DIV_PERIC1, 0, 4), + DIV(none, "div_spi1", "mout_spi1", DIV_PERIC1, 16, 4), + DIV(none, "div_spi2", "mout_spi2", DIV_PERIC2, 0, 4), + DIV(none, "div_pwm", "mout_pwm", DIV_PERIC3, 0, 4), + DIV(none, "div_audio1", "mout_audio1", DIV_PERIC4, 0, 4), + DIV(none, "div_pcm1", "sclk_audio1", DIV_PERIC4, 4, 8), + DIV(none, "div_audio2", "mout_audio2", DIV_PERIC4, 16, 4), + DIV(none, "div_pcm2", "sclk_audio2", DIV_PERIC4, 20, 8), + DIV(none, "div_i2s1", "sclk_audio1", DIV_PERIC5, 0, 6), + DIV(none, "div_i2s2", "sclk_audio2", DIV_PERIC5, 8, 6), + DIV(sclk_pixel, "div_hdmi_pixel", "sclk_vpll", DIV_DISP1_0, 28, 4), + DIV_A(none, "armclk", "div_arm", DIV_CPU0, 28, 3, "armclk"), + DIV_F(none, "div_mipi1_pre", "div_mipi1", + DIV_DISP1_0, 20, 4, CLK_SET_RATE_PARENT, 0), + DIV_F(none, "div_mmc_pre0", "div_mmc0", + DIV_FSYS1, 8, 8, CLK_SET_RATE_PARENT, 0), + DIV_F(none, "div_mmc_pre1", "div_mmc1", + DIV_FSYS1, 24, 8, CLK_SET_RATE_PARENT, 0), + DIV_F(none, "div_mmc_pre2", "div_mmc2", + DIV_FSYS2, 8, 8, CLK_SET_RATE_PARENT, 0), + DIV_F(none, "div_mmc_pre3", "div_mmc3", + DIV_FSYS2, 24, 8, CLK_SET_RATE_PARENT, 0), + DIV_F(none, "div_spi_pre0", "div_spi0", + DIV_PERIC1, 8, 8, CLK_SET_RATE_PARENT, 0), + DIV_F(none, "div_spi_pre1", "div_spi1", + DIV_PERIC1, 24, 8, CLK_SET_RATE_PARENT, 0), + DIV_F(none, "div_spi_pre2", "div_spi2", + DIV_PERIC2, 8, 8, CLK_SET_RATE_PARENT, 0), +}; + +struct samsung_gate_clock exynos5250_gate_clks[] __initdata = { + GATE(gscl0, "gscl0", "none", GATE_IP_GSCL, 0, 0, 0), + GATE(gscl1, "gscl1", "none", GATE_IP_GSCL, 1, 0, 0), + GATE(gscl2, "gscl2", "aclk266", GATE_IP_GSCL, 2, 0, 0), + GATE(gscl3, "gscl3", "aclk266", GATE_IP_GSCL, 3, 0, 0), + GATE(gscl_wa, "gscl_wa", "div_gscl_wa", GATE_IP_GSCL, 5, 0, 0), + GATE(gscl_wb, "gscl_wb", "div_gscl_wb", GATE_IP_GSCL, 6, 0, 0), + GATE(smmu_gscl0, "smmu_gscl0", "aclk266", GATE_IP_GSCL, 7, 0, 0), + GATE(smmu_gscl1, "smmu_gscl1", "aclk266", GATE_IP_GSCL, 8, 0, 0), + GATE(smmu_gscl2, "smmu_gscl2", "aclk266", GATE_IP_GSCL, 9, 0, 0), + GATE(smmu_gscl3, "smmu_gscl3", "aclk266", GATE_IP_GSCL, 10, 0, 0), + GATE(mfc, "mfc", "aclk333", GATE_IP_MFC, 0, 0, 0), + GATE(smmu_mfcl, "smmu_mfcl", "aclk333", GATE_IP_MFC, 1, 0, 0), + GATE(smmu_mfcr, "smmu_mfcr", "aclk333", GATE_IP_MFC, 2, 0, 0), + GATE(rotator, "rotator", "aclk266", GATE_IP_GEN, 1, 0, 0), + GATE(jpeg, "jpeg", "aclk166", GATE_IP_GEN, 2, 0, 0), + GATE(mdma1, "mdma1", "aclk266", GATE_IP_GEN, 4, 0, 0), + GATE(smmu_rotator, "smmu_rotator", "aclk266", GATE_IP_GEN, 6, 0, 0), + GATE(smmu_jpeg, "smmu_jpeg", "aclk166", GATE_IP_GEN, 7, 0, 0), + GATE(smmu_mdma1, "smmu_mdma1", "aclk266", GATE_IP_GEN, 9, 0, 0), + GATE(pdma0, "pdma0", "aclk200", GATE_IP_FSYS, 1, 0, 0), + GATE(pdma1, "pdma1", "aclk200", GATE_IP_FSYS, 2, 0, 0), + GATE(sata, "sata", "aclk200", GATE_IP_FSYS, 6, 0, 0), + GATE(usbotg, "usbotg", "aclk200", GATE_IP_FSYS, 7, 0, 0), + GATE(mipi_hsi, "mipi_hsi", "aclk200", GATE_IP_FSYS, 8, 0, 0), + GATE(sdmmc0, "sdmmc0", "aclk200", GATE_IP_FSYS, 12, 0, 0), + GATE(sdmmc1, "sdmmc1", "aclk200", GATE_IP_FSYS, 13, 0, 0), + GATE(sdmmc2, "sdmmc2", "aclk200", GATE_IP_FSYS, 14, 0, 0), + GATE(sdmmc3, "sdmmc3", "aclk200", GATE_IP_FSYS, 15, 0, 0), + GATE(sromc, "sromc", "aclk200", GATE_IP_FSYS, 17, 0, 0), + GATE(usb2, "usb2", "aclk200", GATE_IP_FSYS, 18, 0, 0), + GATE(usb3, "usb3", "aclk200", GATE_IP_FSYS, 19, 0, 0), + GATE(sata_phyctrl, "sata_phyctrl", "aclk200", GATE_IP_FSYS, 24, 0, 0), + GATE(sata_phyi2c, "sata_phyi2c", "aclk200", GATE_IP_FSYS, 25, 0, 0), + GATE(uart0, "uart0", "aclk66", GATE_IP_PERIC, 0, 0, 0), + GATE(uart1, "uart1", "aclk66", GATE_IP_PERIC, 1, 0, 0), + GATE(uart2, "uart2", "aclk66", GATE_IP_PERIC, 2, 0, 0), + GATE(uart3, "uart3", "aclk66", GATE_IP_PERIC, 3, 0, 0), + GATE(uart4, "uart4", "aclk66", GATE_IP_PERIC, 4, 0, 0), + GATE(i2c0, "i2c0", "aclk66", GATE_IP_PERIC, 6, 0, 0), + GATE(i2c1, "i2c1", "aclk66", GATE_IP_PERIC, 7, 0, 0), + GATE(i2c2, "i2c2", "aclk66", GATE_IP_PERIC, 8, 0, 0), + GATE(i2c3, "i2c3", "aclk66", GATE_IP_PERIC, 9, 0, 0), + GATE(i2c4, "i2c4", "aclk66", GATE_IP_PERIC, 10, 0, 0), + GATE(i2c5, "i2c5", "aclk66", GATE_IP_PERIC, 11, 0, 0), + GATE(i2c6, "i2c6", "aclk66", GATE_IP_PERIC, 12, 0, 0), + GATE(i2c7, "i2c7", "aclk66", GATE_IP_PERIC, 13, 0, 0), + GATE(i2c_hdmi, "i2c_hdmi", "aclk66", GATE_IP_PERIC, 14, 0, 0), + GATE(adc, "adc", "aclk66", GATE_IP_PERIC, 15, 0, 0), + GATE(spi0, "spi0", "aclk66", GATE_IP_PERIC, 16, 0, 0), + GATE(spi1, "spi1", "aclk66", GATE_IP_PERIC, 17, 0, 0), + GATE(spi2, "spi2", "aclk66", GATE_IP_PERIC, 18, 0, 0), + GATE(i2s1, "i2s1", "aclk66", GATE_IP_PERIC, 20, 0, 0), + GATE(i2s2, "i2s2", "aclk66", GATE_IP_PERIC, 21, 0, 0), + GATE(pcm1, "pcm1", "aclk66", GATE_IP_PERIC, 22, 0, 0), + GATE(pcm2, "pcm2", "aclk66", GATE_IP_PERIC, 23, 0, 0), + GATE(pwm, "pwm", "aclk66", GATE_IP_PERIC, 24, 0, 0), + GATE(spdif, "spdif", "aclk66", GATE_IP_PERIC, 26, 0, 0), + GATE(ac97, "ac97", "aclk66", GATE_IP_PERIC, 27, 0, 0), + GATE(hsi2c0, "hsi2c0", "aclk66", GATE_IP_PERIC, 28, 0, 0), + GATE(hsi2c1, "hsi2c1", "aclk66", GATE_IP_PERIC, 29, 0, 0), + GATE(hsi2c2, "hsi2c2", "aclk66", GATE_IP_PERIC, 30, 0, 0), + GATE(hsi2c3, "hsi2c3", "aclk66", GATE_IP_PERIC, 31, 0, 0), + GATE(chipid, "chipid", "aclk66", GATE_IP_PERIS, 0, 0, 0), + GATE(sysreg, "sysreg", "aclk66", GATE_IP_PERIS, 1, 0, 0), + GATE(pmu, "pmu", "aclk66", GATE_IP_PERIS, 2, 0, 0), + GATE(tzpc0, "tzpc0", "aclk66", GATE_IP_PERIS, 6, 0, 0), + GATE(tzpc1, "tzpc1", "aclk66", GATE_IP_PERIS, 7, 0, 0), + GATE(tzpc2, "tzpc2", "aclk66", GATE_IP_PERIS, 8, 0, 0), + GATE(tzpc3, "tzpc3", "aclk66", GATE_IP_PERIS, 9, 0, 0), + GATE(tzpc4, "tzpc4", "aclk66", GATE_IP_PERIS, 10, 0, 0), + GATE(tzpc5, "tzpc5", "aclk66", GATE_IP_PERIS, 11, 0, 0), + GATE(tzpc6, "tzpc6", "aclk66", GATE_IP_PERIS, 12, 0, 0), + GATE(tzpc7, "tzpc7", "aclk66", GATE_IP_PERIS, 13, 0, 0), + GATE(tzpc8, "tzpc8", "aclk66", GATE_IP_PERIS, 14, 0, 0), + GATE(tzpc9, "tzpc9", "aclk66", GATE_IP_PERIS, 15, 0, 0), + GATE(hdmi_cec, "hdmi_cec", "aclk66", GATE_IP_PERIS, 16, 0, 0), + GATE(mct, "mct", "aclk66", GATE_IP_PERIS, 18, 0, 0), + GATE(wdt, "wdt", "aclk66", GATE_IP_PERIS, 19, 0, 0), + GATE(rtc, "rtc", "aclk66", GATE_IP_PERIS, 20, 0, 0), + GATE(tmu, "tmu", "aclk66", GATE_IP_PERIS, 21, 0, 0), + GATE(cmu_top, "cmu_top", "aclk66", + GATE_IP_PERIS, 3, CLK_IGNORE_UNUSED, 0), + GATE(cmu_core, "cmu_core", "aclk66", + GATE_IP_PERIS, 4, CLK_IGNORE_UNUSED, 0), + GATE(cmu_mem, "cmu_mem", "aclk66", + GATE_IP_PERIS, 5, CLK_IGNORE_UNUSED, 0), + GATE(sclk_cam_bayer, "sclk_cam_bayer", "div_cam_bayer", + SRC_MASK_GSCL, 12, CLK_SET_RATE_PARENT, 0), + GATE(sclk_cam0, "sclk_cam0", "div_cam0", + SRC_MASK_GSCL, 16, CLK_SET_RATE_PARENT, 0), + GATE(sclk_cam1, "sclk_cam1", "div_cam1", + SRC_MASK_GSCL, 20, CLK_SET_RATE_PARENT, 0), + GATE(sclk_gscl_wa, "sclk_gscl_wa", "div_gscl_wa", + SRC_MASK_GSCL, 24, CLK_SET_RATE_PARENT, 0), + GATE(sclk_gscl_wb, "sclk_gscl_wb", "div_gscl_wb", + SRC_MASK_GSCL, 28, CLK_SET_RATE_PARENT, 0), + GATE(sclk_fimd1, "sclk_fimd1", "div_fimd1", + SRC_MASK_DISP1_0, 0, CLK_SET_RATE_PARENT, 0), + GATE(sclk_mipi1, "sclk_mipi1", "div_mipi1", + SRC_MASK_DISP1_0, 12, CLK_SET_RATE_PARENT, 0), + GATE(sclk_dp, "sclk_dp", "div_dp", + SRC_MASK_DISP1_0, 16, CLK_SET_RATE_PARENT, 0), + GATE(sclk_hdmi, "sclk_hdmi", "mout_hdmi", + SRC_MASK_DISP1_0, 20, 0, 0), + GATE(sclk_audio0, "sclk_audio0", "div_audio0", + SRC_MASK_MAU, 0, CLK_SET_RATE_PARENT, 0), + GATE(sclk_mmc0, "sclk_mmc0", "div_mmc0", + SRC_MASK_FSYS, 0, CLK_SET_RATE_PARENT, 0), + GATE(sclk_mmc1, "sclk_mmc1", "div_mmc1", + SRC_MASK_FSYS, 4, CLK_SET_RATE_PARENT, 0), + GATE(sclk_mmc2, "sclk_mmc2", "div_mmc2", + SRC_MASK_FSYS, 8, CLK_SET_RATE_PARENT, 0), + GATE(sclk_mmc3, "sclk_mmc3", "div_mmc3", + SRC_MASK_FSYS, 12, CLK_SET_RATE_PARENT, 0), + GATE(sclk_sata, "sclk_sata", "div_sata", + SRC_MASK_FSYS, 24, CLK_SET_RATE_PARENT, 0), + GATE(sclk_usb3, "sclk_usb3", "div_usb3", + SRC_MASK_FSYS, 28, CLK_SET_RATE_PARENT, 0), + GATE(sclk_jpeg, "sclk_jpeg", "div_jpeg", + SRC_MASK_GEN, 0, CLK_SET_RATE_PARENT, 0), + GATE(sclk_uart0, "sclk_uart0", "div_uart0", + SRC_MASK_PERIC0, 0, CLK_SET_RATE_PARENT, 0), + GATE(sclk_uart1, "sclk_uart1", "div_uart1", + SRC_MASK_PERIC0, 4, CLK_SET_RATE_PARENT, 0), + GATE(sclk_uart2, "sclk_uart2", "div_uart2", + SRC_MASK_PERIC0, 8, CLK_SET_RATE_PARENT, 0), + GATE(sclk_uart3, "sclk_uart3", "div_uart3", + SRC_MASK_PERIC0, 12, CLK_SET_RATE_PARENT, 0), + GATE(sclk_pwm, "sclk_pwm", "div_pwm", + SRC_MASK_PERIC0, 24, CLK_SET_RATE_PARENT, 0), + GATE(sclk_audio1, "sclk_audio1", "div_audio1", + SRC_MASK_PERIC1, 0, CLK_SET_RATE_PARENT, 0), + GATE(sclk_audio2, "sclk_audio2", "div_audio2", + SRC_MASK_PERIC1, 4, CLK_SET_RATE_PARENT, 0), + GATE(sclk_spdif, "sclk_spdif", "mout_spdif", + SRC_MASK_PERIC1, 4, 0, 0), + GATE(sclk_spi0, "sclk_spi0", "div_spi_pre0", + SRC_MASK_PERIC1, 16, CLK_SET_RATE_PARENT, 0), + GATE(sclk_spi1, "sclk_spi1", "div_spi_pre1", + SRC_MASK_PERIC1, 20, CLK_SET_RATE_PARENT, 0), + GATE(sclk_spi2, "sclk_spi2", "div_spi_pre2", + SRC_MASK_PERIC1, 24, CLK_SET_RATE_PARENT, 0), +}; + +static __initdata struct of_device_id ext_clk_match[] = { + { .compatible = "samsung,clock-xxti", .data = (void *)0, }, + { }, +}; + +/* register exynox5250 clocks */ +void __init exynos5250_clk_init(struct device_node *np) +{ + void __iomem *reg_base; + struct clk *apll, *mpll, *epll, *vpll, *bpll, *gpll, *cpll; + + if (np) { + reg_base = of_iomap(np, 0); + if (!reg_base) + panic("%s: failed to map registers\n", __func__); + } else { + panic("%s: unable to determine soc\n", __func__); + } + + samsung_clk_init(np, reg_base, nr_clks, + exynos5250_clk_regs, ARRAY_SIZE(exynos5250_clk_regs)); + samsung_clk_of_register_fixed_ext(exynos5250_fixed_rate_ext_clks, + ARRAY_SIZE(exynos5250_fixed_rate_ext_clks), + ext_clk_match); + + apll = samsung_clk_register_pll35xx("fout_apll", "fin_pll", + reg_base + 0x100); + mpll = samsung_clk_register_pll35xx("fout_mpll", "fin_pll", + reg_base + 0x4100); + bpll = samsung_clk_register_pll35xx("fout_bpll", "fin_pll", + reg_base + 0x20110); + gpll = samsung_clk_register_pll35xx("fout_gpll", "fin_pll", + reg_base + 0x10150); + cpll = samsung_clk_register_pll35xx("fout_cpll", "fin_pll", + reg_base + 0x10120); + epll = samsung_clk_register_pll36xx("fout_epll", "fin_pll", + reg_base + 0x10130); + vpll = samsung_clk_register_pll36xx("fout_vpll", "mout_vpllsrc", + reg_base + 0x10140); + + samsung_clk_register_fixed_rate(exynos5250_fixed_rate_clks, + ARRAY_SIZE(exynos5250_fixed_rate_clks)); + samsung_clk_register_fixed_factor(exynos5250_fixed_factor_clks, + ARRAY_SIZE(exynos5250_fixed_factor_clks)); + samsung_clk_register_mux(exynos5250_mux_clks, + ARRAY_SIZE(exynos5250_mux_clks)); + samsung_clk_register_div(exynos5250_div_clks, + ARRAY_SIZE(exynos5250_div_clks)); + samsung_clk_register_gate(exynos5250_gate_clks, + ARRAY_SIZE(exynos5250_gate_clks)); + + pr_info("Exynos5250: clock setup completed, armclk=%ld\n", + _get_rate("armclk")); +} +CLK_OF_DECLARE(exynos5250_clk, "samsung,exynos5250-clock", exynos5250_clk_init); -- cgit v1.2.3 From f2585b1cce24d7bc5b4a1de582bf81e43813f840 Mon Sep 17 00:00:00 2001 From: Thomas Abraham Date: Sat, 9 Mar 2013 17:03:01 +0900 Subject: clk: exynos5440: register clocks using common clock framework The Exynos5440 clocks are statically listed and registered using the Samsung specific common clock helper functions. Signed-off-by: Thomas Abraham Acked-by: Mike Turquette Signed-off-by: Kukjin Kim --- drivers/clk/samsung/Makefile | 1 + drivers/clk/samsung/clk-exynos5440.c | 139 +++++++++++++++++++++++++++++++++++ 2 files changed, 140 insertions(+) create mode 100644 drivers/clk/samsung/clk-exynos5440.c (limited to 'drivers/clk') diff --git a/drivers/clk/samsung/Makefile b/drivers/clk/samsung/Makefile index f18fb0718157..b7c232e67425 100644 --- a/drivers/clk/samsung/Makefile +++ b/drivers/clk/samsung/Makefile @@ -5,3 +5,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 diff --git a/drivers/clk/samsung/clk-exynos5440.c b/drivers/clk/samsung/clk-exynos5440.c new file mode 100644 index 000000000000..d588e939c235 --- /dev/null +++ b/drivers/clk/samsung/clk-exynos5440.c @@ -0,0 +1,139 @@ +/* + * Copyright (c) 2013 Samsung Electronics Co., Ltd. + * Author: Thomas Abraham + * + * 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. + * + * Common Clock Framework support for Exynos5440 SoC. +*/ + +#include +#include +#include +#include +#include + +#include +#include "clk.h" +#include "clk-pll.h" + +#define CLKEN_OV_VAL 0xf8 +#define CPU_CLK_STATUS 0xfc +#define MISC_DOUT1 0x558 + +/* + * Let each supported clock get a unique id. This id is used to lookup the clock + * for device tree based platforms. + */ +enum exynos5440_clks { + none, xtal, arm_clk, + + spi_baud = 16, pb0_250, pr0_250, pr1_250, b_250, b_125, b_200, sata, + usb, gmac0, cs250, pb0_250_o, pr0_250_o, pr1_250_o, b_250_o, b_125_o, + b_200_o, sata_o, usb_o, gmac0_o, cs250_o, + + nr_clks, +}; + +/* parent clock name list */ +PNAME(mout_armclk_p) = { "cplla", "cpllb" }; +PNAME(mout_spi_p) = { "div125", "div200" }; + +/* fixed rate clocks generated outside the soc */ +struct samsung_fixed_rate_clock exynos5440_fixed_rate_ext_clks[] __initdata = { + FRATE(none, "xtal", NULL, CLK_IS_ROOT, 0), +}; + +/* fixed rate clocks */ +struct samsung_fixed_rate_clock exynos5440_fixed_rate_clks[] __initdata = { + FRATE(none, "ppll", NULL, CLK_IS_ROOT, 1000000000), + FRATE(none, "usb_phy0", NULL, CLK_IS_ROOT, 60000000), + FRATE(none, "usb_phy1", NULL, CLK_IS_ROOT, 60000000), + FRATE(none, "usb_ohci12", NULL, CLK_IS_ROOT, 12000000), + FRATE(none, "usb_ohci48", NULL, CLK_IS_ROOT, 48000000), +}; + +/* fixed factor clocks */ +struct samsung_fixed_factor_clock exynos5440_fixed_factor_clks[] __initdata = { + FFACTOR(none, "div250", "ppll", 1, 4, 0), + FFACTOR(none, "div200", "ppll", 1, 5, 0), + FFACTOR(none, "div125", "div250", 1, 2, 0), +}; + +/* mux clocks */ +struct samsung_mux_clock exynos5440_mux_clks[] __initdata = { + MUX(none, "mout_spi", mout_spi_p, MISC_DOUT1, 5, 1), + MUX_A(arm_clk, "arm_clk", mout_armclk_p, + CPU_CLK_STATUS, 0, 1, "armclk"), +}; + +/* divider clocks */ +struct samsung_div_clock exynos5440_div_clks[] __initdata = { + DIV(spi_baud, "div_spi", "mout_spi", MISC_DOUT1, 3, 2), +}; + +/* gate clocks */ +struct samsung_gate_clock exynos5440_gate_clks[] __initdata = { + GATE(pb0_250, "pb0_250", "div250", CLKEN_OV_VAL, 3, 0, 0), + GATE(pr0_250, "pr0_250", "div250", CLKEN_OV_VAL, 4, 0, 0), + GATE(pr1_250, "pr1_250", "div250", CLKEN_OV_VAL, 5, 0, 0), + GATE(b_250, "b_250", "div250", CLKEN_OV_VAL, 9, 0, 0), + GATE(b_125, "b_125", "div125", CLKEN_OV_VAL, 10, 0, 0), + GATE(b_200, "b_200", "div200", CLKEN_OV_VAL, 11, 0, 0), + GATE(sata, "sata", "div200", CLKEN_OV_VAL, 12, 0, 0), + GATE(usb, "usb", "div200", CLKEN_OV_VAL, 13, 0, 0), + GATE(gmac0, "gmac0", "div200", CLKEN_OV_VAL, 14, 0, 0), + GATE(cs250, "cs250", "div250", CLKEN_OV_VAL, 19, 0, 0), + GATE(pb0_250_o, "pb0_250_o", "pb0_250", CLKEN_OV_VAL, 3, 0, 0), + GATE(pr0_250_o, "pr0_250_o", "pr0_250", CLKEN_OV_VAL, 4, 0, 0), + GATE(pr1_250_o, "pr1_250_o", "pr1_250", CLKEN_OV_VAL, 5, 0, 0), + GATE(b_250_o, "b_250_o", "b_250", CLKEN_OV_VAL, 9, 0, 0), + GATE(b_125_o, "b_125_o", "b_125", CLKEN_OV_VAL, 10, 0, 0), + GATE(b_200_o, "b_200_o", "b_200", CLKEN_OV_VAL, 11, 0, 0), + GATE(sata_o, "sata_o", "sata", CLKEN_OV_VAL, 12, 0, 0), + GATE(usb_o, "usb_o", "usb", CLKEN_OV_VAL, 13, 0, 0), + GATE(gmac0_o, "gmac0_o", "gmac", CLKEN_OV_VAL, 14, 0, 0), + GATE(cs250_o, "cs250_o", "cs250", CLKEN_OV_VAL, 19, 0, 0), +}; + +static __initdata struct of_device_id ext_clk_match[] = { + { .compatible = "samsung,clock-xtal", .data = (void *)0, }, + {}, +}; + +/* register exynos5440 clocks */ +void __init exynos5440_clk_init(struct device_node *np) +{ + void __iomem *reg_base; + + reg_base = of_iomap(np, 0); + if (!reg_base) { + pr_err("%s: failed to map clock controller registers," + " aborting clock initialization\n", __func__); + return; + } + + samsung_clk_init(np, reg_base, nr_clks, NULL, 0); + samsung_clk_of_register_fixed_ext(exynos5440_fixed_rate_ext_clks, + ARRAY_SIZE(exynos5440_fixed_rate_ext_clks), ext_clk_match); + + samsung_clk_register_pll2550x("cplla", "xtal", reg_base + 0x1c, 0x10); + samsung_clk_register_pll2550x("cpllb", "xtal", reg_base + 0x20, 0x10); + + samsung_clk_register_fixed_rate(exynos5440_fixed_rate_clks, + ARRAY_SIZE(exynos5440_fixed_rate_clks)); + samsung_clk_register_fixed_factor(exynos5440_fixed_factor_clks, + ARRAY_SIZE(exynos5440_fixed_factor_clks)); + samsung_clk_register_mux(exynos5440_mux_clks, + ARRAY_SIZE(exynos5440_mux_clks)); + samsung_clk_register_div(exynos5440_div_clks, + ARRAY_SIZE(exynos5440_div_clks)); + samsung_clk_register_gate(exynos5440_gate_clks, + ARRAY_SIZE(exynos5440_gate_clks)); + + pr_info("Exynos5440: arm_clk = %ldHz\n", _get_rate("armclk")); + pr_info("exynos5440 clock initialization complete\n"); +} +CLK_OF_DECLARE(exynos5440_clk, "samsung,exynos5440-clock", exynos5440_clk_init); -- cgit v1.2.3 From 798ed613f5db7f61a7773412b9a6bc3d37d17ecb Mon Sep 17 00:00:00 2001 From: Heiko Stuebner Date: Mon, 18 Mar 2013 13:43:52 +0900 Subject: clk: samsung: register clk_div_tables for divider clocks On some Samsung platforms divider clocks only use specific divider combinations like the armdiv on s3c2443 and s3c2416. For these usecases the generic divider clock already provides the option of providing a lookup table mapping register values to divider values. Therefore add a new field to samsung_div_clock and if filled with a table, use clk_register_divider_table instead of clk_register_divider to register a divider clock Signed-off-by: Heiko Stuebner Reviewed-by: Thomas Abraham Acked-by: Mike Turquette Signed-off-by: Kukjin Kim --- drivers/clk/samsung/clk.c | 14 +++++++++++--- drivers/clk/samsung/clk.h | 13 +++++++++---- 2 files changed, 20 insertions(+), 7 deletions(-) (limited to 'drivers/clk') diff --git a/drivers/clk/samsung/clk.c b/drivers/clk/samsung/clk.c index 91d12f397f5d..d36cdd511761 100644 --- a/drivers/clk/samsung/clk.c +++ b/drivers/clk/samsung/clk.c @@ -183,9 +183,17 @@ void __init samsung_clk_register_div(struct samsung_div_clock *list, unsigned int idx, ret; for (idx = 0; idx < nr_clk; idx++, list++) { - clk = clk_register_divider(NULL, list->name, list->parent_name, - list->flags, reg_base + list->offset, list->shift, - list->width, list->div_flags, &lock); + if (list->table) + clk = clk_register_divider_table(NULL, list->name, + list->parent_name, list->flags, + reg_base + list->offset, list->shift, + list->width, list->div_flags, + list->table, &lock); + else + clk = clk_register_divider(NULL, list->name, + list->parent_name, list->flags, + reg_base + list->offset, list->shift, + list->width, list->div_flags, &lock); if (IS_ERR(clk)) { pr_err("%s: failed to register clock %s\n", __func__, list->name); diff --git a/drivers/clk/samsung/clk.h b/drivers/clk/samsung/clk.h index 961192ffd696..26a752b18f88 100644 --- a/drivers/clk/samsung/clk.h +++ b/drivers/clk/samsung/clk.h @@ -150,9 +150,10 @@ struct samsung_div_clock { u8 width; u8 div_flags; const char *alias; + struct clk_div_table *table; }; -#define __DIV(_id, dname, cname, pname, o, s, w, f, df, a) \ +#define __DIV(_id, dname, cname, pname, o, s, w, f, df, a, t) \ { \ .id = _id, \ .dev_name = dname, \ @@ -164,16 +165,20 @@ struct samsung_div_clock { .width = w, \ .div_flags = df, \ .alias = a, \ + .table = t, \ } #define DIV(_id, cname, pname, o, s, w) \ - __DIV(_id, NULL, cname, pname, o, s, w, 0, 0, NULL) + __DIV(_id, NULL, cname, pname, o, s, w, 0, 0, NULL, NULL) #define DIV_A(_id, cname, pname, o, s, w, a) \ - __DIV(_id, NULL, cname, pname, o, s, w, 0, 0, a) + __DIV(_id, NULL, cname, pname, o, s, w, 0, 0, a, NULL) #define DIV_F(_id, cname, pname, o, s, w, f, df) \ - __DIV(_id, NULL, cname, pname, o, s, w, f, df, NULL) + __DIV(_id, NULL, cname, pname, o, s, w, f, df, NULL, NULL) + +#define DIV_T(_id, cname, pname, o, s, w, t) \ + __DIV(_id, NULL, cname, pname, o, s, w, 0, 0, NULL, t) /** * struct samsung_gate_clock: information about gate clock -- cgit v1.2.3 From 2466196d3e4f1fbe902ca8480bf4a03db78572b2 Mon Sep 17 00:00:00 2001 From: Heiko Stueber Date: Mon, 18 Mar 2013 13:43:52 +0900 Subject: clk: samsung: fix pm init on non-dt platforms The clock_init function checked for a dt node, returning immediately for non-dt machines. This let to the suspend init never being reached on those non-DT machines. So fix this by moving the pm init code above the check. Signed-off-by: Heiko Stueber Acked-by: Mike Turquette Signed-off-by: Kukjin Kim --- drivers/clk/samsung/clk.c | 25 +++++++++++++------------ 1 file changed, 13 insertions(+), 12 deletions(-) (limited to 'drivers/clk') diff --git a/drivers/clk/samsung/clk.c b/drivers/clk/samsung/clk.c index d36cdd511761..ca04b9e61588 100644 --- a/drivers/clk/samsung/clk.c +++ b/drivers/clk/samsung/clk.c @@ -57,18 +57,6 @@ void __init samsung_clk_init(struct device_node *np, void __iomem *base, unsigned long nr_rdump) { reg_base = base; - if (!np) - return; - -#ifdef CONFIG_OF - clk_table = kzalloc(sizeof(struct clk *) * nr_clks, GFP_KERNEL); - if (!clk_table) - panic("could not allocate clock lookup table\n"); - - clk_data.clks = clk_table; - clk_data.clk_num = nr_clks; - of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data); -#endif #ifdef CONFIG_PM_SLEEP if (rdump && nr_rdump) { @@ -87,6 +75,19 @@ void __init samsung_clk_init(struct device_node *np, void __iomem *base, register_syscore_ops(&samsung_clk_syscore_ops); } #endif + + if (!np) + return; + +#ifdef CONFIG_OF + clk_table = kzalloc(sizeof(struct clk *) * nr_clks, GFP_KERNEL); + if (!clk_table) + panic("could not allocate clock lookup table\n"); + + clk_data.clks = clk_table; + clk_data.clk_num = nr_clks; + of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data); +#endif } /* add a clock instance to the clock lookup table used for dt based lookup */ -- cgit v1.2.3 From 6e92bf5a01afb1f897aa15a34517da07d7c0c320 Mon Sep 17 00:00:00 2001 From: Heiko Stuebner Date: Mon, 18 Mar 2013 13:43:52 +0900 Subject: clk: samsung: always allocate the clk_table This is needed to allow looking up previous created clocks when adding separate aliases to them. Signed-off-by: Heiko Stuebner Acked-by: Mike Turquette Signed-off-by: Kukjin Kim --- drivers/clk/samsung/clk.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers/clk') diff --git a/drivers/clk/samsung/clk.c b/drivers/clk/samsung/clk.c index ca04b9e61588..1ed571606395 100644 --- a/drivers/clk/samsung/clk.c +++ b/drivers/clk/samsung/clk.c @@ -76,14 +76,14 @@ void __init samsung_clk_init(struct device_node *np, void __iomem *base, } #endif - if (!np) - return; - -#ifdef CONFIG_OF clk_table = kzalloc(sizeof(struct clk *) * nr_clks, GFP_KERNEL); if (!clk_table) panic("could not allocate clock lookup table\n"); + if (!np) + return; + +#ifdef CONFIG_OF clk_data.clks = clk_table; clk_data.clk_num = nr_clks; of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data); -- cgit v1.2.3 From 5e2e0195ec89d8e266a2530ffec335c483c64899 Mon Sep 17 00:00:00 2001 From: Heiko Stuebner Date: Mon, 18 Mar 2013 13:43:56 +0900 Subject: clk: samsung: add infrastructure to add separate aliases The current code adds aliases, if necessary, directly when adding the clock, limiting the number of possible aliases to one. Some platforms need more than one alias, like the hsmmc pclocks on s3c2416 which need a "hsmmc" and "mmc_busclk.0" alias for the s3c- sdhci driver. Therefore add the possibility to separately add clock aliases for previously created clocks. Signed-off-by: Heiko Stuebner Acked-by: Mike Turquette Signed-off-by: Kukjin Kim --- drivers/clk/samsung/clk.c | 33 +++++++++++++++++++++++++++++++++ drivers/clk/samsung/clk.h | 21 +++++++++++++++++++++ 2 files changed, 54 insertions(+) (limited to 'drivers/clk') diff --git a/drivers/clk/samsung/clk.c b/drivers/clk/samsung/clk.c index 1ed571606395..82f27f644dae 100644 --- a/drivers/clk/samsung/clk.c +++ b/drivers/clk/samsung/clk.c @@ -97,6 +97,39 @@ void samsung_clk_add_lookup(struct clk *clk, unsigned int id) clk_table[id] = clk; } +/* register a list of aliases */ +void __init samsung_clk_register_alias(struct samsung_clock_alias *list, + unsigned int nr_clk) +{ + struct clk *clk; + unsigned int idx, ret; + + if (!clk_table) { + pr_err("%s: clock table missing\n", __func__); + return; + } + + for (idx = 0; idx < nr_clk; idx++, list++) { + if (!list->id) { + pr_err("%s: clock id missing for index %d\n", __func__, + idx); + continue; + } + + clk = clk_table[list->id]; + if (!clk) { + pr_err("%s: failed to find clock %d\n", __func__, + list->id); + continue; + } + + ret = clk_register_clkdev(clk, list->alias, list->dev_name); + if (ret) + pr_err("%s: failed to register lookup %s\n", + __func__, list->alias); + } +} + /* register a list of fixed clocks */ void __init samsung_clk_register_fixed_rate( struct samsung_fixed_rate_clock *list, unsigned int nr_clk) diff --git a/drivers/clk/samsung/clk.h b/drivers/clk/samsung/clk.h index 26a752b18f88..6bacd6fa0200 100644 --- a/drivers/clk/samsung/clk.h +++ b/drivers/clk/samsung/clk.h @@ -22,6 +22,25 @@ #include +/** + * struct samsung_clock_alias: information about mux clock + * @id: platform specific id of the clock. + * @dev_name: name of the device to which this clock belongs. + * @alias: optional clock alias name to be assigned to this clock. + */ +struct samsung_clock_alias { + unsigned int id; + const char *dev_name; + const char *alias; +}; + +#define ALIAS(_id, dname, a) \ + { \ + .id = _id, \ + .dev_name = dname, \ + .alias = a, \ + } + /** * struct samsung_fixed_rate_clock: information about fixed-rate clock * @id: platform specific id of the clock. @@ -251,6 +270,8 @@ extern void __init samsung_clk_of_register_fixed_ext( extern void samsung_clk_add_lookup(struct clk *clk, unsigned int id); +extern void samsung_clk_register_alias(struct samsung_clock_alias *list, + unsigned int nr_clk); extern void __init samsung_clk_register_fixed_rate( struct samsung_fixed_rate_clock *clk_list, unsigned int nr_clk); extern void __init samsung_clk_register_fixed_factor( -- cgit v1.2.3 From 36fc09722d49077c6a602e8c07b06d21e798b75a Mon Sep 17 00:00:00 2001 From: Sylwester Nawrocki Date: Thu, 4 Apr 2013 13:32:33 +0900 Subject: clk: exynos4: Correct sclk_mfc clock definition This clock must be exported to allow lookup using device tree. Signed-off-by: Sylwester Nawrocki Signed-off-by: Tomasz Figa Signed-off-by: Kyungmin Park Reviewed-by: Thomas Abraham Acked-by: Mike Turquette Signed-off-by: Kukjin Kim --- drivers/clk/samsung/clk-exynos4.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/clk') diff --git a/drivers/clk/samsung/clk-exynos4.c b/drivers/clk/samsung/clk-exynos4.c index e1bb81a1c264..44a99b58c981 100644 --- a/drivers/clk/samsung/clk-exynos4.c +++ b/drivers/clk/samsung/clk-exynos4.c @@ -122,7 +122,7 @@ enum exynos4_clks { sclk_sata, sclk_uart0, sclk_uart1, sclk_uart2, sclk_uart3, sclk_uart4, sclk_audio1, sclk_audio2, sclk_spdif, sclk_spi0, sclk_spi1, sclk_spi2, sclk_slimbus, sclk_fimd1, sclk_mipi1, sclk_pcm1, sclk_pcm2, sclk_i2s1, - sclk_i2s2, sclk_mipihsi, + sclk_i2s2, sclk_mipihsi, sclk_mfc, /* gate clocks */ fimc0 = 256, fimc1, fimc2, fimc3, csis0, csis1, jpeg, smmu_fimc0, @@ -355,7 +355,7 @@ struct samsung_div_clock exynos4_div_clks[] __initdata = { DIV(none, "div_cam1", "mout_cam1", DIV_CAM, 20, 4), DIV(none, "div_csis0", "mout_csis0", DIV_CAM, 24, 4), DIV(none, "div_csis1", "mout_csis1", DIV_CAM, 28, 4), - DIV(none, "div_mfc", "mout_mfc", DIV_MFC, 0, 4), + DIV(sclk_mfc, "sclk_mfc", "mout_mfc", DIV_MFC, 0, 4), DIV(none, "div_g3d", "mout_g3d", DIV_G3D, 0, 4), DIV(none, "div_fimd0", "mout_fimd0", DIV_LCD0, 0, 4), DIV(none, "div_mipi0", "mout_mipi0", DIV_LCD0, 16, 4), -- cgit v1.2.3 From 74f7f8ba5092a76da1e9d07f245575cef86f15ab Mon Sep 17 00:00:00 2001 From: Tomasz Figa Date: Thu, 4 Apr 2013 13:32:37 +0900 Subject: clk: exynos4: Use mout_mpll_user_* on Exynos4x12 Many clock muxes of Exynos 4x12 uses mout_mpll_user_* clocks instead of sclk_mpll as one of their parents. This patch moves such clocks from common array into SoC-specific arrays and adjusts their parent lists respectively. Signed-off-by: Tomasz Figa Signed-off-by: Kyungmin Park Reviewed-by: Thomas Abraham Acked-by: Mike Turquette Signed-off-by: Kukjin Kim --- drivers/clk/samsung/clk-exynos4.c | 172 ++++++++++++++++++++++++-------------- 1 file changed, 111 insertions(+), 61 deletions(-) (limited to 'drivers/clk') diff --git a/drivers/clk/samsung/clk-exynos4.c b/drivers/clk/samsung/clk-exynos4.c index 44a99b58c981..8edd64cb18a8 100644 --- a/drivers/clk/samsung/clk-exynos4.c +++ b/drivers/clk/samsung/clk-exynos4.c @@ -112,7 +112,7 @@ enum exynos4_clks { /* core clocks */ xxti, xusbxti, fin_pll, fout_apll, fout_mpll, fout_epll, fout_vpll, sclk_apll, sclk_mpll, sclk_epll, sclk_vpll, arm_clk, aclk200, aclk100, - aclk160, aclk133, + aclk160, aclk133, mout_mpll_user_t, mout_mpll_user_c, /* 18 */ /* gate for special clocks (sclk) */ sclk_fimc0 = 128, sclk_fimc1, sclk_fimc2, sclk_fimc3, sclk_cam0, @@ -218,35 +218,53 @@ PNAME(mout_apll_p) = { "fin_pll", "fout_apll", }; PNAME(mout_mpll_p) = { "fin_pll", "fout_mpll", }; PNAME(mout_epll_p) = { "fin_pll", "fout_epll", }; PNAME(mout_vpllsrc_p) = { "fin_pll", "sclk_hdmi24m", }; -PNAME(sclk_vpll_p4210) = { "mout_vpllsrc", "fout_vpll", }; PNAME(mout_vpll_p) = { "fin_pll", "fout_vpll", }; -PNAME(mout_core_p) = { "mout_apll", "sclk_mpll", }; -PNAME(sclk_ampll_p) = { "sclk_mpll", "sclk_apll", }; -PNAME(mout_mpll_user_p) = { "fin_pll", "sclk_mpll", }; -PNAME(aclk_p4412) = { "mout_mpll_user", "sclk_apll", }; PNAME(sclk_evpll_p) = { "sclk_epll", "sclk_vpll", }; PNAME(mout_mfc_p) = { "mout_mfc0", "mout_mfc1", }; PNAME(mout_g3d_p) = { "mout_g3d0", "mout_g3d1", }; PNAME(mout_g2d_p) = { "mout_g2d0", "mout_g2d1", }; -PNAME(mout_mixer_p4210) = { "sclk_dac", "sclk_hdmi", }; -PNAME(mout_dac_p4210) = { "sclk_vpll", "sclk_hdmiphy", }; PNAME(mout_hdmi_p) = { "sclk_pixel", "sclk_hdmiphy", }; PNAME(mout_jpeg_p) = { "mout_jpeg0", "mout_jpeg1", }; -PNAME(group1_p) = { "xxti", "xusbxti", "sclk_hdmi24m", "sclk_usbphy0", - "none", "sclk_hdmiphy", "sclk_mpll", - "sclk_epll", "sclk_vpll", }; -PNAME(mout_audio0_p) = { "cdclk0", "none", "sclk_hdmi24m", "sclk_usbphy0", - "xxti", "xusbxti", "sclk_mpll", "sclk_epll", - "sclk_vpll" }; -PNAME(mout_audio1_p) = { "cdclk1", "none", "sclk_hdmi24m", "sclk_usbphy0", - "xxti", "xusbxti", "sclk_mpll", "sclk_epll", - "sclk_vpll", }; -PNAME(mout_audio2_p) = { "cdclk2", "none", "sclk_hdmi24m", "sclk_usbphy0", - "xxti", "xusbxti", "sclk_mpll", "sclk_epll", - "sclk_vpll", }; PNAME(mout_spdif_p) = { "sclk_audio0", "sclk_audio1", "sclk_audio2", "spdif_extclk", }; +/* Exynos 4210-specific parent groups */ +PNAME(sclk_vpll_p4210) = { "mout_vpllsrc", "fout_vpll", }; +PNAME(mout_core_p4210) = { "mout_apll", "sclk_mpll", }; +PNAME(sclk_ampll_p4210) = { "sclk_mpll", "sclk_apll", }; +PNAME(group1_p4210) = { "xxti", "xusbxti", "sclk_hdmi24m", + "sclk_usbphy0", "none", "sclk_hdmiphy", + "sclk_mpll", "sclk_epll", "sclk_vpll", }; +PNAME(mout_audio0_p4210) = { "cdclk0", "none", "sclk_hdmi24m", + "sclk_usbphy0", "xxti", "xusbxti", "sclk_mpll", + "sclk_epll", "sclk_vpll" }; +PNAME(mout_audio1_p4210) = { "cdclk1", "none", "sclk_hdmi24m", + "sclk_usbphy0", "xxti", "xusbxti", "sclk_mpll", + "sclk_epll", "sclk_vpll", }; +PNAME(mout_audio2_p4210) = { "cdclk2", "none", "sclk_hdmi24m", + "sclk_usbphy0", "xxti", "xusbxti", "sclk_mpll", + "sclk_epll", "sclk_vpll", }; +PNAME(mout_mixer_p4210) = { "sclk_dac", "sclk_hdmi", }; +PNAME(mout_dac_p4210) = { "sclk_vpll", "sclk_hdmiphy", }; + +/* Exynos 4x12-specific parent groups */ +PNAME(mout_mpll_user_p4x12) = { "fin_pll", "sclk_mpll", }; +PNAME(mout_core_p4x12) = { "mout_apll", "mout_mpll_user_c", }; +PNAME(sclk_ampll_p4x12) = { "mout_mpll_user_t", "sclk_apll", }; +PNAME(group1_p4x12) = { "xxti", "xusbxti", "sclk_hdmi24m", "sclk_usbphy0", + "none", "sclk_hdmiphy", "mout_mpll_user_t", + "sclk_epll", "sclk_vpll", }; +PNAME(mout_audio0_p4x12) = { "cdclk0", "none", "sclk_hdmi24m", + "sclk_usbphy0", "xxti", "xusbxti", + "mout_mpll_user_t", "sclk_epll", "sclk_vpll" }; +PNAME(mout_audio1_p4x12) = { "cdclk1", "none", "sclk_hdmi24m", + "sclk_usbphy0", "xxti", "xusbxti", + "mout_mpll_user_t", "sclk_epll", "sclk_vpll", }; +PNAME(mout_audio2_p4x12) = { "cdclk2", "none", "sclk_hdmi24m", + "sclk_usbphy0", "xxti", "xusbxti", + "mout_mpll_user_t", "sclk_epll", "sclk_vpll", }; +PNAME(aclk_p4412) = { "mout_mpll_user_t", "sclk_apll", }; + /* fixed rate clocks generated outside the soc */ struct samsung_fixed_rate_clock exynos4_fixed_rate_ext_clks[] __initdata = { FRATE(xxti, "xxti", NULL, CLK_IS_ROOT, 0), @@ -267,80 +285,112 @@ struct samsung_fixed_rate_clock exynos4210_fixed_rate_clks[] __initdata = { /* list of mux clocks supported in all exynos4 soc's */ struct samsung_mux_clock exynos4_mux_clks[] __initdata = { MUX(none, "mout_apll", mout_apll_p, SRC_CPU, 0, 1), - MUX(none, "mout_core", mout_core_p, SRC_CPU, 16, 1), - MUX(none, "mout_fimc0", group1_p, SRC_CAM, 0, 4), - MUX(none, "mout_fimc1", group1_p, SRC_CAM, 4, 4), - MUX(none, "mout_fimc2", group1_p, SRC_CAM, 8, 4), - MUX(none, "mout_fimc3", group1_p, SRC_CAM, 12, 4), - MUX(none, "mout_cam0", group1_p, SRC_CAM, 16, 4), - MUX(none, "mout_cam1", group1_p, SRC_CAM, 20, 4), - MUX(none, "mout_csis0", group1_p, SRC_CAM, 24, 4), - MUX(none, "mout_csis1", group1_p, SRC_CAM, 28, 4), MUX(none, "mout_hdmi", mout_hdmi_p, SRC_TV, 0, 1), - MUX(none, "mout_mfc0", sclk_ampll_p, SRC_MFC, 0, 1), MUX(none, "mout_mfc1", sclk_evpll_p, SRC_MFC, 4, 1), MUX(none, "mout_mfc", mout_mfc_p, SRC_MFC, 8, 1), - MUX(none, "mout_g3d0", sclk_ampll_p, SRC_G3D, 0, 1), MUX(none, "mout_g3d1", sclk_evpll_p, SRC_G3D, 4, 1), MUX(none, "mout_g3d", mout_g3d_p, SRC_G3D, 8, 1), - MUX(none, "mout_fimd0", group1_p, SRC_LCD0, 0, 4), - MUX(none, "mout_mipi0", group1_p, SRC_LCD0, 12, 4), - MUX(none, "mout_audio0", mout_audio0_p, SRC_MAUDIO, 0, 4), - MUX(none, "mout_mmc0", group1_p, SRC_FSYS, 0, 4), - MUX(none, "mout_mmc1", group1_p, SRC_FSYS, 4, 4), - MUX(none, "mout_mmc2", group1_p, SRC_FSYS, 8, 4), - MUX(none, "mout_mmc3", group1_p, SRC_FSYS, 12, 4), - MUX(none, "mout_mmc4", group1_p, SRC_FSYS, 16, 4), - MUX(none, "mout_uart0", group1_p, SRC_PERIL0, 0, 4), - MUX(none, "mout_uart1", group1_p, SRC_PERIL0, 4, 4), - MUX(none, "mout_uart2", group1_p, SRC_PERIL0, 8, 4), - MUX(none, "mout_uart3", group1_p, SRC_PERIL0, 12, 4), - MUX(none, "mout_uart4", group1_p, SRC_PERIL0, 16, 4), - MUX(none, "mout_audio1", mout_audio1_p, SRC_PERIL1, 0, 4), - MUX(none, "mout_audio2", mout_audio2_p, SRC_PERIL1, 4, 4), MUX(none, "mout_spdif", mout_spdif_p, SRC_PERIL1, 8, 2), - MUX(none, "mout_spi0", group1_p, SRC_PERIL1, 16, 4), - MUX(none, "mout_spi1", group1_p, SRC_PERIL1, 20, 4), - MUX(none, "mout_spi2", group1_p, SRC_PERIL1, 24, 4), MUX_A(sclk_epll, "sclk_epll", mout_epll_p, SRC_TOP0, 4, 1, "sclk_epll"), }; /* list of mux clocks supported in exynos4210 soc */ struct samsung_mux_clock exynos4210_mux_clks[] __initdata = { - MUX(none, "mout_aclk200", sclk_ampll_p, SRC_TOP0, 12, 1), - MUX(none, "mout_aclk100", sclk_ampll_p, SRC_TOP0, 16, 1), - MUX(none, "mout_aclk160", sclk_ampll_p, SRC_TOP0, 20, 1), - MUX(none, "mout_aclk133", sclk_ampll_p, SRC_TOP0, 24, 1), + MUX(none, "mout_aclk200", sclk_ampll_p4210, SRC_TOP0, 12, 1), + MUX(none, "mout_aclk100", sclk_ampll_p4210, SRC_TOP0, 16, 1), + MUX(none, "mout_aclk160", sclk_ampll_p4210, SRC_TOP0, 20, 1), + MUX(none, "mout_aclk133", sclk_ampll_p4210, SRC_TOP0, 24, 1), MUX(none, "mout_vpllsrc", mout_vpllsrc_p, SRC_TOP1, 0, 1), MUX(none, "mout_mixer", mout_mixer_p4210, SRC_TV, 4, 1), MUX(none, "mout_dac", mout_dac_p4210, SRC_TV, 8, 1), - MUX(none, "mout_g2d0", sclk_ampll_p, E4210_SRC_IMAGE, 0, 1), + MUX(none, "mout_g2d0", sclk_ampll_p4210, E4210_SRC_IMAGE, 0, 1), MUX(none, "mout_g2d1", sclk_evpll_p, E4210_SRC_IMAGE, 4, 1), MUX(none, "mout_g2d", mout_g2d_p, E4210_SRC_IMAGE, 8, 1), - MUX(none, "mout_fimd1", group1_p, SRC_LCD1, 0, 4), - MUX(none, "mout_mipi1", group1_p, SRC_LCD1, 12, 4), + MUX(none, "mout_fimd1", group1_p4210, SRC_LCD1, 0, 4), + MUX(none, "mout_mipi1", group1_p4210, SRC_LCD1, 12, 4), MUX_A(sclk_mpll, "sclk_mpll", mout_mpll_p, SRC_CPU, 8, 1, "sclk_mpll"), + MUX(none, "mout_core", mout_core_p4210, SRC_CPU, 16, 1), MUX_A(sclk_vpll, "sclk_vpll", sclk_vpll_p4210, SRC_TOP0, 8, 1, "sclk_vpll"), + MUX(none, "mout_fimc0", group1_p4210, SRC_CAM, 0, 4), + MUX(none, "mout_fimc1", group1_p4210, SRC_CAM, 4, 4), + MUX(none, "mout_fimc2", group1_p4210, SRC_CAM, 8, 4), + MUX(none, "mout_fimc3", group1_p4210, SRC_CAM, 12, 4), + MUX(none, "mout_cam0", group1_p4210, SRC_CAM, 16, 4), + MUX(none, "mout_cam1", group1_p4210, SRC_CAM, 20, 4), + MUX(none, "mout_csis0", group1_p4210, SRC_CAM, 24, 4), + MUX(none, "mout_csis1", group1_p4210, SRC_CAM, 28, 4), + MUX(none, "mout_mfc0", sclk_ampll_p4210, SRC_MFC, 0, 1), + MUX(none, "mout_g3d0", sclk_ampll_p4210, SRC_G3D, 0, 1), + MUX(none, "mout_fimd0", group1_p4210, SRC_LCD0, 0, 4), + MUX(none, "mout_mipi0", group1_p4210, SRC_LCD0, 12, 4), + MUX(none, "mout_audio0", mout_audio0_p4210, SRC_MAUDIO, 0, 4), + MUX(none, "mout_mmc0", group1_p4210, SRC_FSYS, 0, 4), + MUX(none, "mout_mmc1", group1_p4210, SRC_FSYS, 4, 4), + MUX(none, "mout_mmc2", group1_p4210, SRC_FSYS, 8, 4), + MUX(none, "mout_mmc3", group1_p4210, SRC_FSYS, 12, 4), + MUX(none, "mout_mmc4", group1_p4210, SRC_FSYS, 16, 4), + MUX(none, "mout_uart0", group1_p4210, SRC_PERIL0, 0, 4), + MUX(none, "mout_uart1", group1_p4210, SRC_PERIL0, 4, 4), + MUX(none, "mout_uart2", group1_p4210, SRC_PERIL0, 8, 4), + MUX(none, "mout_uart3", group1_p4210, SRC_PERIL0, 12, 4), + MUX(none, "mout_uart4", group1_p4210, SRC_PERIL0, 16, 4), + MUX(none, "mout_audio1", mout_audio1_p4210, SRC_PERIL1, 0, 4), + MUX(none, "mout_audio2", mout_audio2_p4210, SRC_PERIL1, 4, 4), + MUX(none, "mout_spi0", group1_p4210, SRC_PERIL1, 16, 4), + MUX(none, "mout_spi1", group1_p4210, SRC_PERIL1, 20, 4), + MUX(none, "mout_spi2", group1_p4210, SRC_PERIL1, 24, 4), }; /* list of mux clocks supported in exynos4x12 soc */ struct samsung_mux_clock exynos4x12_mux_clks[] __initdata = { - MUX(none, "mout_mpll_user", mout_mpll_user_p, SRC_LEFTBUS, 4, 1), + MUX(mout_mpll_user_c, "mout_mpll_user_c", mout_mpll_user_p4x12, + SRC_CPU, 24, 1), + MUX(mout_mpll_user_t, "mout_mpll_user_t", mout_mpll_user_p4x12, + SRC_TOP1, 12, 1), MUX(none, "mout_aclk200", aclk_p4412, SRC_TOP0, 12, 1), MUX(none, "mout_aclk100", aclk_p4412, SRC_TOP0, 16, 1), MUX(none, "mout_aclk160", aclk_p4412, SRC_TOP0, 20, 1), MUX(none, "mout_aclk133", aclk_p4412, SRC_TOP0, 24, 1), - MUX(none, "mout_mdnie0", group1_p, SRC_LCD0, 4, 4), - MUX(none, "mout_mdnie_pwm0", group1_p, SRC_LCD0, 8, 4), - MUX(none, "mout_sata", sclk_ampll_p, SRC_FSYS, 24, 1), - MUX(none, "mout_jpeg0", sclk_ampll_p, E4X12_SRC_CAM1, 0, 1), + MUX(none, "mout_mdnie0", group1_p4x12, SRC_LCD0, 4, 4), + MUX(none, "mout_mdnie_pwm0", group1_p4x12, SRC_LCD0, 8, 4), + MUX(none, "mout_sata", sclk_ampll_p4x12, SRC_FSYS, 24, 1), + MUX(none, "mout_jpeg0", sclk_ampll_p4x12, E4X12_SRC_CAM1, 0, 1), MUX(none, "mout_jpeg1", sclk_evpll_p, E4X12_SRC_CAM1, 4, 1), MUX(none, "mout_jpeg", mout_jpeg_p, E4X12_SRC_CAM1, 8, 1), MUX_A(sclk_mpll, "sclk_mpll", mout_mpll_p, E4X12_SRC_DMC, 12, 1, "sclk_mpll"), MUX_A(sclk_vpll, "sclk_vpll", mout_vpll_p, SRC_TOP0, 8, 1, "sclk_vpll"), + MUX(none, "mout_core", mout_core_p4x12, SRC_CPU, 16, 1), + MUX(none, "mout_fimc0", group1_p4x12, SRC_CAM, 0, 4), + MUX(none, "mout_fimc1", group1_p4x12, SRC_CAM, 4, 4), + MUX(none, "mout_fimc2", group1_p4x12, SRC_CAM, 8, 4), + MUX(none, "mout_fimc3", group1_p4x12, SRC_CAM, 12, 4), + MUX(none, "mout_cam0", group1_p4x12, SRC_CAM, 16, 4), + MUX(none, "mout_cam1", group1_p4x12, SRC_CAM, 20, 4), + MUX(none, "mout_csis0", group1_p4x12, SRC_CAM, 24, 4), + MUX(none, "mout_csis1", group1_p4x12, SRC_CAM, 28, 4), + MUX(none, "mout_mfc0", sclk_ampll_p4x12, SRC_MFC, 0, 1), + MUX(none, "mout_g3d0", sclk_ampll_p4x12, SRC_G3D, 0, 1), + MUX(none, "mout_fimd0", group1_p4x12, SRC_LCD0, 0, 4), + MUX(none, "mout_mipi0", group1_p4x12, SRC_LCD0, 12, 4), + MUX(none, "mout_audio0", mout_audio0_p4x12, SRC_MAUDIO, 0, 4), + MUX(none, "mout_mmc0", group1_p4x12, SRC_FSYS, 0, 4), + MUX(none, "mout_mmc1", group1_p4x12, SRC_FSYS, 4, 4), + MUX(none, "mout_mmc2", group1_p4x12, SRC_FSYS, 8, 4), + MUX(none, "mout_mmc3", group1_p4x12, SRC_FSYS, 12, 4), + MUX(none, "mout_mmc4", group1_p4x12, SRC_FSYS, 16, 4), + MUX(none, "mout_uart0", group1_p4x12, SRC_PERIL0, 0, 4), + MUX(none, "mout_uart1", group1_p4x12, SRC_PERIL0, 4, 4), + MUX(none, "mout_uart2", group1_p4x12, SRC_PERIL0, 8, 4), + MUX(none, "mout_uart3", group1_p4x12, SRC_PERIL0, 12, 4), + MUX(none, "mout_uart4", group1_p4x12, SRC_PERIL0, 16, 4), + MUX(none, "mout_audio1", mout_audio1_p4x12, SRC_PERIL1, 0, 4), + MUX(none, "mout_audio2", mout_audio2_p4x12, SRC_PERIL1, 4, 4), + MUX(none, "mout_spi0", group1_p4x12, SRC_PERIL1, 16, 4), + MUX(none, "mout_spi1", group1_p4x12, SRC_PERIL1, 20, 4), + MUX(none, "mout_spi2", group1_p4x12, SRC_PERIL1, 24, 4), }; /* list of divider clocks supported in all exynos4 soc's */ -- cgit v1.2.3 From 4c3cc72cc7760f2aa3411e1e0f1a6cfca2659653 Mon Sep 17 00:00:00 2001 From: Tomasz Figa Date: Thu, 4 Apr 2013 13:32:43 +0900 Subject: clk: exynos4: Add missing mout_mipihsi clock This patch adds missing output of mux MIPIHSI which is needed for div_mipihsi clock. Signed-off-by: Tomasz Figa Signed-off-by: Kyungmin Park Reviewed-by: Thomas Abraham Acked-by: Mike Turquette Signed-off-by: Kukjin Kim --- drivers/clk/samsung/clk-exynos4.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers/clk') diff --git a/drivers/clk/samsung/clk-exynos4.c b/drivers/clk/samsung/clk-exynos4.c index 8edd64cb18a8..42c098df2e22 100644 --- a/drivers/clk/samsung/clk-exynos4.c +++ b/drivers/clk/samsung/clk-exynos4.c @@ -381,6 +381,7 @@ struct samsung_mux_clock exynos4x12_mux_clks[] __initdata = { MUX(none, "mout_mmc2", group1_p4x12, SRC_FSYS, 8, 4), MUX(none, "mout_mmc3", group1_p4x12, SRC_FSYS, 12, 4), MUX(none, "mout_mmc4", group1_p4x12, SRC_FSYS, 16, 4), + MUX(none, "mout_mipihsi", aclk_p4412, SRC_FSYS, 24, 1), MUX(none, "mout_uart0", group1_p4x12, SRC_PERIL0, 0, 4), MUX(none, "mout_uart1", group1_p4x12, SRC_PERIL0, 4, 4), MUX(none, "mout_uart2", group1_p4x12, SRC_PERIL0, 8, 4), -- cgit v1.2.3 From 69aff2fd1d01f10268bb972d4d52931c766c44d8 Mon Sep 17 00:00:00 2001 From: Tomasz Figa Date: Thu, 4 Apr 2013 13:32:47 +0900 Subject: clk: exynos4: Add missing sclk_audio0 clock This clock is a parent of mout_spdif and sclk_pcm0. Signed-off-by: Tomasz Figa Signed-off-by: Kyungmin Park Reviewed-by: Thomas Abraham Acked-by: Mike Turquette Signed-off-by: Kukjin Kim --- drivers/clk/samsung/clk-exynos4.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers/clk') diff --git a/drivers/clk/samsung/clk-exynos4.c b/drivers/clk/samsung/clk-exynos4.c index 42c098df2e22..0e89d97c2ce3 100644 --- a/drivers/clk/samsung/clk-exynos4.c +++ b/drivers/clk/samsung/clk-exynos4.c @@ -508,6 +508,8 @@ struct samsung_gate_clock exynos4_gate_clks[] __initdata = { CLK_SET_RATE_PARENT, 0), GATE(sclk_mipi0, "sclk_mipi0", "div_mipi_pre0", SRC_MASK_LCD0, 12, CLK_SET_RATE_PARENT, 0), + GATE(sclk_audio0, "sclk_audio0", "div_audio0", SRC_MASK_MAUDIO, 0, + CLK_SET_RATE_PARENT, 0), GATE(sclk_audio1, "sclk_audio1", "div_audio1", 0xc354, 0, CLK_SET_RATE_PARENT, 0), GATE_D(vp, "s5p-mixer", "vp", "aclk160", GATE_IP_TV, 0, 0, 0), -- cgit v1.2.3 From 6976d27415a10d19a718a2e4f862f5c5cc25fd19 Mon Sep 17 00:00:00 2001 From: Tomasz Figa Date: Thu, 4 Apr 2013 13:32:51 +0900 Subject: clk: exynos4: Export sclk_pcm0 This clock is used by PCM interface 0. Signed-off-by: Tomasz Figa Signed-off-by: Kyungmin Park Reviewed-by: Thomas Abraham Acked-by: Mike Turquette Signed-off-by: Kukjin Kim --- drivers/clk/samsung/clk-exynos4.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/clk') diff --git a/drivers/clk/samsung/clk-exynos4.c b/drivers/clk/samsung/clk-exynos4.c index 0e89d97c2ce3..96f2e746473d 100644 --- a/drivers/clk/samsung/clk-exynos4.c +++ b/drivers/clk/samsung/clk-exynos4.c @@ -122,7 +122,7 @@ enum exynos4_clks { sclk_sata, sclk_uart0, sclk_uart1, sclk_uart2, sclk_uart3, sclk_uart4, sclk_audio1, sclk_audio2, sclk_spdif, sclk_spi0, sclk_spi1, sclk_spi2, sclk_slimbus, sclk_fimd1, sclk_mipi1, sclk_pcm1, sclk_pcm2, sclk_i2s1, - sclk_i2s2, sclk_mipihsi, sclk_mfc, + sclk_i2s2, sclk_mipihsi, sclk_mfc, sclk_pcm0, /* gate clocks */ fimc0 = 256, fimc1, fimc2, fimc3, csis0, csis1, jpeg, smmu_fimc0, @@ -411,7 +411,7 @@ struct samsung_div_clock exynos4_div_clks[] __initdata = { DIV(none, "div_fimd0", "mout_fimd0", DIV_LCD0, 0, 4), DIV(none, "div_mipi0", "mout_mipi0", DIV_LCD0, 16, 4), DIV(none, "div_audio0", "mout_audio0", DIV_MAUDIO, 0, 4), - DIV(none, "div_pcm0", "sclk_audio0", DIV_MAUDIO, 4, 8), + DIV(sclk_pcm0, "sclk_pcm0", "sclk_audio0", DIV_MAUDIO, 4, 8), DIV(none, "div_mmc0", "mout_mmc0", DIV_FSYS1, 0, 4), DIV(none, "div_mmc1", "mout_mmc1", DIV_FSYS1, 16, 4), DIV(none, "div_mmc2", "mout_mmc2", DIV_FSYS2, 0, 4), -- cgit v1.2.3 From 7bc1d2da0aa80ff387507e3bcb68bd72abec8a92 Mon Sep 17 00:00:00 2001 From: Tomasz Figa Date: Thu, 4 Apr 2013 13:32:55 +0900 Subject: clk: exynos4: Move dac and mixer to Exynos4210-specific clocks The sclk_dac and sclk_mixer clocks are not present on Exynos4x12. Signed-off-by: Tomasz Figa Signed-off-by: Kyungmin Park Reviewed-by: Thomas Abraham Acked-by: Mike Turquette Signed-off-by: Kukjin Kim --- drivers/clk/samsung/clk-exynos4.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/clk') diff --git a/drivers/clk/samsung/clk-exynos4.c b/drivers/clk/samsung/clk-exynos4.c index 96f2e746473d..c1e64512c1b8 100644 --- a/drivers/clk/samsung/clk-exynos4.c +++ b/drivers/clk/samsung/clk-exynos4.c @@ -483,8 +483,6 @@ struct samsung_gate_clock exynos4_gate_clks[] __initdata = { * of the clocks can be removed. */ GATE(sclk_hdmi, "sclk_hdmi", "mout_hdmi", SRC_MASK_TV, 0, 0, 0), - GATE(sclk_mixer, "sclk_mixer", "mout_mixer", SRC_MASK_TV, 4, 0, 0), - GATE(sclk_dac, "sclk_dac", "mout_dac", SRC_MASK_TV, 8, 0, 0), GATE(sclk_spdif, "sclk_spdif", "mout_spdif", 0xc354, 8, 0, 0), GATE(jpeg, "jpeg", "aclk160", GATE_IP_CAM, 6, 0, 0), GATE(mie0, "mie0", "aclk160", GATE_IP_LCD0, 1, 0, 0), @@ -681,6 +679,8 @@ struct samsung_gate_clock exynos4210_gate_clks[] __initdata = { SRC_MASK_LCD1, 12, CLK_SET_RATE_PARENT, 0), GATE(sclk_sata, "sclk_sata", "div_sata", SRC_MASK_FSYS, 24, CLK_SET_RATE_PARENT, 0), + GATE(sclk_mixer, "sclk_mixer", "mout_mixer", SRC_MASK_TV, 4, 0, 0), + GATE(sclk_dac, "sclk_dac", "mout_dac", SRC_MASK_TV, 8, 0, 0), GATE_A(tsadc, "tsadc", "aclk100", GATE_IP_PERIL, 15, 0, 0, "adc"), GATE_A(mct, "mct", "aclk100", GATE_IP_PERIR, 13, 0, 0, "mct"), GATE_A(wdt, "watchdog", "aclk100", GATE_IP_PERIR, 14, 0, 0, "watchdog"), -- cgit v1.2.3 From e77ba804c103db5380d182aaa83af4566699fca1 Mon Sep 17 00:00:00 2001 From: Lukasz Majewski Date: Thu, 4 Apr 2013 13:32:59 +0900 Subject: clk: exynos4: Export clocks used by exynos cpufreq drivers This patch exports clocks used by Exynos cpufreq drivers to allow lookup using device tree. (Support to cpufreq drivers will be added in further patches.) Signed-off-by: Lukasz Majewski Signed-off-by: Tomasz Figa Signed-off-by: Kyungmin Park Reviewed-by: Thomas Abraham Acked-by: Mike Turquette Signed-off-by: Kukjin Kim --- drivers/clk/samsung/clk-exynos4.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'drivers/clk') diff --git a/drivers/clk/samsung/clk-exynos4.c b/drivers/clk/samsung/clk-exynos4.c index c1e64512c1b8..5592a78b2edc 100644 --- a/drivers/clk/samsung/clk-exynos4.c +++ b/drivers/clk/samsung/clk-exynos4.c @@ -112,7 +112,8 @@ enum exynos4_clks { /* core clocks */ xxti, xusbxti, fin_pll, fout_apll, fout_mpll, fout_epll, fout_vpll, sclk_apll, sclk_mpll, sclk_epll, sclk_vpll, arm_clk, aclk200, aclk100, - aclk160, aclk133, mout_mpll_user_t, mout_mpll_user_c, /* 18 */ + aclk160, aclk133, mout_mpll_user_t, mout_mpll_user_c, mout_core, + mout_apll, /* 20 */ /* gate for special clocks (sclk) */ sclk_fimc0 = 128, sclk_fimc1, sclk_fimc2, sclk_fimc3, sclk_cam0, @@ -284,7 +285,8 @@ struct samsung_fixed_rate_clock exynos4210_fixed_rate_clks[] __initdata = { /* list of mux clocks supported in all exynos4 soc's */ struct samsung_mux_clock exynos4_mux_clks[] __initdata = { - MUX(none, "mout_apll", mout_apll_p, SRC_CPU, 0, 1), + MUX_F(mout_apll, "mout_apll", mout_apll_p, SRC_CPU, 0, 1, + CLK_SET_RATE_PARENT, 0), MUX(none, "mout_hdmi", mout_hdmi_p, SRC_TV, 0, 1), MUX(none, "mout_mfc1", sclk_evpll_p, SRC_MFC, 4, 1), MUX(none, "mout_mfc", mout_mfc_p, SRC_MFC, 8, 1), @@ -362,7 +364,7 @@ struct samsung_mux_clock exynos4x12_mux_clks[] __initdata = { E4X12_SRC_DMC, 12, 1, "sclk_mpll"), MUX_A(sclk_vpll, "sclk_vpll", mout_vpll_p, SRC_TOP0, 8, 1, "sclk_vpll"), - MUX(none, "mout_core", mout_core_p4x12, SRC_CPU, 16, 1), + MUX(mout_core, "mout_core", mout_core_p4x12, SRC_CPU, 16, 1), MUX(none, "mout_fimc0", group1_p4x12, SRC_CAM, 0, 4), MUX(none, "mout_fimc1", group1_p4x12, SRC_CAM, 4, 4), MUX(none, "mout_fimc2", group1_p4x12, SRC_CAM, 8, 4), -- cgit v1.2.3 From a8b5a39ecbbe5b00554b5025af4464abe12bfcd8 Mon Sep 17 00:00:00 2001 From: Tomasz Figa Date: Thu, 4 Apr 2013 13:33:02 +0900 Subject: clk: samsung: Remove unimplemented ops for pll Unimplemented clock operations should be simply omitted instead of returning error values. This patch removes unimplemented PLL operations to fix problems caused by returning error code in round_rate callback. Signed-off-by: Tomasz Figa Signed-off-by: Kyungmin Park Reviewed-by: Thomas Abraham Acked-by: Mike Turquette Signed-off-by: Kukjin Kim --- drivers/clk/samsung/clk-pll.c | 80 ------------------------------------------- 1 file changed, 80 deletions(-) (limited to 'drivers/clk') diff --git a/drivers/clk/samsung/clk-pll.c b/drivers/clk/samsung/clk-pll.c index 4b2451129d44..89135f6be116 100644 --- a/drivers/clk/samsung/clk-pll.c +++ b/drivers/clk/samsung/clk-pll.c @@ -49,24 +49,8 @@ static unsigned long samsung_pll35xx_recalc_rate(struct clk_hw *hw, return (unsigned long)fvco; } -/* todo: implement pl35xx clock round rate operation */ -static long samsung_pll35xx_round_rate(struct clk_hw *hw, - unsigned long drate, unsigned long *prate) -{ - return -ENOTSUPP; -} - -/* todo: implement pl35xx clock set rate */ -static int samsung_pll35xx_set_rate(struct clk_hw *hw, unsigned long drate, - unsigned long prate) -{ - return -ENOTSUPP; -} - static const struct clk_ops samsung_pll35xx_clk_ops = { .recalc_rate = samsung_pll35xx_recalc_rate, - .round_rate = samsung_pll35xx_round_rate, - .set_rate = samsung_pll35xx_set_rate, }; struct clk * __init samsung_clk_register_pll35xx(const char *name, @@ -144,24 +128,8 @@ static unsigned long samsung_pll36xx_recalc_rate(struct clk_hw *hw, return (unsigned long)fvco; } -/* todo: implement pl36xx clock round rate operation */ -static long samsung_pll36xx_round_rate(struct clk_hw *hw, - unsigned long drate, unsigned long *prate) -{ - return -ENOTSUPP; -} - -/* todo: implement pl36xx clock set rate */ -static int samsung_pll36xx_set_rate(struct clk_hw *hw, unsigned long drate, - unsigned long prate) -{ - return -ENOTSUPP; -} - static const struct clk_ops samsung_pll36xx_clk_ops = { .recalc_rate = samsung_pll36xx_recalc_rate, - .round_rate = samsung_pll36xx_round_rate, - .set_rate = samsung_pll36xx_set_rate, }; struct clk * __init samsung_clk_register_pll36xx(const char *name, @@ -239,24 +207,8 @@ static unsigned long samsung_pll45xx_recalc_rate(struct clk_hw *hw, return (unsigned long)fvco; } -/* todo: implement pl45xx clock round rate operation */ -static long samsung_pll45xx_round_rate(struct clk_hw *hw, - unsigned long drate, unsigned long *prate) -{ - return -ENOTSUPP; -} - -/* todo: implement pl45xx clock set rate */ -static int samsung_pll45xx_set_rate(struct clk_hw *hw, unsigned long drate, - unsigned long prate) -{ - return -ENOTSUPP; -} - static const struct clk_ops samsung_pll45xx_clk_ops = { .recalc_rate = samsung_pll45xx_recalc_rate, - .round_rate = samsung_pll45xx_round_rate, - .set_rate = samsung_pll45xx_set_rate, }; struct clk * __init samsung_clk_register_pll45xx(const char *name, @@ -342,24 +294,8 @@ static unsigned long samsung_pll46xx_recalc_rate(struct clk_hw *hw, return (unsigned long)fvco; } -/* todo: implement pl46xx clock round rate operation */ -static long samsung_pll46xx_round_rate(struct clk_hw *hw, - unsigned long drate, unsigned long *prate) -{ - return -ENOTSUPP; -} - -/* todo: implement pl46xx clock set rate */ -static int samsung_pll46xx_set_rate(struct clk_hw *hw, unsigned long drate, - unsigned long prate) -{ - return -ENOTSUPP; -} - static const struct clk_ops samsung_pll46xx_clk_ops = { .recalc_rate = samsung_pll46xx_recalc_rate, - .round_rate = samsung_pll46xx_round_rate, - .set_rate = samsung_pll46xx_set_rate, }; struct clk * __init samsung_clk_register_pll46xx(const char *name, @@ -441,24 +377,8 @@ static unsigned long samsung_pll2550x_recalc_rate(struct clk_hw *hw, return (unsigned long)fvco; } -/* todo: implement pl2550x clock round rate operation */ -static long samsung_pll2550x_round_rate(struct clk_hw *hw, - unsigned long drate, unsigned long *prate) -{ - return -ENOTSUPP; -} - -/* todo: implement pl2550x clock set rate */ -static int samsung_pll2550x_set_rate(struct clk_hw *hw, unsigned long drate, - unsigned long prate) -{ - return -ENOTSUPP; -} - static const struct clk_ops samsung_pll2550x_clk_ops = { .recalc_rate = samsung_pll2550x_recalc_rate, - .round_rate = samsung_pll2550x_round_rate, - .set_rate = samsung_pll2550x_set_rate, }; struct clk * __init samsung_clk_register_pll2550x(const char *name, -- cgit v1.2.3 From fba79e32a7dfe467a0803a372afa20ccb51ba294 Mon Sep 17 00:00:00 2001 From: Tomasz Figa Date: Thu, 4 Apr 2013 13:33:08 +0900 Subject: clk: exynos4: Export mout_core clock of Exynos4210 This patch enables clock lookup registration for mout_core clock used in Exynos4210 cpufreq driver. Signed-off-by: Tomasz Figa Signed-off-by: Kyungmin Park Reviewed-by: Thomas Abraham Acked-by: Mike Turquette Signed-off-by: Kukjin Kim --- drivers/clk/samsung/clk-exynos4.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers/clk') diff --git a/drivers/clk/samsung/clk-exynos4.c b/drivers/clk/samsung/clk-exynos4.c index 5592a78b2edc..f81888dfc5c7 100644 --- a/drivers/clk/samsung/clk-exynos4.c +++ b/drivers/clk/samsung/clk-exynos4.c @@ -311,7 +311,8 @@ struct samsung_mux_clock exynos4210_mux_clks[] __initdata = { MUX(none, "mout_fimd1", group1_p4210, SRC_LCD1, 0, 4), MUX(none, "mout_mipi1", group1_p4210, SRC_LCD1, 12, 4), MUX_A(sclk_mpll, "sclk_mpll", mout_mpll_p, SRC_CPU, 8, 1, "sclk_mpll"), - MUX(none, "mout_core", mout_core_p4210, SRC_CPU, 16, 1), + MUX_A(mout_core, "mout_core", mout_core_p4210, + SRC_CPU, 16, 1, "mout_core"), MUX_A(sclk_vpll, "sclk_vpll", sclk_vpll_p4210, SRC_TOP0, 8, 1, "sclk_vpll"), MUX(none, "mout_fimc0", group1_p4210, SRC_CAM, 0, 4), -- cgit v1.2.3 From 1e25810bbbc927348070da3f47a591315f3aa926 Mon Sep 17 00:00:00 2001 From: Sylwester Nawrocki Date: Thu, 4 Apr 2013 13:33:12 +0900 Subject: clk: exynos4: Add camera related clock definitions This patch adds several gate and mux clocks related to camera and ISP blocks. Signed-off-by: Sylwester Nawrocki Signed-off-by: Andrzej Hajda Signed-off-by: Tomasz Figa Signed-off-by: Kyungmin Park Reviewed-by: Thomas Abraham Acked-by: Mike Turquette Signed-off-by: Kukjin Kim --- drivers/clk/samsung/clk-exynos4.c | 50 ++++++++++++++++++++++++++------------- 1 file changed, 33 insertions(+), 17 deletions(-) (limited to 'drivers/clk') diff --git a/drivers/clk/samsung/clk-exynos4.c b/drivers/clk/samsung/clk-exynos4.c index f81888dfc5c7..6d7fa82aab87 100644 --- a/drivers/clk/samsung/clk-exynos4.c +++ b/drivers/clk/samsung/clk-exynos4.c @@ -87,6 +87,7 @@ #define E4210_MPLL_CON0 0x14108 #define SRC_CPU 0x14200 #define DIV_CPU0 0x14500 +#define E4X12_GATE_ISP0 0x18800 /* the exynos4 soc type */ enum exynos4_soc { @@ -136,7 +137,12 @@ enum exynos4_clks { uart4, i2c0, i2c1, i2c2, i2c3, i2c4, i2c5, i2c6, i2c7, i2c_hdmi, tsadc, spi0, spi1, spi2, i2s1, i2s2, pcm0, i2s0, pcm1, pcm2, pwm, slimbus, spdif, ac97, modemif, chipid, sysreg, hdmi_cec, mct, wdt, rtc, keyif, - audss, mipi_hsi, mdma2, + audss, mipi_hsi, mdma2, pixelasyncm0, pixelasyncm1, fimc_lite0, + fimc_lite1, ppmuispx, ppmuispmx, + + /* mux clocks */ + mout_fimc0 = 384, mout_fimc1, mout_fimc2, mout_fimc3, mout_cam0, + mout_cam1, mout_csis0, mout_csis1, nr_clks, }; @@ -315,14 +321,14 @@ struct samsung_mux_clock exynos4210_mux_clks[] __initdata = { SRC_CPU, 16, 1, "mout_core"), MUX_A(sclk_vpll, "sclk_vpll", sclk_vpll_p4210, SRC_TOP0, 8, 1, "sclk_vpll"), - MUX(none, "mout_fimc0", group1_p4210, SRC_CAM, 0, 4), - MUX(none, "mout_fimc1", group1_p4210, SRC_CAM, 4, 4), - MUX(none, "mout_fimc2", group1_p4210, SRC_CAM, 8, 4), - MUX(none, "mout_fimc3", group1_p4210, SRC_CAM, 12, 4), - MUX(none, "mout_cam0", group1_p4210, SRC_CAM, 16, 4), - MUX(none, "mout_cam1", group1_p4210, SRC_CAM, 20, 4), - MUX(none, "mout_csis0", group1_p4210, SRC_CAM, 24, 4), - MUX(none, "mout_csis1", group1_p4210, SRC_CAM, 28, 4), + MUX(mout_fimc0, "mout_fimc0", group1_p4210, SRC_CAM, 0, 4), + MUX(mout_fimc1, "mout_fimc1", group1_p4210, SRC_CAM, 4, 4), + MUX(mout_fimc2, "mout_fimc2", group1_p4210, SRC_CAM, 8, 4), + MUX(mout_fimc3, "mout_fimc3", group1_p4210, SRC_CAM, 12, 4), + MUX(mout_cam0, "mout_cam0", group1_p4210, SRC_CAM, 16, 4), + MUX(mout_cam1, "mout_cam1", group1_p4210, SRC_CAM, 20, 4), + MUX(mout_csis0, "mout_csis0", group1_p4210, SRC_CAM, 24, 4), + MUX(mout_csis1, "mout_csis1", group1_p4210, SRC_CAM, 28, 4), MUX(none, "mout_mfc0", sclk_ampll_p4210, SRC_MFC, 0, 1), MUX(none, "mout_g3d0", sclk_ampll_p4210, SRC_G3D, 0, 1), MUX(none, "mout_fimd0", group1_p4210, SRC_LCD0, 0, 4), @@ -366,14 +372,14 @@ struct samsung_mux_clock exynos4x12_mux_clks[] __initdata = { MUX_A(sclk_vpll, "sclk_vpll", mout_vpll_p, SRC_TOP0, 8, 1, "sclk_vpll"), MUX(mout_core, "mout_core", mout_core_p4x12, SRC_CPU, 16, 1), - MUX(none, "mout_fimc0", group1_p4x12, SRC_CAM, 0, 4), - MUX(none, "mout_fimc1", group1_p4x12, SRC_CAM, 4, 4), - MUX(none, "mout_fimc2", group1_p4x12, SRC_CAM, 8, 4), - MUX(none, "mout_fimc3", group1_p4x12, SRC_CAM, 12, 4), - MUX(none, "mout_cam0", group1_p4x12, SRC_CAM, 16, 4), - MUX(none, "mout_cam1", group1_p4x12, SRC_CAM, 20, 4), - MUX(none, "mout_csis0", group1_p4x12, SRC_CAM, 24, 4), - MUX(none, "mout_csis1", group1_p4x12, SRC_CAM, 28, 4), + MUX(mout_fimc0, "mout_fimc0", group1_p4x12, SRC_CAM, 0, 4), + MUX(mout_fimc1, "mout_fimc1", group1_p4x12, SRC_CAM, 4, 4), + MUX(mout_fimc2, "mout_fimc2", group1_p4x12, SRC_CAM, 8, 4), + MUX(mout_fimc3, "mout_fimc3", group1_p4x12, SRC_CAM, 12, 4), + MUX(mout_cam0, "mout_cam0", group1_p4x12, SRC_CAM, 16, 4), + MUX(mout_cam1, "mout_cam1", group1_p4x12, SRC_CAM, 20, 4), + MUX(mout_csis0, "mout_csis0", group1_p4x12, SRC_CAM, 24, 4), + MUX(mout_csis1, "mout_csis1", group1_p4x12, SRC_CAM, 28, 4), MUX(none, "mout_mfc0", sclk_ampll_p4x12, SRC_MFC, 0, 1), MUX(none, "mout_g3d0", sclk_ampll_p4x12, SRC_G3D, 0, 1), MUX(none, "mout_fimd0", group1_p4x12, SRC_LCD0, 0, 4), @@ -588,6 +594,8 @@ struct samsung_gate_clock exynos4_gate_clks[] __initdata = { GATE_IP_CAM, 10, 0, 0, "sysmmu"), GATE_DA(smmu_jpeg, "exynos-sysmmu.3", "smmu_jpeg", "aclk160", GATE_IP_CAM, 11, 0, 0, "sysmmu"), + GATE(pixelasyncm0, "pxl_async0", "aclk160", GATE_IP_CAM, 17, 0, 0), + GATE(pixelasyncm1, "pxl_async1", "aclk160", GATE_IP_CAM, 18, 0, 0), GATE_DA(smmu_tv, "exynos-sysmmu.2", "smmu_tv", "aclk160", GATE_IP_TV, 4, 0, 0, "sysmmu"), GATE_DA(mfc, "s5p-mfc", "mfc", "aclk100", GATE_IP_MFC, 0, 0, 0, "mfc"), @@ -722,6 +730,14 @@ struct samsung_gate_clock exynos4x12_gate_clks[] __initdata = { 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_lite0, "lite0", "aclk200", E4X12_GATE_ISP0, 3, + CLK_IGNORE_UNUSED, 0), + GATE(fimc_lite1, "lite1", "aclk200", E4X12_GATE_ISP0, 4, + CLK_IGNORE_UNUSED, 0), + GATE(ppmuispmx, "ppmuispmx", "aclk200", E4X12_GATE_ISP0, 20, + CLK_IGNORE_UNUSED, 0), + GATE(ppmuispx, "ppmuispx", "aclk200", E4X12_GATE_ISP0, 21, + CLK_IGNORE_UNUSED, 0), }; #ifdef CONFIG_OF -- cgit v1.2.3 From 8e1ce8393eb7c27a8aa38da3d245187ec808ba88 Mon Sep 17 00:00:00 2001 From: Tomasz Figa Date: Thu, 4 Apr 2013 13:33:17 +0900 Subject: clk: exynos4: Add G3D clocks This patch adds clocks needed for G3D block present on Exynos 4 SoCs. Signed-off-by: Tomasz Figa Signed-off-by: Kyungmin Park Reviewed-by: Thomas Abraham Acked-by: Mike Turquette Signed-off-by: Kukjin Kim --- drivers/clk/samsung/clk-exynos4.c | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) (limited to 'drivers/clk') diff --git a/drivers/clk/samsung/clk-exynos4.c b/drivers/clk/samsung/clk-exynos4.c index 6d7fa82aab87..ddd654bc9865 100644 --- a/drivers/clk/samsung/clk-exynos4.c +++ b/drivers/clk/samsung/clk-exynos4.c @@ -124,7 +124,7 @@ enum exynos4_clks { sclk_sata, sclk_uart0, sclk_uart1, sclk_uart2, sclk_uart3, sclk_uart4, sclk_audio1, sclk_audio2, sclk_spdif, sclk_spi0, sclk_spi1, sclk_spi2, sclk_slimbus, sclk_fimd1, sclk_mipi1, sclk_pcm1, sclk_pcm2, sclk_i2s1, - sclk_i2s2, sclk_mipihsi, sclk_mfc, sclk_pcm0, + sclk_i2s2, sclk_mipihsi, sclk_mfc, sclk_pcm0, sclk_g3d, /* gate clocks */ fimc0 = 256, fimc1, fimc2, fimc3, csis0, csis1, jpeg, smmu_fimc0, @@ -142,7 +142,7 @@ enum exynos4_clks { /* mux clocks */ mout_fimc0 = 384, mout_fimc1, mout_fimc2, mout_fimc3, mout_cam0, - mout_cam1, mout_csis0, mout_csis1, + mout_cam1, mout_csis0, mout_csis1, mout_g3d0, mout_g3d1, mout_g3d, nr_clks, }; @@ -296,8 +296,10 @@ struct samsung_mux_clock exynos4_mux_clks[] __initdata = { MUX(none, "mout_hdmi", mout_hdmi_p, SRC_TV, 0, 1), MUX(none, "mout_mfc1", sclk_evpll_p, SRC_MFC, 4, 1), MUX(none, "mout_mfc", mout_mfc_p, SRC_MFC, 8, 1), - MUX(none, "mout_g3d1", sclk_evpll_p, SRC_G3D, 4, 1), - MUX(none, "mout_g3d", mout_g3d_p, SRC_G3D, 8, 1), + MUX_F(mout_g3d1, "mout_g3d1", sclk_evpll_p, SRC_G3D, 4, 1, + CLK_SET_RATE_PARENT, 0), + MUX_F(mout_g3d, "mout_g3d", mout_g3d_p, SRC_G3D, 8, 1, + CLK_SET_RATE_PARENT, 0), MUX(none, "mout_spdif", mout_spdif_p, SRC_PERIL1, 8, 2), MUX_A(sclk_epll, "sclk_epll", mout_epll_p, SRC_TOP0, 4, 1, "sclk_epll"), }; @@ -330,7 +332,8 @@ struct samsung_mux_clock exynos4210_mux_clks[] __initdata = { MUX(mout_csis0, "mout_csis0", group1_p4210, SRC_CAM, 24, 4), MUX(mout_csis1, "mout_csis1", group1_p4210, SRC_CAM, 28, 4), MUX(none, "mout_mfc0", sclk_ampll_p4210, SRC_MFC, 0, 1), - MUX(none, "mout_g3d0", sclk_ampll_p4210, SRC_G3D, 0, 1), + MUX_F(mout_g3d0, "mout_g3d0", sclk_ampll_p4210, SRC_G3D, 0, 1, + CLK_SET_RATE_PARENT, 0), MUX(none, "mout_fimd0", group1_p4210, SRC_LCD0, 0, 4), MUX(none, "mout_mipi0", group1_p4210, SRC_LCD0, 12, 4), MUX(none, "mout_audio0", mout_audio0_p4210, SRC_MAUDIO, 0, 4), @@ -381,7 +384,8 @@ struct samsung_mux_clock exynos4x12_mux_clks[] __initdata = { MUX(mout_csis0, "mout_csis0", group1_p4x12, SRC_CAM, 24, 4), MUX(mout_csis1, "mout_csis1", group1_p4x12, SRC_CAM, 28, 4), MUX(none, "mout_mfc0", sclk_ampll_p4x12, SRC_MFC, 0, 1), - MUX(none, "mout_g3d0", sclk_ampll_p4x12, SRC_G3D, 0, 1), + MUX_F(mout_g3d0, "mout_g3d0", sclk_ampll_p4x12, SRC_G3D, 0, 1, + CLK_SET_RATE_PARENT, 0), MUX(none, "mout_fimd0", group1_p4x12, SRC_LCD0, 0, 4), MUX(none, "mout_mipi0", group1_p4x12, SRC_LCD0, 12, 4), MUX(none, "mout_audio0", mout_audio0_p4x12, SRC_MAUDIO, 0, 4), @@ -416,7 +420,8 @@ struct samsung_div_clock exynos4_div_clks[] __initdata = { DIV(none, "div_csis0", "mout_csis0", DIV_CAM, 24, 4), DIV(none, "div_csis1", "mout_csis1", DIV_CAM, 28, 4), DIV(sclk_mfc, "sclk_mfc", "mout_mfc", DIV_MFC, 0, 4), - DIV(none, "div_g3d", "mout_g3d", DIV_G3D, 0, 4), + DIV_F(none, "div_g3d", "mout_g3d", DIV_G3D, 0, 4, + CLK_SET_RATE_PARENT, 0), DIV(none, "div_fimd0", "mout_fimd0", DIV_LCD0, 0, 4), DIV(none, "div_mipi0", "mout_mipi0", DIV_LCD0, 16, 4), DIV(none, "div_audio0", "mout_audio0", DIV_MAUDIO, 0, 4), @@ -502,7 +507,8 @@ struct samsung_gate_clock exynos4_gate_clks[] __initdata = { GATE(smmu_fimd1, "smmu_fimd1", "aclk160", GATE_IP_LCD1, 4, 0, 0), GATE(tsi, "tsi", "aclk133", GATE_IP_FSYS, 4, 0, 0), GATE(sromc, "sromc", "aclk133", GATE_IP_FSYS, 11, 0, 0), - GATE(g3d, "g3d", "aclk200", GATE_IP_G3D, 0, 0, 0), + GATE(sclk_g3d, "sclk_g3d", "div_g3d", GATE_IP_G3D, 0, + CLK_SET_RATE_PARENT, 0), GATE(usb_device, "usb_device", "aclk133", GATE_IP_FSYS, 13, 0, 0), GATE(onenand, "onenand", "aclk133", GATE_IP_FSYS, 15, 0, 0), GATE(nfcon, "nfcon", "aclk133", GATE_IP_FSYS, 16, 0, 0), -- cgit v1.2.3 From 1554701528479c81240076b0c9251f4544be6319 Mon Sep 17 00:00:00 2001 From: Andrzej Hajda Date: Thu, 4 Apr 2013 13:33:22 +0900 Subject: clk: exynos4: Add missing CMU_TOP and ISP clocks The patch adds missing clocks to TOP and ISP clock domains. It also adds clock gates for ISP sub-blocks. Signed-off-by: Andrzej Hajda Signed-off-by: Tomasz Figa Signed-off-by: Kyungmin Park Reviewed-by: Thomas Abraham Acked-by: Mike Turquette Signed-off-by: Kukjin Kim --- drivers/clk/samsung/clk-exynos4.c | 110 ++++++++++++++++++++++++++++++++++++-- 1 file changed, 107 insertions(+), 3 deletions(-) (limited to 'drivers/clk') diff --git a/drivers/clk/samsung/clk-exynos4.c b/drivers/clk/samsung/clk-exynos4.c index ddd654bc9865..7e875a462d89 100644 --- a/drivers/clk/samsung/clk-exynos4.c +++ b/drivers/clk/samsung/clk-exynos4.c @@ -34,6 +34,7 @@ #define E4210_SRC_IMAGE 0xc230 #define SRC_LCD0 0xc234 #define SRC_LCD1 0xc238 +#define E4X12_SRC_ISP 0xc238 #define SRC_MAUDIO 0xc23c #define SRC_FSYS 0xc240 #define SRC_PERIL0 0xc250 @@ -43,6 +44,7 @@ #define SRC_MASK_TV 0xc324 #define SRC_MASK_LCD0 0xc334 #define SRC_MASK_LCD1 0xc338 +#define E4X12_SRC_MASK_ISP 0xc338 #define SRC_MASK_MAUDIO 0xc33c #define SRC_MASK_FSYS 0xc340 #define SRC_MASK_PERIL0 0xc350 @@ -76,6 +78,7 @@ #define E4210_GATE_IP_IMAGE 0xc930 #define GATE_IP_LCD0 0xc934 #define GATE_IP_LCD1 0xc938 +#define E4X12_GATE_IP_ISP 0xc938 #define E4X12_GATE_IP_MAUDIO 0xc93c #define GATE_IP_FSYS 0xc940 #define GATE_IP_GPS 0xc94c @@ -87,7 +90,10 @@ #define E4210_MPLL_CON0 0x14108 #define SRC_CPU 0x14200 #define DIV_CPU0 0x14500 +#define E4X12_DIV_ISP0 0x18300 +#define E4X12_DIV_ISP1 0x18304 #define E4X12_GATE_ISP0 0x18800 +#define E4X12_GATE_ISP1 0x18804 /* the exynos4 soc type */ enum exynos4_soc { @@ -124,7 +130,8 @@ enum exynos4_clks { sclk_sata, sclk_uart0, sclk_uart1, sclk_uart2, sclk_uart3, sclk_uart4, sclk_audio1, sclk_audio2, sclk_spdif, sclk_spi0, sclk_spi1, sclk_spi2, sclk_slimbus, sclk_fimd1, sclk_mipi1, sclk_pcm1, sclk_pcm2, sclk_i2s1, - sclk_i2s2, sclk_mipihsi, sclk_mfc, sclk_pcm0, sclk_g3d, + sclk_i2s2, sclk_mipihsi, sclk_mfc, sclk_pcm0, sclk_g3d, sclk_pwm_isp, + sclk_spi0_isp, sclk_spi1_isp, sclk_uart_isp, /* gate clocks */ fimc0 = 256, fimc1, fimc2, fimc3, csis0, csis1, jpeg, smmu_fimc0, @@ -138,7 +145,11 @@ enum exynos4_clks { spi0, spi1, spi2, i2s1, i2s2, pcm0, i2s0, pcm1, pcm2, pwm, slimbus, spdif, ac97, modemif, chipid, sysreg, hdmi_cec, mct, wdt, rtc, keyif, audss, mipi_hsi, mdma2, pixelasyncm0, pixelasyncm1, fimc_lite0, - fimc_lite1, ppmuispx, ppmuispmx, + fimc_lite1, ppmuispx, ppmuispmx, fimc_isp, fimc_drc, fimc_fd, mcuisp, + gicisp, smmu_isp, smmu_drc, smmu_fd, smmu_lite0, smmu_lite1, mcuctl_isp, + mpwm_isp, i2c0_isp, i2c1_isp, mtcadc_isp, pwm_isp, wdt_isp, uart_isp, + asyncaxim, smmu_ispcx, spi0_isp, spi1_isp, pwm_isp_sclk, spi0_isp_sclk, + spi1_isp_sclk, uart_isp_sclk, /* mux clocks */ mout_fimc0 = 384, mout_fimc1, mout_fimc2, mout_fimc3, mout_cam0, @@ -234,6 +245,8 @@ PNAME(mout_hdmi_p) = { "sclk_pixel", "sclk_hdmiphy", }; PNAME(mout_jpeg_p) = { "mout_jpeg0", "mout_jpeg1", }; PNAME(mout_spdif_p) = { "sclk_audio0", "sclk_audio1", "sclk_audio2", "spdif_extclk", }; +PNAME(mout_onenand_p) = {"aclk133", "aclk160", }; +PNAME(mout_onenand1_p) = {"mout_onenand", "sclk_vpll", }; /* Exynos 4210-specific parent groups */ PNAME(sclk_vpll_p4210) = { "mout_vpllsrc", "fout_vpll", }; @@ -271,6 +284,9 @@ PNAME(mout_audio2_p4x12) = { "cdclk2", "none", "sclk_hdmi24m", "sclk_usbphy0", "xxti", "xusbxti", "mout_mpll_user_t", "sclk_epll", "sclk_vpll", }; PNAME(aclk_p4412) = { "mout_mpll_user_t", "sclk_apll", }; +PNAME(mout_user_aclk400_mcuisp_p4x12) = {"fin_pll", "div_aclk400_mcuisp", }; +PNAME(mout_user_aclk200_p4x12) = {"fin_pll", "div_aclk200", }; +PNAME(mout_user_aclk266_gps_p4x12) = {"fin_pll", "div_aclk266_gps", }; /* fixed rate clocks generated outside the soc */ struct samsung_fixed_rate_clock exynos4_fixed_rate_ext_clks[] __initdata = { @@ -301,7 +317,9 @@ struct samsung_mux_clock exynos4_mux_clks[] __initdata = { MUX_F(mout_g3d, "mout_g3d", mout_g3d_p, SRC_G3D, 8, 1, CLK_SET_RATE_PARENT, 0), MUX(none, "mout_spdif", mout_spdif_p, SRC_PERIL1, 8, 2), + MUX(none, "mout_onenand1", mout_onenand1_p, SRC_TOP0, 0, 1), MUX_A(sclk_epll, "sclk_epll", mout_epll_p, SRC_TOP0, 4, 1, "sclk_epll"), + MUX(none, "mout_onenand", mout_onenand_p, SRC_TOP0, 28, 1), }; /* list of mux clocks supported in exynos4210 soc */ @@ -358,8 +376,15 @@ struct samsung_mux_clock exynos4210_mux_clks[] __initdata = { struct samsung_mux_clock exynos4x12_mux_clks[] __initdata = { MUX(mout_mpll_user_c, "mout_mpll_user_c", mout_mpll_user_p4x12, SRC_CPU, 24, 1), + MUX(none, "mout_aclk266_gps", aclk_p4412, SRC_TOP1, 4, 1), + MUX(none, "mout_aclk400_mcuisp", aclk_p4412, SRC_TOP1, 8, 1), MUX(mout_mpll_user_t, "mout_mpll_user_t", mout_mpll_user_p4x12, SRC_TOP1, 12, 1), + MUX(none, "mout_user_aclk266_gps", mout_user_aclk266_gps_p4x12, + SRC_TOP1, 16, 1), + MUX(aclk200, "aclk200", mout_user_aclk200_p4x12, SRC_TOP1, 20, 1), + MUX(none, "aclk400_mcuisp", mout_user_aclk400_mcuisp_p4x12, + SRC_TOP1, 24, 1), MUX(none, "mout_aclk200", aclk_p4412, SRC_TOP0, 12, 1), MUX(none, "mout_aclk100", aclk_p4412, SRC_TOP0, 16, 1), MUX(none, "mout_aclk160", aclk_p4412, SRC_TOP0, 20, 1), @@ -405,6 +430,10 @@ struct samsung_mux_clock exynos4x12_mux_clks[] __initdata = { MUX(none, "mout_spi0", group1_p4x12, SRC_PERIL1, 16, 4), MUX(none, "mout_spi1", group1_p4x12, SRC_PERIL1, 20, 4), MUX(none, "mout_spi2", group1_p4x12, SRC_PERIL1, 24, 4), + MUX(none, "mout_pwm_isp", group1_p4x12, E4X12_SRC_ISP, 0, 4), + MUX(none, "mout_spi0_isp", group1_p4x12, E4X12_SRC_ISP, 4, 4), + MUX(none, "mout_spi1_isp", group1_p4x12, E4X12_SRC_ISP, 8, 4), + MUX(none, "mout_uart_isp", group1_p4x12, E4X12_SRC_ISP, 12, 4), }; /* list of divider clocks supported in all exynos4 soc's */ @@ -431,10 +460,10 @@ struct samsung_div_clock exynos4_div_clks[] __initdata = { DIV(none, "div_mmc2", "mout_mmc2", DIV_FSYS2, 0, 4), DIV(none, "div_mmc3", "mout_mmc3", DIV_FSYS2, 16, 4), DIV(sclk_pixel, "sclk_pixel", "sclk_vpll", DIV_TV, 0, 4), - DIV(aclk200, "aclk200", "mout_aclk200", DIV_TOP, 0, 3), DIV(aclk100, "aclk100", "mout_aclk100", DIV_TOP, 4, 4), DIV(aclk160, "aclk160", "mout_aclk160", DIV_TOP, 8, 3), DIV(aclk133, "aclk133", "mout_aclk133", DIV_TOP, 12, 3), + DIV(none, "div_onenand", "mout_onenand1", DIV_TOP, 16, 3), DIV(sclk_slimbus, "sclk_slimbus", "sclk_epll", DIV_PERIL3, 4, 4), DIV(sclk_pcm1, "sclk_pcm1", "sclk_audio1", DIV_PERIL4, 4, 8), DIV(sclk_pcm2, "sclk_pcm2", "sclk_audio2", DIV_PERIL4, 20, 8), @@ -472,6 +501,7 @@ struct samsung_div_clock exynos4_div_clks[] __initdata = { /* list of divider clocks supported in exynos4210 soc */ struct samsung_div_clock exynos4210_div_clks[] __initdata = { + DIV(aclk200, "aclk200", "mout_aclk200", DIV_TOP, 0, 3), DIV(none, "div_g2d", "mout_g2d", DIV_IMAGE, 0, 4), DIV(none, "div_fimd1", "mout_fimd1", E4210_DIV_LCD1, 0, 4), DIV(none, "div_mipi1", "mout_mipi1", E4210_DIV_LCD1, 16, 4), @@ -487,6 +517,20 @@ struct samsung_div_clock exynos4x12_div_clks[] __initdata = { DIV(none, "div_mdnie_pwm_pre0", "div_mdnie_pwm0", DIV_LCD0, 12, 4), DIV(none, "div_mipihsi", "mout_mipihsi", DIV_FSYS0, 20, 4), DIV(none, "div_jpeg", "mout_jpeg", E4X12_DIV_CAM1, 0, 4), + DIV(none, "div_aclk200", "mout_aclk200", DIV_TOP, 0, 3), + DIV(none, "div_aclk266_gps", "mout_aclk266_gps", DIV_TOP, 20, 3), + DIV(none, "div_aclk400_mcuisp", "mout_aclk400_mcuisp", DIV_TOP, 24, 3), + DIV(none, "div_pwm_isp", "mout_pwm_isp", E4X12_DIV_ISP, 0, 4), + DIV(none, "div_spi0_isp", "mout_spi0_isp", E4X12_DIV_ISP, 4, 4), + DIV(none, "div_spi0_isp_pre", "div_spi0_isp", E4X12_DIV_ISP, 8, 8), + DIV(none, "div_spi1_isp", "mout_spi1_isp", E4X12_DIV_ISP, 16, 4), + DIV(none, "div_spi1_isp_pre", "div_spi1_isp", E4X12_DIV_ISP, 20, 8), + DIV(none, "div_uart_isp", "mout_uart_isp", E4X12_DIV_ISP, 28, 4), + DIV(none, "div_isp0", "aclk200", E4X12_DIV_ISP0, 0, 3), + DIV(none, "div_isp1", "aclk200", E4X12_DIV_ISP0, 4, 3), + DIV(none, "div_mpwm", "div_isp1", E4X12_DIV_ISP1, 0, 3), + DIV(none, "div_mcuisp0", "aclk400_mcuisp", E4X12_DIV_ISP1, 4, 3), + DIV(none, "div_mcuisp1", "div_mcuisp0", E4X12_DIV_ISP1, 8, 3), }; /* list of gate clocks supported in all exynos4 soc's */ @@ -730,20 +774,80 @@ struct samsung_gate_clock exynos4x12_gate_clks[] __initdata = { GATE_A(rtc, "rtc", "aclk100", E4X12_GATE_IP_PERIR, 15, 0, 0, "rtc"), GATE_A(keyif, "keyif", "aclk100", E4X12_GATE_IP_PERIR, 16, 0, 0, "keypad"), + GATE(sclk_pwm_isp, "sclk_pwm_isp", "div_pwm_isp", + E4X12_SRC_MASK_ISP, 0, CLK_SET_RATE_PARENT, 0), + GATE(sclk_spi0_isp, "sclk_spi0_isp", "div_spi0_isp_pre", + E4X12_SRC_MASK_ISP, 4, CLK_SET_RATE_PARENT, 0), + GATE(sclk_spi1_isp, "sclk_spi1_isp", "div_spi1_isp_pre", + E4X12_SRC_MASK_ISP, 8, CLK_SET_RATE_PARENT, 0), + GATE(sclk_uart_isp, "sclk_uart_isp", "div_uart_isp", + E4X12_SRC_MASK_ISP, 12, CLK_SET_RATE_PARENT, 0), + GATE(pwm_isp_sclk, "pwm_isp_sclk", "sclk_pwm_isp", + E4X12_GATE_IP_ISP, 0, 0, 0), + GATE(spi0_isp_sclk, "spi0_isp_sclk", "sclk_spi0_isp", + E4X12_GATE_IP_ISP, 1, 0, 0), + GATE(spi1_isp_sclk, "spi1_isp_sclk", "sclk_spi1_isp", + E4X12_GATE_IP_ISP, 2, 0, 0), + GATE(uart_isp_sclk, "uart_isp_sclk", "sclk_uart_isp", + 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, + CLK_IGNORE_UNUSED, 0), + GATE(fimc_fd, "fd", "aclk200", E4X12_GATE_ISP0, 2, + CLK_IGNORE_UNUSED, 0), GATE(fimc_lite0, "lite0", "aclk200", E4X12_GATE_ISP0, 3, CLK_IGNORE_UNUSED, 0), GATE(fimc_lite1, "lite1", "aclk200", E4X12_GATE_ISP0, 4, CLK_IGNORE_UNUSED, 0), + GATE(mcuisp, "mcuisp", "aclk200", E4X12_GATE_ISP0, 5, + CLK_IGNORE_UNUSED, 0), + GATE(gicisp, "gicisp", "aclk200", E4X12_GATE_ISP0, 7, + CLK_IGNORE_UNUSED, 0), + GATE(smmu_isp, "smmu_isp", "aclk200", E4X12_GATE_ISP0, 8, + CLK_IGNORE_UNUSED, 0), + GATE(smmu_drc, "smmu_drc", "aclk200", E4X12_GATE_ISP0, 9, + CLK_IGNORE_UNUSED, 0), + GATE(smmu_fd, "smmu_fd", "aclk200", E4X12_GATE_ISP0, 10, + CLK_IGNORE_UNUSED, 0), + GATE(smmu_lite0, "smmu_lite0", "aclk200", E4X12_GATE_ISP0, 11, + CLK_IGNORE_UNUSED, 0), + GATE(smmu_lite1, "smmu_lite1", "aclk200", E4X12_GATE_ISP0, 12, + CLK_IGNORE_UNUSED, 0), GATE(ppmuispmx, "ppmuispmx", "aclk200", E4X12_GATE_ISP0, 20, CLK_IGNORE_UNUSED, 0), GATE(ppmuispx, "ppmuispx", "aclk200", E4X12_GATE_ISP0, 21, CLK_IGNORE_UNUSED, 0), + GATE(mcuctl_isp, "mcuctl_isp", "aclk200", E4X12_GATE_ISP0, 23, + CLK_IGNORE_UNUSED, 0), + GATE(mpwm_isp, "mpwm_isp", "aclk200", E4X12_GATE_ISP0, 24, + CLK_IGNORE_UNUSED, 0), + GATE(i2c0_isp, "i2c0_isp", "aclk200", E4X12_GATE_ISP0, 25, + CLK_IGNORE_UNUSED, 0), + GATE(i2c1_isp, "i2c1_isp", "aclk200", E4X12_GATE_ISP0, 26, + CLK_IGNORE_UNUSED, 0), + GATE(mtcadc_isp, "mtcadc_isp", "aclk200", E4X12_GATE_ISP0, 27, + CLK_IGNORE_UNUSED, 0), + GATE(pwm_isp, "pwm_isp", "aclk200", E4X12_GATE_ISP0, 28, + CLK_IGNORE_UNUSED, 0), + GATE(wdt_isp, "wdt_isp", "aclk200", E4X12_GATE_ISP0, 30, + CLK_IGNORE_UNUSED, 0), + GATE(uart_isp, "uart_isp", "aclk200", E4X12_GATE_ISP0, 31, + CLK_IGNORE_UNUSED, 0), + GATE(asyncaxim, "asyncaxim", "aclk200", E4X12_GATE_ISP1, 0, + CLK_IGNORE_UNUSED, 0), + GATE(smmu_ispcx, "smmu_ispcx", "aclk200", E4X12_GATE_ISP1, 4, + CLK_IGNORE_UNUSED, 0), + GATE(spi0_isp, "spi0_isp", "aclk200", E4X12_GATE_ISP1, 12, + CLK_IGNORE_UNUSED, 0), + GATE(spi1_isp, "spi1_isp", "aclk200", E4X12_GATE_ISP1, 13, + CLK_IGNORE_UNUSED, 0), }; #ifdef CONFIG_OF -- cgit v1.2.3 From 8e79561c41ec7746361a1e9a079c7225e010515e Mon Sep 17 00:00:00 2001 From: Tomasz Figa Date: Thu, 4 Apr 2013 13:33:27 +0900 Subject: clk: exynos4: Add missing mout_sata on Exynos4210 This patch adds missing mout_sata that is a parent of div_sata clock. Signed-off-by: Tomasz Figa Signed-off-by: Kyungmin Park Reviewed-by: Thomas Abraham Acked-by: Mike Turquette Signed-off-by: Kukjin Kim --- drivers/clk/samsung/clk-exynos4.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers/clk') diff --git a/drivers/clk/samsung/clk-exynos4.c b/drivers/clk/samsung/clk-exynos4.c index 7e875a462d89..e572f62ec423 100644 --- a/drivers/clk/samsung/clk-exynos4.c +++ b/drivers/clk/samsung/clk-exynos4.c @@ -360,6 +360,7 @@ struct samsung_mux_clock exynos4210_mux_clks[] __initdata = { MUX(none, "mout_mmc2", group1_p4210, SRC_FSYS, 8, 4), MUX(none, "mout_mmc3", group1_p4210, SRC_FSYS, 12, 4), MUX(none, "mout_mmc4", group1_p4210, SRC_FSYS, 16, 4), + MUX(none, "mout_sata", sclk_ampll_p4210, SRC_FSYS, 24, 1), MUX(none, "mout_uart0", group1_p4210, SRC_PERIL0, 0, 4), MUX(none, "mout_uart1", group1_p4210, SRC_PERIL0, 4, 4), MUX(none, "mout_uart2", group1_p4210, SRC_PERIL0, 8, 4), -- cgit v1.2.3 From 6d7190f846e74be2cbaae4cd56d1a5385e46f6ff Mon Sep 17 00:00:00 2001 From: Tomasz Figa Date: Thu, 4 Apr 2013 13:33:30 +0900 Subject: clk: exynos4: Define {E,V}PLL registers This patch adds preprocessor definitions of EPLL and VPLL registers and replaces all occurences of offsets of related registers with new definitions. Signed-off-by: Tomasz Figa Signed-off-by: Kyungmin Park Reviewed-by: Thomas Abraham Acked-by: Mike Turquette Signed-off-by: Kukjin Kim --- drivers/clk/samsung/clk-exynos4.c | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) (limited to 'drivers/clk') diff --git a/drivers/clk/samsung/clk-exynos4.c b/drivers/clk/samsung/clk-exynos4.c index e572f62ec423..57aa527981b5 100644 --- a/drivers/clk/samsung/clk-exynos4.c +++ b/drivers/clk/samsung/clk-exynos4.c @@ -25,6 +25,14 @@ #define E4X12_GATE_IP_IMAGE 0x4930 #define GATE_IP_RIGHTBUS 0x8800 #define E4X12_GATE_IP_PERIR 0x8960 +#define EPLL_LOCK 0xc010 +#define VPLL_LOCK 0xc020 +#define EPLL_CON0 0xc110 +#define EPLL_CON1 0xc114 +#define EPLL_CON2 0xc118 +#define VPLL_CON0 0xc120 +#define VPLL_CON1 0xc124 +#define VPLL_CON2 0xc128 #define SRC_TOP0 0xc210 #define SRC_TOP1 0xc214 #define SRC_CAM 0xc220 @@ -969,18 +977,18 @@ void __init exynos4_clk_init(struct device_node *np) mpll = samsung_clk_register_pll45xx("fout_mpll", "fin_pll", reg_base + E4210_MPLL_CON0, pll_4508); epll = samsung_clk_register_pll46xx("fout_epll", "fin_pll", - reg_base + 0xc110, pll_4600); + reg_base + EPLL_CON0, pll_4600); vpll = samsung_clk_register_pll46xx("fout_vpll", "mout_vpllsrc", - reg_base + 0xc120, pll_4650c); + reg_base + VPLL_CON0, pll_4650c); } else { apll = samsung_clk_register_pll35xx("fout_apll", "fin_pll", reg_base + APLL_CON0); mpll = samsung_clk_register_pll35xx("fout_mpll", "fin_pll", reg_base + E4X12_MPLL_CON0); epll = samsung_clk_register_pll36xx("fout_epll", "fin_pll", - reg_base + 0xc110); + reg_base + EPLL_CON0); vpll = samsung_clk_register_pll36xx("fout_vpll", "fin_pll", - reg_base + 0xc120); + reg_base + VPLL_CON0); } samsung_clk_add_lookup(apll, fout_apll); -- cgit v1.2.3 From 017ab64bdbca6f2f421d59a8235cdee90da08463 Mon Sep 17 00:00:00 2001 From: Tomasz Figa Date: Thu, 4 Apr 2013 13:33:34 +0900 Subject: clk: exynos4: Use SRC_MASK_PERIL{0,1} definitions There are definitions of SRC_MASK_PERIL0 and SRC_MASK_PERIL1 registers, but they are not used for clock definitions. This patch modifies related clock definitions to use defined macros instead of numeric offsets. Signed-off-by: Tomasz Figa Signed-off-by: Kyungmin Park Reviewed-by: Thomas Abraham Acked-by: Mike Turquette Signed-off-by: Kukjin Kim --- drivers/clk/samsung/clk-exynos4.c | 30 +++++++++++++++++++----------- 1 file changed, 19 insertions(+), 11 deletions(-) (limited to 'drivers/clk') diff --git a/drivers/clk/samsung/clk-exynos4.c b/drivers/clk/samsung/clk-exynos4.c index 57aa527981b5..5e26d5d0d8a3 100644 --- a/drivers/clk/samsung/clk-exynos4.c +++ b/drivers/clk/samsung/clk-exynos4.c @@ -550,7 +550,7 @@ struct samsung_gate_clock exynos4_gate_clks[] __initdata = { * of the clocks can be removed. */ GATE(sclk_hdmi, "sclk_hdmi", "mout_hdmi", SRC_MASK_TV, 0, 0, 0), - GATE(sclk_spdif, "sclk_spdif", "mout_spdif", 0xc354, 8, 0, 0), + GATE(sclk_spdif, "sclk_spdif", "mout_spdif", SRC_MASK_PERIL1, 8, 0, 0), GATE(jpeg, "jpeg", "aclk160", GATE_IP_CAM, 6, 0, 0), GATE(mie0, "mie0", "aclk160", GATE_IP_LCD0, 1, 0, 0), GATE(dsim0, "dsim0", "aclk160", GATE_IP_LCD0, 3, 0, 0), @@ -576,7 +576,7 @@ struct samsung_gate_clock exynos4_gate_clks[] __initdata = { SRC_MASK_LCD0, 12, CLK_SET_RATE_PARENT, 0), GATE(sclk_audio0, "sclk_audio0", "div_audio0", SRC_MASK_MAUDIO, 0, CLK_SET_RATE_PARENT, 0), - GATE(sclk_audio1, "sclk_audio1", "div_audio1", 0xc354, 0, + GATE(sclk_audio1, "sclk_audio1", "div_audio1", SRC_MASK_PERIL1, 0, CLK_SET_RATE_PARENT, 0), GATE_D(vp, "s5p-mixer", "vp", "aclk160", GATE_IP_TV, 0, 0, 0), GATE_D(mixer, "s5p-mixer", "mixer", "aclk160", GATE_IP_TV, 1, 0, 0), @@ -614,23 +614,31 @@ struct samsung_gate_clock exynos4_gate_clks[] __initdata = { GATE_DA(sclk_mmc4, NULL, "sclk_mmc4", "div_mmc_pre4", SRC_MASK_FSYS, 16, CLK_SET_RATE_PARENT, 0, "ciu"), GATE_DA(sclk_uart0, "exynos4210-uart.0", "uclk0", "div_uart0", - 0xc350, 0, CLK_SET_RATE_PARENT, 0, "clk_uart_baud0"), + SRC_MASK_PERIL0, 0, CLK_SET_RATE_PARENT, + 0, "clk_uart_baud0"), GATE_DA(sclk_uart1, "exynos4210-uart.1", "uclk1", "div_uart1", - 0xc350, 4, CLK_SET_RATE_PARENT, 0, "clk_uart_baud0"), + SRC_MASK_PERIL0, 4, CLK_SET_RATE_PARENT, + 0, "clk_uart_baud0"), GATE_DA(sclk_uart2, "exynos4210-uart.2", "uclk2", "div_uart2", - 0xc350, 8, CLK_SET_RATE_PARENT, 0, "clk_uart_baud0"), + SRC_MASK_PERIL0, 8, CLK_SET_RATE_PARENT, + 0, "clk_uart_baud0"), GATE_DA(sclk_uart3, "exynos4210-uart.3", "uclk3", "div_uart3", - 0xc350, 12, CLK_SET_RATE_PARENT, 0, "clk_uart_baud0"), + SRC_MASK_PERIL0, 12, CLK_SET_RATE_PARENT, + 0, "clk_uart_baud0"), GATE_DA(sclk_uart4, "exynos4210-uart.4", "uclk4", "div_uart4", - 0xc350, 16, CLK_SET_RATE_PARENT, 0, "clk_uart_baud0"), - GATE(sclk_audio2, "sclk_audio2", "div_audio2", 0xc354, 4, + SRC_MASK_PERIL0, 16, CLK_SET_RATE_PARENT, + 0, "clk_uart_baud0"), + GATE(sclk_audio2, "sclk_audio2", "div_audio2", SRC_MASK_PERIL1, 4, CLK_SET_RATE_PARENT, 0), GATE_DA(sclk_spi0, "exynos4210-spi.0", "sclk_spi0", "div_spi_pre0", - 0xc354, 16, CLK_SET_RATE_PARENT, 0, "spi_busclk0"), + SRC_MASK_PERIL1, 16, CLK_SET_RATE_PARENT, + 0, "spi_busclk0"), GATE_DA(sclk_spi1, "exynos4210-spi.1", "sclk_spi1", "div_spi_pre1", - 0xc354, 20, CLK_SET_RATE_PARENT, 0, "spi_busclk0"), + SRC_MASK_PERIL1, 20, CLK_SET_RATE_PARENT, + 0, "spi_busclk0"), GATE_DA(sclk_spi2, "exynos4210-spi.2", "sclk_spi2", "div_spi_pre2", - 0xc354, 24, CLK_SET_RATE_PARENT, 0, "spi_busclk0"), + SRC_MASK_PERIL1, 24, CLK_SET_RATE_PARENT, + 0, "spi_busclk0"), GATE_DA(fimc0, "exynos4-fimc.0", "fimc0", "aclk160", GATE_IP_CAM, 0, 0, 0, "fimc"), GATE_DA(fimc1, "exynos4-fimc.1", "fimc1", "aclk160", -- cgit v1.2.3 From 0f1fce908efb2aa76b713d424b422f117376a04a Mon Sep 17 00:00:00 2001 From: Tomasz Figa Date: Thu, 4 Apr 2013 13:33:37 +0900 Subject: clk: exynos4: Remove SoC-specific registers from save list Current clock save list is shared for all Exynos4 SoCs, so it must contain only registers present in all supported SoCs, because accessing unavailable registers might have undefined effect. This patch removes registers specific for particular SoCs from shared save list, as they should be supported by separate SoC-specific lists. Signed-off-by: Tomasz Figa Signed-off-by: Kyungmin Park Reviewed-by: Thomas Abraham Acked-by: Mike Turquette Signed-off-by: Kukjin Kim --- drivers/clk/samsung/clk-exynos4.c | 16 ---------------- 1 file changed, 16 deletions(-) (limited to 'drivers/clk') diff --git a/drivers/clk/samsung/clk-exynos4.c b/drivers/clk/samsung/clk-exynos4.c index 5e26d5d0d8a3..7ae0a0560354 100644 --- a/drivers/clk/samsung/clk-exynos4.c +++ b/drivers/clk/samsung/clk-exynos4.c @@ -172,27 +172,21 @@ enum exynos4_clks { */ static __initdata unsigned long exynos4_clk_regs[] = { SRC_LEFTBUS, - E4X12_GATE_IP_IMAGE, GATE_IP_RIGHTBUS, - E4X12_GATE_IP_PERIR, SRC_TOP0, SRC_TOP1, SRC_CAM, SRC_TV, SRC_MFC, SRC_G3D, - E4210_SRC_IMAGE, SRC_LCD0, - SRC_LCD1, SRC_MAUDIO, SRC_FSYS, SRC_PERIL0, SRC_PERIL1, - E4X12_SRC_CAM1, SRC_MASK_CAM, SRC_MASK_TV, SRC_MASK_LCD0, - SRC_MASK_LCD1, SRC_MASK_MAUDIO, SRC_MASK_FSYS, SRC_MASK_PERIL0, @@ -204,8 +198,6 @@ static __initdata unsigned long exynos4_clk_regs[] = { DIV_G3D, DIV_IMAGE, DIV_LCD0, - E4210_DIV_LCD1, - E4X12_DIV_ISP, DIV_MAUDIO, DIV_FSYS0, DIV_FSYS1, @@ -217,24 +209,16 @@ static __initdata unsigned long exynos4_clk_regs[] = { DIV_PERIL3, DIV_PERIL4, DIV_PERIL5, - E4X12_DIV_CAM1, GATE_SCLK_CAM, GATE_IP_CAM, GATE_IP_TV, GATE_IP_MFC, GATE_IP_G3D, - E4210_GATE_IP_IMAGE, GATE_IP_LCD0, - GATE_IP_LCD1, - E4X12_GATE_IP_MAUDIO, GATE_IP_FSYS, GATE_IP_GPS, GATE_IP_PERIL, - GATE_IP_PERIR, - E4X12_MPLL_CON0, - E4X12_SRC_DMC, APLL_CON0, - E4210_MPLL_CON0, SRC_CPU, DIV_CPU0, }; -- cgit v1.2.3 From 7406ee7c2a31c0fad0d8062de93fcb58d1fa498c Mon Sep 17 00:00:00 2001 From: Tomasz Figa Date: Thu, 4 Apr 2013 13:35:18 +0900 Subject: clk: exynos4: Add E4210 prefix to LCD1 clock registers This patch adds E4210 prefix to all registers related to LCD1 clock domain, because they are present only on Exynos4210. Signed-off-by: Tomasz Figa Signed-off-by: Kyungmin Park Reviewed-by: Thomas Abraham Acked-by: Mike Turquette Signed-off-by: Kukjin Kim --- drivers/clk/samsung/clk-exynos4.c | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) (limited to 'drivers/clk') diff --git a/drivers/clk/samsung/clk-exynos4.c b/drivers/clk/samsung/clk-exynos4.c index 7ae0a0560354..3d8a8a6fc5d0 100644 --- a/drivers/clk/samsung/clk-exynos4.c +++ b/drivers/clk/samsung/clk-exynos4.c @@ -41,7 +41,7 @@ #define SRC_G3D 0xc22c #define E4210_SRC_IMAGE 0xc230 #define SRC_LCD0 0xc234 -#define SRC_LCD1 0xc238 +#define E4210_SRC_LCD1 0xc238 #define E4X12_SRC_ISP 0xc238 #define SRC_MAUDIO 0xc23c #define SRC_FSYS 0xc240 @@ -51,7 +51,7 @@ #define SRC_MASK_CAM 0xc320 #define SRC_MASK_TV 0xc324 #define SRC_MASK_LCD0 0xc334 -#define SRC_MASK_LCD1 0xc338 +#define E4210_SRC_MASK_LCD1 0xc338 #define E4X12_SRC_MASK_ISP 0xc338 #define SRC_MASK_MAUDIO 0xc33c #define SRC_MASK_FSYS 0xc340 @@ -85,7 +85,7 @@ #define GATE_IP_G3D 0xc92c #define E4210_GATE_IP_IMAGE 0xc930 #define GATE_IP_LCD0 0xc934 -#define GATE_IP_LCD1 0xc938 +#define E4210_GATE_IP_LCD1 0xc938 #define E4X12_GATE_IP_ISP 0xc938 #define E4X12_GATE_IP_MAUDIO 0xc93c #define GATE_IP_FSYS 0xc940 @@ -326,8 +326,8 @@ struct samsung_mux_clock exynos4210_mux_clks[] __initdata = { MUX(none, "mout_g2d0", sclk_ampll_p4210, E4210_SRC_IMAGE, 0, 1), MUX(none, "mout_g2d1", sclk_evpll_p, E4210_SRC_IMAGE, 4, 1), MUX(none, "mout_g2d", mout_g2d_p, E4210_SRC_IMAGE, 8, 1), - MUX(none, "mout_fimd1", group1_p4210, SRC_LCD1, 0, 4), - MUX(none, "mout_mipi1", group1_p4210, SRC_LCD1, 12, 4), + MUX(none, "mout_fimd1", group1_p4210, E4210_SRC_LCD1, 0, 4), + MUX(none, "mout_mipi1", group1_p4210, E4210_SRC_LCD1, 12, 4), MUX_A(sclk_mpll, "sclk_mpll", mout_mpll_p, SRC_CPU, 8, 1, "sclk_mpll"), MUX_A(mout_core, "mout_core", mout_core_p4210, SRC_CPU, 16, 1, "mout_core"), @@ -538,10 +538,10 @@ struct samsung_gate_clock exynos4_gate_clks[] __initdata = { GATE(jpeg, "jpeg", "aclk160", GATE_IP_CAM, 6, 0, 0), GATE(mie0, "mie0", "aclk160", GATE_IP_LCD0, 1, 0, 0), GATE(dsim0, "dsim0", "aclk160", GATE_IP_LCD0, 3, 0, 0), - GATE(fimd1, "fimd1", "aclk160", GATE_IP_LCD1, 0, 0, 0), - GATE(mie1, "mie1", "aclk160", GATE_IP_LCD1, 1, 0, 0), - GATE(dsim1, "dsim1", "aclk160", GATE_IP_LCD1, 3, 0, 0), - GATE(smmu_fimd1, "smmu_fimd1", "aclk160", GATE_IP_LCD1, 4, 0, 0), + GATE(fimd1, "fimd1", "aclk160", E4210_GATE_IP_LCD1, 0, 0, 0), + GATE(mie1, "mie1", "aclk160", E4210_GATE_IP_LCD1, 1, 0, 0), + GATE(dsim1, "dsim1", "aclk160", E4210_GATE_IP_LCD1, 3, 0, 0), + GATE(smmu_fimd1, "smmu_fimd1", "aclk160", E4210_GATE_IP_LCD1, 4, 0, 0), GATE(tsi, "tsi", "aclk133", GATE_IP_FSYS, 4, 0, 0), GATE(sromc, "sromc", "aclk133", GATE_IP_FSYS, 11, 0, 0), GATE(sclk_g3d, "sclk_g3d", "div_g3d", GATE_IP_G3D, 0, @@ -738,7 +738,7 @@ struct samsung_gate_clock exynos4210_gate_clks[] __initdata = { GATE(smmu_rotator, "smmu_rotator", "aclk200", E4210_GATE_IP_IMAGE, 4, 0, 0), GATE(sclk_mipi1, "sclk_mipi1", "div_mipi_pre1", - SRC_MASK_LCD1, 12, CLK_SET_RATE_PARENT, 0), + E4210_SRC_MASK_LCD1, 12, CLK_SET_RATE_PARENT, 0), GATE(sclk_sata, "sclk_sata", "div_sata", SRC_MASK_FSYS, 24, CLK_SET_RATE_PARENT, 0), GATE(sclk_mixer, "sclk_mixer", "mout_mixer", SRC_MASK_TV, 4, 0, 0), @@ -749,7 +749,7 @@ struct samsung_gate_clock exynos4210_gate_clks[] __initdata = { GATE_A(rtc, "rtc", "aclk100", GATE_IP_PERIR, 15, 0, 0, "rtc"), GATE_A(keyif, "keyif", "aclk100", GATE_IP_PERIR, 16, 0, 0, "keypad"), GATE_DA(sclk_fimd1, "exynos4-fb.1", "sclk_fimd1", "div_fimd1", - SRC_MASK_LCD1, 0, CLK_SET_RATE_PARENT, 0, "sclk_fimd"), + E4210_SRC_MASK_LCD1, 0, CLK_SET_RATE_PARENT, 0, "sclk_fimd"), }; /* list of gate clocks supported in exynos4x12 soc */ -- cgit v1.2.3 From 1f1f326763cf2352173eca1fc4116de6950ba773 Mon Sep 17 00:00:00 2001 From: Tomasz Figa Date: Thu, 4 Apr 2013 13:35:22 +0900 Subject: clk: exynos4: Add E4210 prefix to GATE_IP_PERIR register This definition is specific for Exynos4210 (which has another location than the same register on Exynos4x12 SoCs) and so needs appropriate prefix. Signed-off-by: Tomasz Figa Signed-off-by: Kyungmin Park Reviewed-by: Thomas Abraham Acked-by: Mike Turquette Signed-off-by: Kukjin Kim --- drivers/clk/samsung/clk-exynos4.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) (limited to 'drivers/clk') diff --git a/drivers/clk/samsung/clk-exynos4.c b/drivers/clk/samsung/clk-exynos4.c index 3d8a8a6fc5d0..b4daffaeb3f9 100644 --- a/drivers/clk/samsung/clk-exynos4.c +++ b/drivers/clk/samsung/clk-exynos4.c @@ -91,7 +91,7 @@ #define GATE_IP_FSYS 0xc940 #define GATE_IP_GPS 0xc94c #define GATE_IP_PERIL 0xc950 -#define GATE_IP_PERIR 0xc960 +#define E4210_GATE_IP_PERIR 0xc960 #define E4X12_MPLL_CON0 0x10108 #define E4X12_SRC_DMC 0x10200 #define APLL_CON0 0x14100 @@ -732,9 +732,9 @@ struct samsung_gate_clock exynos4210_gate_clks[] __initdata = { GATE(pcie, "pcie", "aclk133", GATE_IP_FSYS, 14, 0, 0), GATE(smmu_pcie, "smmu_pcie", "aclk133", GATE_IP_FSYS, 18, 0, 0), GATE(modemif, "modemif", "aclk100", GATE_IP_PERIL, 28, 0, 0), - GATE(chipid, "chipid", "aclk100", GATE_IP_PERIR, 0, 0, 0), - GATE(sysreg, "sysreg", "aclk100", GATE_IP_PERIR, 0, 0, 0), - GATE(hdmi_cec, "hdmi_cec", "aclk100", GATE_IP_PERIR, 11, 0, 0), + GATE(chipid, "chipid", "aclk100", E4210_GATE_IP_PERIR, 0, 0, 0), + GATE(sysreg, "sysreg", "aclk100", E4210_GATE_IP_PERIR, 0, 0, 0), + GATE(hdmi_cec, "hdmi_cec", "aclk100", E4210_GATE_IP_PERIR, 11, 0, 0), GATE(smmu_rotator, "smmu_rotator", "aclk200", E4210_GATE_IP_IMAGE, 4, 0, 0), GATE(sclk_mipi1, "sclk_mipi1", "div_mipi_pre1", @@ -744,10 +744,10 @@ struct samsung_gate_clock exynos4210_gate_clks[] __initdata = { GATE(sclk_mixer, "sclk_mixer", "mout_mixer", SRC_MASK_TV, 4, 0, 0), GATE(sclk_dac, "sclk_dac", "mout_dac", SRC_MASK_TV, 8, 0, 0), GATE_A(tsadc, "tsadc", "aclk100", GATE_IP_PERIL, 15, 0, 0, "adc"), - GATE_A(mct, "mct", "aclk100", GATE_IP_PERIR, 13, 0, 0, "mct"), - GATE_A(wdt, "watchdog", "aclk100", GATE_IP_PERIR, 14, 0, 0, "watchdog"), - GATE_A(rtc, "rtc", "aclk100", GATE_IP_PERIR, 15, 0, 0, "rtc"), - GATE_A(keyif, "keyif", "aclk100", GATE_IP_PERIR, 16, 0, 0, "keypad"), + GATE_A(mct, "mct", "aclk100", E4210_GATE_IP_PERIR, 13, 0, 0, "mct"), + GATE_A(wdt, "watchdog", "aclk100", E4210_GATE_IP_PERIR, 14, 0, 0, "watchdog"), + GATE_A(rtc, "rtc", "aclk100", E4210_GATE_IP_PERIR, 15, 0, 0, "rtc"), + GATE_A(keyif, "keyif", "aclk100", E4210_GATE_IP_PERIR, 16, 0, 0, "keypad"), GATE_DA(sclk_fimd1, "exynos4-fb.1", "sclk_fimd1", "div_fimd1", E4210_SRC_MASK_LCD1, 0, CLK_SET_RATE_PARENT, 0, "sclk_fimd"), }; -- cgit v1.2.3 From b950622bddc1c15f1e17041f1aec5816912ccca5 Mon Sep 17 00:00:00 2001 From: Tomasz Figa Date: Thu, 4 Apr 2013 13:35:27 +0900 Subject: clk: exynos4: Remove E4X12 prefix from SRC_DMC register This register is present on all Exynos4 SoCs and so the prefix is misleading. Signed-off-by: Tomasz Figa Signed-off-by: Kyungmin Park Reviewed-by: Thomas Abraham Acked-by: Mike Turquette Signed-off-by: Kukjin Kim --- drivers/clk/samsung/clk-exynos4.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/clk') diff --git a/drivers/clk/samsung/clk-exynos4.c b/drivers/clk/samsung/clk-exynos4.c index b4daffaeb3f9..a33b0acc5931 100644 --- a/drivers/clk/samsung/clk-exynos4.c +++ b/drivers/clk/samsung/clk-exynos4.c @@ -93,7 +93,7 @@ #define GATE_IP_PERIL 0xc950 #define E4210_GATE_IP_PERIR 0xc960 #define E4X12_MPLL_CON0 0x10108 -#define E4X12_SRC_DMC 0x10200 +#define SRC_DMC 0x10200 #define APLL_CON0 0x14100 #define E4210_MPLL_CON0 0x14108 #define SRC_CPU 0x14200 @@ -389,7 +389,7 @@ struct samsung_mux_clock exynos4x12_mux_clks[] __initdata = { MUX(none, "mout_jpeg1", sclk_evpll_p, E4X12_SRC_CAM1, 4, 1), MUX(none, "mout_jpeg", mout_jpeg_p, E4X12_SRC_CAM1, 8, 1), MUX_A(sclk_mpll, "sclk_mpll", mout_mpll_p, - E4X12_SRC_DMC, 12, 1, "sclk_mpll"), + SRC_DMC, 12, 1, "sclk_mpll"), MUX_A(sclk_vpll, "sclk_vpll", mout_vpll_p, SRC_TOP0, 8, 1, "sclk_vpll"), MUX(mout_core, "mout_core", mout_core_p4x12, SRC_CPU, 16, 1), -- cgit v1.2.3 From fb948f74ce05c5540f9ad7e92242e1c931f7c2f6 Mon Sep 17 00:00:00 2001 From: Tomasz Figa Date: Thu, 4 Apr 2013 13:35:32 +0900 Subject: clk: exynos4: Add missing registers to suspend save list This patch adds missing clock control registers to the list of registers that should be saved across system suspend. Signed-off-by: Tomasz Figa Signed-off-by: Kyungmin Park Reviewed-by: Thomas Abraham Acked-by: Mike Turquette Signed-off-by: Kukjin Kim --- drivers/clk/samsung/clk-exynos4.c | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) (limited to 'drivers/clk') diff --git a/drivers/clk/samsung/clk-exynos4.c b/drivers/clk/samsung/clk-exynos4.c index a33b0acc5931..23210006785b 100644 --- a/drivers/clk/samsung/clk-exynos4.c +++ b/drivers/clk/samsung/clk-exynos4.c @@ -22,7 +22,11 @@ /* Exynos4 clock controller register offsets */ #define SRC_LEFTBUS 0x4200 +#define DIV_LEFTBUS 0x4500 +#define GATE_IP_LEFTBUS 0x4800 #define E4X12_GATE_IP_IMAGE 0x4930 +#define SRC_RIGHTBUS 0x8200 +#define DIV_RIGHTBUS 0x8500 #define GATE_IP_RIGHTBUS 0x8800 #define E4X12_GATE_IP_PERIR 0x8960 #define EPLL_LOCK 0xc010 @@ -48,6 +52,7 @@ #define SRC_PERIL0 0xc250 #define SRC_PERIL1 0xc254 #define E4X12_SRC_CAM1 0xc258 +#define SRC_MASK_TOP 0xc310 #define SRC_MASK_CAM 0xc320 #define SRC_MASK_TV 0xc324 #define SRC_MASK_LCD0 0xc334 @@ -92,12 +97,20 @@ #define GATE_IP_GPS 0xc94c #define GATE_IP_PERIL 0xc950 #define E4210_GATE_IP_PERIR 0xc960 +#define GATE_BLOCK 0xc970 #define E4X12_MPLL_CON0 0x10108 #define SRC_DMC 0x10200 +#define SRC_MASK_DMC 0x10300 +#define DIV_DMC0 0x10500 +#define DIV_DMC1 0x10504 +#define GATE_IP_DMC 0x10900 #define APLL_CON0 0x14100 #define E4210_MPLL_CON0 0x14108 #define SRC_CPU 0x14200 #define DIV_CPU0 0x14500 +#define DIV_CPU1 0x14504 +#define GATE_SCLK_CPU 0x14800 +#define GATE_IP_CPU 0x14900 #define E4X12_DIV_ISP0 0x18300 #define E4X12_DIV_ISP1 0x18304 #define E4X12_GATE_ISP0 0x18800 @@ -172,7 +185,17 @@ enum exynos4_clks { */ static __initdata unsigned long exynos4_clk_regs[] = { SRC_LEFTBUS, + DIV_LEFTBUS, + GATE_IP_LEFTBUS, + SRC_RIGHTBUS, + DIV_RIGHTBUS, GATE_IP_RIGHTBUS, + EPLL_CON0, + EPLL_CON1, + EPLL_CON2, + VPLL_CON0, + VPLL_CON1, + VPLL_CON2, SRC_TOP0, SRC_TOP1, SRC_CAM, @@ -184,6 +207,7 @@ static __initdata unsigned long exynos4_clk_regs[] = { SRC_FSYS, SRC_PERIL0, SRC_PERIL1, + SRC_MASK_TOP, SRC_MASK_CAM, SRC_MASK_TV, SRC_MASK_LCD0, @@ -218,9 +242,18 @@ static __initdata unsigned long exynos4_clk_regs[] = { GATE_IP_FSYS, GATE_IP_GPS, GATE_IP_PERIL, + GATE_BLOCK, + SRC_MASK_DMC, + SRC_DMC, + DIV_DMC0, + DIV_DMC1, + GATE_IP_DMC, APLL_CON0, SRC_CPU, DIV_CPU0, + DIV_CPU1, + GATE_SCLK_CPU, + GATE_IP_CPU, }; /* list of all parent clock list */ -- cgit v1.2.3 From 6b5756e8bd19f8f1f23386d41997d0309e7a82a6 Mon Sep 17 00:00:00 2001 From: Tomasz Figa Date: Thu, 4 Apr 2013 13:35:35 +0900 Subject: clk: exynos4: Add support for SoC-specific register save list This patch extends suspend/resume support for SoC-specific registers to handle differences in register sets on particular SoCs. Signed-off-by: Tomasz Figa Signed-off-by: Kyungmin Park Reviewed-by: Thomas Abraham Acked-by: Mike Turquette Signed-off-by: Kukjin Kim --- drivers/clk/samsung/clk-exynos4.c | 30 ++++++++++++++++++++++++++++-- drivers/clk/samsung/clk-exynos5250.c | 3 ++- drivers/clk/samsung/clk-exynos5440.c | 2 +- drivers/clk/samsung/clk.c | 9 ++++++--- drivers/clk/samsung/clk.h | 3 ++- 5 files changed, 39 insertions(+), 8 deletions(-) (limited to 'drivers/clk') diff --git a/drivers/clk/samsung/clk-exynos4.c b/drivers/clk/samsung/clk-exynos4.c index 23210006785b..17674da1c5f8 100644 --- a/drivers/clk/samsung/clk-exynos4.c +++ b/drivers/clk/samsung/clk-exynos4.c @@ -183,6 +183,26 @@ enum exynos4_clks { * list of controller registers to be saved and restored during a * suspend/resume cycle. */ +static __initdata unsigned long exynos4210_clk_save[] = { + E4210_SRC_IMAGE, + E4210_SRC_LCD1, + E4210_SRC_MASK_LCD1, + E4210_DIV_LCD1, + E4210_GATE_IP_IMAGE, + E4210_GATE_IP_LCD1, + E4210_GATE_IP_PERIR, + E4210_MPLL_CON0, +}; + +static __initdata unsigned long exynos4x12_clk_save[] = { + E4X12_GATE_IP_IMAGE, + E4X12_GATE_IP_PERIR, + E4X12_SRC_CAM1, + E4X12_DIV_ISP, + E4X12_DIV_CAM1, + E4X12_MPLL_CON0, +}; + static __initdata unsigned long exynos4_clk_regs[] = { SRC_LEFTBUS, DIV_LEFTBUS, @@ -986,8 +1006,14 @@ void __init exynos4_clk_init(struct device_node *np) panic("%s: unable to determine soc\n", __func__); } - samsung_clk_init(np, reg_base, nr_clks, - exynos4_clk_regs, ARRAY_SIZE(exynos4_clk_regs)); + if (exynos4_soc == EXYNOS4210) + samsung_clk_init(np, reg_base, nr_clks, + exynos4_clk_regs, ARRAY_SIZE(exynos4_clk_regs), + exynos4210_clk_save, ARRAY_SIZE(exynos4210_clk_save)); + else + samsung_clk_init(np, reg_base, nr_clks, + exynos4_clk_regs, ARRAY_SIZE(exynos4_clk_regs), + exynos4x12_clk_save, ARRAY_SIZE(exynos4x12_clk_save)); if (np) samsung_clk_of_register_fixed_ext(exynos4_fixed_rate_ext_clks, diff --git a/drivers/clk/samsung/clk-exynos5250.c b/drivers/clk/samsung/clk-exynos5250.c index 115212525dd2..5cd9a0c47bf2 100644 --- a/drivers/clk/samsung/clk-exynos5250.c +++ b/drivers/clk/samsung/clk-exynos5250.c @@ -477,7 +477,8 @@ void __init exynos5250_clk_init(struct device_node *np) } samsung_clk_init(np, reg_base, nr_clks, - exynos5250_clk_regs, ARRAY_SIZE(exynos5250_clk_regs)); + exynos5250_clk_regs, ARRAY_SIZE(exynos5250_clk_regs), + NULL, 0); samsung_clk_of_register_fixed_ext(exynos5250_fixed_rate_ext_clks, ARRAY_SIZE(exynos5250_fixed_rate_ext_clks), ext_clk_match); diff --git a/drivers/clk/samsung/clk-exynos5440.c b/drivers/clk/samsung/clk-exynos5440.c index d588e939c235..a0a094c06f19 100644 --- a/drivers/clk/samsung/clk-exynos5440.c +++ b/drivers/clk/samsung/clk-exynos5440.c @@ -115,7 +115,7 @@ void __init exynos5440_clk_init(struct device_node *np) return; } - samsung_clk_init(np, reg_base, nr_clks, NULL, 0); + samsung_clk_init(np, reg_base, nr_clks, NULL, 0, NULL, 0); samsung_clk_of_register_fixed_ext(exynos5440_fixed_rate_ext_clks, ARRAY_SIZE(exynos5440_fixed_rate_ext_clks), ext_clk_match); diff --git a/drivers/clk/samsung/clk.c b/drivers/clk/samsung/clk.c index 82f27f644dae..3a50d4fe0be9 100644 --- a/drivers/clk/samsung/clk.c +++ b/drivers/clk/samsung/clk.c @@ -54,7 +54,8 @@ static struct syscore_ops samsung_clk_syscore_ops = { /* setup the essentials required to support clock lookup using ccf */ void __init samsung_clk_init(struct device_node *np, void __iomem *base, unsigned long nr_clks, unsigned long *rdump, - unsigned long nr_rdump) + unsigned long nr_rdump, unsigned long *soc_rdump, + unsigned long nr_soc_rdump) { reg_base = base; @@ -62,7 +63,7 @@ void __init samsung_clk_init(struct device_node *np, void __iomem *base, if (rdump && nr_rdump) { unsigned int idx; reg_dump = kzalloc(sizeof(struct samsung_clk_reg_dump) - * nr_rdump, GFP_KERNEL); + * (nr_rdump + nr_soc_rdump), GFP_KERNEL); if (!reg_dump) { pr_err("%s: memory alloc for register dump failed\n", __func__); @@ -71,7 +72,9 @@ void __init samsung_clk_init(struct device_node *np, void __iomem *base, for (idx = 0; idx < nr_rdump; idx++) reg_dump[idx].offset = rdump[idx]; - nr_reg_dump = nr_rdump; + for (idx = 0; idx < nr_soc_rdump; idx++) + reg_dump[nr_rdump + idx].offset = soc_rdump[idx]; + nr_reg_dump = nr_rdump + nr_soc_rdump; register_syscore_ops(&samsung_clk_syscore_ops); } #endif diff --git a/drivers/clk/samsung/clk.h b/drivers/clk/samsung/clk.h index 6bacd6fa0200..10b2111f0c0f 100644 --- a/drivers/clk/samsung/clk.h +++ b/drivers/clk/samsung/clk.h @@ -262,7 +262,8 @@ struct samsung_clk_reg_dump { extern void __init samsung_clk_init(struct device_node *np, void __iomem *base, unsigned long nr_clks, unsigned long *rdump, - unsigned long nr_rdump); + unsigned long nr_rdump, unsigned long *soc_rdump, + unsigned long nr_soc_rdump); extern void __init samsung_clk_of_register_fixed_ext( struct samsung_fixed_rate_clock *fixed_rate_clk, unsigned int nr_fixed_rate_clk, -- cgit v1.2.3 From 17d4caccefd138c3e4970132c1db177024caf3c6 Mon Sep 17 00:00:00 2001 From: Leela Krishna Amudala Date: Thu, 4 Apr 2013 15:44:40 +0900 Subject: clk: exynos5250: register display block gate clocks to common clock framework Add gate clocks for fimd, mie, dsim, dp, mixer and hdmi. Register it to common clock framework. Signed-off-by: Leela Krishna Amudala Signed-off-by: Kukjin Kim --- drivers/clk/samsung/clk-exynos5250.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) (limited to 'drivers/clk') diff --git a/drivers/clk/samsung/clk-exynos5250.c b/drivers/clk/samsung/clk-exynos5250.c index 5cd9a0c47bf2..e5e733af6c88 100644 --- a/drivers/clk/samsung/clk-exynos5250.c +++ b/drivers/clk/samsung/clk-exynos5250.c @@ -62,6 +62,7 @@ #define GATE_IP_PERIS 0x10960 #define SRC_CDREX 0x20200 #define PLL_DIV2_SEL 0x20a24 +#define GATE_IP_DISP1 0x10928 /* * Let each supported clock get a unique id. This id is used to lookup the clock @@ -98,7 +99,7 @@ enum exynos5250_clks { spi2, i2s1, i2s2, pcm1, pcm2, pwm, spdif, ac97, hsi2c0, hsi2c1, hsi2c2, hsi2c3, chipid, sysreg, pmu, cmu_top, cmu_core, cmu_mem, tzpc0, tzpc1, tzpc2, tzpc3, tzpc4, tzpc5, tzpc6, tzpc7, tzpc8, tzpc9, hdmi_cec, mct, - wdt, rtc, tmu, + wdt, rtc, tmu, fimd1, mie1, dsim0, dp, mixer, hdmi, nr_clks, }; @@ -150,6 +151,7 @@ static __initdata unsigned long exynos5250_clk_regs[] = { GATE_IP_PERIS, SRC_CDREX, PLL_DIV2_SEL, + GATE_IP_DISP1, }; /* list of all parent clock list */ @@ -455,6 +457,12 @@ struct samsung_gate_clock exynos5250_gate_clks[] __initdata = { SRC_MASK_PERIC1, 20, CLK_SET_RATE_PARENT, 0), GATE(sclk_spi2, "sclk_spi2", "div_spi_pre2", SRC_MASK_PERIC1, 24, CLK_SET_RATE_PARENT, 0), + GATE(fimd1, "fimd1", "aclk200", GATE_IP_DISP1, 0, 0, 0), + GATE(mie1, "mie1", "aclk200", GATE_IP_DISP1, 1, 0, 0), + GATE(dsim0, "dsim0", "aclk200", GATE_IP_DISP1, 3, 0, 0), + GATE(dp, "dp", "aclk200", GATE_IP_DISP1, 4, 0, 0), + GATE(mixer, "mixer", "aclk200", GATE_IP_DISP1, 5, 0, 0), + GATE(hdmi, "hdmi", "aclk200", GATE_IP_DISP1, 6, 0, 0), }; static __initdata struct of_device_id ext_clk_match[] = { -- cgit v1.2.3 From 6cec90826e9a3e505c9df91a62de59078f521dd3 Mon Sep 17 00:00:00 2001 From: Sachin Kamat Date: Mon, 8 Apr 2013 21:35:25 +0900 Subject: clk: samsung: Fix compilation error Fixes the below compilation error during non-dt build. drivers/clk/samsung/clk.c: In function 'samsung_clk_of_register_fixed_ext': drivers/clk/samsung/clk.c:252:2: error: implicit declaration of function 'for_each_matching_node_and_match' [-Werror=implicit-function-declaration] drivers/clk/samsung/clk.c:252:60: error: expected ';' before '{' token Signed-off-by: Sachin Kamat Signed-off-by: Kukjin Kim --- drivers/clk/samsung/clk.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers/clk') diff --git a/drivers/clk/samsung/clk.c b/drivers/clk/samsung/clk.c index 3a50d4fe0be9..cd3c40ab50f3 100644 --- a/drivers/clk/samsung/clk.c +++ b/drivers/clk/samsung/clk.c @@ -284,6 +284,7 @@ void __init samsung_clk_register_gate(struct samsung_gate_clock *list, * obtain the clock speed of all external fixed clock sources from device * tree and register it */ +#ifdef CONFIG_OF void __init samsung_clk_of_register_fixed_ext( struct samsung_fixed_rate_clock *fixed_rate_clk, unsigned int nr_fixed_rate_clk, @@ -300,6 +301,7 @@ void __init samsung_clk_of_register_fixed_ext( } samsung_clk_register_fixed_rate(fixed_rate_clk, nr_fixed_rate_clk); } +#endif /* utility function to get the rate of a specified clock */ unsigned long _get_rate(const char *clk_name) -- cgit v1.2.3 From cdbf618ab8a326cb3bdc65e8adb74bac9c347e64 Mon Sep 17 00:00:00 2001 From: Sylwester Nawrocki Date: Mon, 8 Apr 2013 15:24:47 +0900 Subject: clk: exynos4: export clocks required for fimc-is This patch adds clock indexes for ACLK_DIV0, ACLK_DIV1, ACLK_400_MCUISP, ACLK_MCUISP_DIV0, ACLK_MCUISP_DIV1, DIVACLK_400_MCUISP and DIVACLK_200 so these clocks are available to the consumers (Exynos4x12 FIMC-IS subsystem). While at it, indentation of the mux clocks table is corrected. Signed-off-by: Sylwester Nawrocki Signed-off-by: Kyungmin Park Acked-by: Mike Turquette Signed-off-by: Kukjin Kim --- drivers/clk/samsung/clk-exynos4.c | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) (limited to 'drivers/clk') diff --git a/drivers/clk/samsung/clk-exynos4.c b/drivers/clk/samsung/clk-exynos4.c index 17674da1c5f8..71046694d9dd 100644 --- a/drivers/clk/samsung/clk-exynos4.c +++ b/drivers/clk/samsung/clk-exynos4.c @@ -175,6 +175,11 @@ enum exynos4_clks { /* mux clocks */ mout_fimc0 = 384, mout_fimc1, mout_fimc2, mout_fimc3, mout_cam0, mout_cam1, mout_csis0, mout_csis1, mout_g3d0, mout_g3d1, mout_g3d, + aclk400_mcuisp, + + /* div clocks */ + div_isp0 = 450, div_isp1, div_mcuisp0, div_mcuisp1, div_aclk200, + div_aclk400_mcuisp, nr_clks, }; @@ -429,7 +434,7 @@ struct samsung_mux_clock exynos4x12_mux_clks[] __initdata = { MUX(none, "mout_user_aclk266_gps", mout_user_aclk266_gps_p4x12, SRC_TOP1, 16, 1), MUX(aclk200, "aclk200", mout_user_aclk200_p4x12, SRC_TOP1, 20, 1), - MUX(none, "aclk400_mcuisp", mout_user_aclk400_mcuisp_p4x12, + MUX(aclk400_mcuisp, "aclk400_mcuisp", mout_user_aclk400_mcuisp_p4x12, SRC_TOP1, 24, 1), MUX(none, "mout_aclk200", aclk_p4412, SRC_TOP0, 12, 1), MUX(none, "mout_aclk100", aclk_p4412, SRC_TOP0, 16, 1), @@ -563,20 +568,21 @@ struct samsung_div_clock exynos4x12_div_clks[] __initdata = { DIV(none, "div_mdnie_pwm_pre0", "div_mdnie_pwm0", DIV_LCD0, 12, 4), DIV(none, "div_mipihsi", "mout_mipihsi", DIV_FSYS0, 20, 4), DIV(none, "div_jpeg", "mout_jpeg", E4X12_DIV_CAM1, 0, 4), - DIV(none, "div_aclk200", "mout_aclk200", DIV_TOP, 0, 3), + DIV(div_aclk200, "div_aclk200", "mout_aclk200", DIV_TOP, 0, 3), DIV(none, "div_aclk266_gps", "mout_aclk266_gps", DIV_TOP, 20, 3), - DIV(none, "div_aclk400_mcuisp", "mout_aclk400_mcuisp", DIV_TOP, 24, 3), + DIV(div_aclk400_mcuisp, "div_aclk400_mcuisp", "mout_aclk400_mcuisp", + DIV_TOP, 24, 3), DIV(none, "div_pwm_isp", "mout_pwm_isp", E4X12_DIV_ISP, 0, 4), DIV(none, "div_spi0_isp", "mout_spi0_isp", E4X12_DIV_ISP, 4, 4), DIV(none, "div_spi0_isp_pre", "div_spi0_isp", E4X12_DIV_ISP, 8, 8), DIV(none, "div_spi1_isp", "mout_spi1_isp", E4X12_DIV_ISP, 16, 4), DIV(none, "div_spi1_isp_pre", "div_spi1_isp", E4X12_DIV_ISP, 20, 8), DIV(none, "div_uart_isp", "mout_uart_isp", E4X12_DIV_ISP, 28, 4), - DIV(none, "div_isp0", "aclk200", E4X12_DIV_ISP0, 0, 3), - DIV(none, "div_isp1", "aclk200", E4X12_DIV_ISP0, 4, 3), + DIV(div_isp0, "div_isp0", "aclk200", E4X12_DIV_ISP0, 0, 3), + DIV(div_isp1, "div_isp1", "aclk200", E4X12_DIV_ISP0, 4, 3), DIV(none, "div_mpwm", "div_isp1", E4X12_DIV_ISP1, 0, 3), - DIV(none, "div_mcuisp0", "aclk400_mcuisp", E4X12_DIV_ISP1, 4, 3), - DIV(none, "div_mcuisp1", "div_mcuisp0", E4X12_DIV_ISP1, 8, 3), + DIV(div_mcuisp0, "div_mcuisp0", "aclk400_mcuisp", E4X12_DIV_ISP1, 4, 3), + DIV(div_mcuisp1, "div_mcuisp1", "div_mcuisp0", E4X12_DIV_ISP1, 8, 3), }; /* list of gate clocks supported in all exynos4 soc's */ -- cgit v1.2.3 From 688f7d8c9fef621c53c7b385ff6baf62bcb6b077 Mon Sep 17 00:00:00 2001 From: Tushar Behera Date: Mon, 8 Apr 2013 15:28:12 +0900 Subject: clk: exynos5250: Fix divider values for sclk_mmc{0,1,2,3} In legacy setup, sclk_mmc{0,1,2,3} used PRE_RATIO bit-field (8-bit wide) instead of RATIO bit-field (4-bit wide) for dividing clock rate. With current common clock setup, we are using RATIO bit-field which is creating FIFO read errors while accessing eMMC. Changing over to use PRE_RATIO bit-field fixes this issue. dwmmc_exynos 12200000.dwmmc0: data FIFO error (status=00008020) mmcblk0: error -5 transferring data, sector 1, nr 7, cmd response 0x900, card status 0x0 end_request: I/O error, dev mmcblk0, sector 1 Signed-off-by: Tushar Behera CC: Thomas Abraham Acked-by: Mike Turquette Signed-off-by: Kukjin Kim --- drivers/clk/samsung/clk-exynos5250.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers/clk') diff --git a/drivers/clk/samsung/clk-exynos5250.c b/drivers/clk/samsung/clk-exynos5250.c index e5e733af6c88..7290faa518d2 100644 --- a/drivers/clk/samsung/clk-exynos5250.c +++ b/drivers/clk/samsung/clk-exynos5250.c @@ -276,10 +276,10 @@ struct samsung_div_clock exynos5250_div_clks[] __initdata = { DIV(none, "div_pcm0", "sclk_audio0", DIV_MAU, 4, 8), DIV(none, "div_sata", "mout_sata", DIV_FSYS0, 20, 4), DIV(none, "div_usb3", "mout_usb3", DIV_FSYS0, 24, 4), - DIV(none, "div_mmc0", "mout_mmc0", DIV_FSYS1, 0, 4), - DIV(none, "div_mmc1", "mout_mmc1", DIV_FSYS1, 16, 4), - DIV(none, "div_mmc2", "mout_mmc2", DIV_FSYS2, 0, 4), - DIV(none, "div_mmc3", "mout_mmc3", DIV_FSYS2, 16, 4), + DIV(none, "div_mmc0", "mout_mmc0", DIV_FSYS1, 8, 8), + DIV(none, "div_mmc1", "mout_mmc1", DIV_FSYS1, 24, 8), + DIV(none, "div_mmc2", "mout_mmc2", DIV_FSYS2, 8, 8), + DIV(none, "div_mmc3", "mout_mmc3", DIV_FSYS2, 24, 8), DIV(none, "div_uart0", "mout_uart0", DIV_PERIC0, 0, 4), DIV(none, "div_uart1", "mout_uart1", DIV_PERIC0, 4, 4), DIV(none, "div_uart2", "mout_uart2", DIV_PERIC0, 8, 4), -- cgit v1.2.3