* [PATCH 0/3] clk: ux500: Add support for ab850x clocks @ 2013-04-02 23:06 Ulf Hansson 2013-04-02 23:06 ` [PATCH 1/3] clk: ux500: Add support for sysctrl clocks Ulf Hansson ` (2 more replies) 0 siblings, 3 replies; 9+ messages in thread From: Ulf Hansson @ 2013-04-02 23:06 UTC (permalink / raw) To: linux-arm-kernel From: Ulf Hansson <ulf.hansson@linaro.org> This patchset implements a new clock hw type called sysctrl used for abx500 clocks. It will then setup the first version of clock tree specfic for ab850x. The new sysctrl clk hw type depends on the ab8500-sysctrl API. The last patch is a mfd patch which alignes the probe order between the abx500-clk driver and the ab8500-sysctrl driver. The intent is to merge the patchset together, preferably through Mike's clk tree. I would thus try to fetch an ack from Samuel regarding the mfd patch. Ulf Hansson (3): clk: ux500: Add support for sysctrl clocks clk: ux500: abx500: Define clock tree for ab850x mfd: ab8500: sysctrl: Initialize driver at arch_initcall drivers/clk/ux500/Makefile | 1 + drivers/clk/ux500/abx500-clk.c | 71 ++++++++++++- drivers/clk/ux500/clk-sysctrl.c | 224 +++++++++++++++++++++++++++++++++++++++ drivers/clk/ux500/clk.h | 29 +++++ drivers/mfd/ab8500-sysctrl.c | 2 +- 5 files changed, 323 insertions(+), 4 deletions(-) create mode 100644 drivers/clk/ux500/clk-sysctrl.c -- 1.7.10 ^ permalink raw reply [flat|nested] 9+ messages in thread
* [PATCH 1/3] clk: ux500: Add support for sysctrl clocks 2013-04-02 23:06 [PATCH 0/3] clk: ux500: Add support for ab850x clocks Ulf Hansson @ 2013-04-02 23:06 ` Ulf Hansson 2013-04-02 23:26 ` Mike Turquette 2013-04-02 23:06 ` [PATCH 2/3] clk: ux500: abx500: Define clock tree for ab850x Ulf Hansson 2013-04-02 23:06 ` [PATCH 3/3] mfd: ab8500: sysctrl: Initialize driver at arch_initcall Ulf Hansson 2 siblings, 1 reply; 9+ messages in thread From: Ulf Hansson @ 2013-04-02 23:06 UTC (permalink / raw) To: linux-arm-kernel From: Ulf Hansson <ulf.hansson@linaro.org> The abx500 sysctrl clocks are using the ab8500 sysctrl driver to modify the clock hardware. Sysctrl clocks are represented by a ab8500 sysctrl register and with a corresponding bitmask. The sysctrl clocks are slow path clocks, which means clk_prepare and clk_unprepare will be used to gate|ungate these clocks. Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org> --- drivers/clk/ux500/Makefile | 1 + drivers/clk/ux500/clk-sysctrl.c | 224 +++++++++++++++++++++++++++++++++++++++ drivers/clk/ux500/clk.h | 29 +++++ 3 files changed, 254 insertions(+) create mode 100644 drivers/clk/ux500/clk-sysctrl.c diff --git a/drivers/clk/ux500/Makefile b/drivers/clk/ux500/Makefile index bcc0c11..c6a806e 100644 --- a/drivers/clk/ux500/Makefile +++ b/drivers/clk/ux500/Makefile @@ -5,6 +5,7 @@ # Clock types obj-y += clk-prcc.o obj-y += clk-prcmu.o +obj-y += clk-sysctrl.o # Clock definitions obj-y += u8500_clk.o diff --git a/drivers/clk/ux500/clk-sysctrl.c b/drivers/clk/ux500/clk-sysctrl.c new file mode 100644 index 0000000..72c826d --- /dev/null +++ b/drivers/clk/ux500/clk-sysctrl.c @@ -0,0 +1,224 @@ +/* + * Sysctrl clock implementation for ux500 platform. + * + * Copyright (C) 2013 ST-Ericsson SA + * Author: Ulf Hansson <ulf.hansson@linaro.org> + * + * License terms: GNU General Public License (GPL) version 2 + */ + +#include <linux/clk-provider.h> +#include <linux/clk-private.h> +#include <linux/mfd/abx500/ab8500-sysctrl.h> +#include <linux/device.h> +#include <linux/slab.h> +#include <linux/delay.h> +#include <linux/io.h> +#include <linux/err.h> +#include "clk.h" + +#define SYSCTRL_MAX_NUM_PARENTS 4 + +#define to_clk_sysctrl(_hw) container_of(_hw, struct clk_sysctrl, hw) + +struct clk_sysctrl { + struct clk_hw hw; + struct device *dev; + u8 parent_index; + u16 reg_sel[SYSCTRL_MAX_NUM_PARENTS]; + u8 reg_mask[SYSCTRL_MAX_NUM_PARENTS]; + u8 reg_bits[SYSCTRL_MAX_NUM_PARENTS]; + unsigned long rate; + unsigned long enable_delay_us; +}; + +/* Sysctrl clock operations. */ + +static int clk_sysctrl_prepare(struct clk_hw *hw) +{ + int ret; + struct clk_sysctrl *clk = to_clk_sysctrl(hw); + + ret = ab8500_sysctrl_write(clk->reg_sel[0], clk->reg_mask[0], + clk->reg_bits[0]); + + if (!ret && clk->enable_delay_us) + usleep_range(clk->enable_delay_us, clk->enable_delay_us); + + return ret; +} + +static void clk_sysctrl_unprepare(struct clk_hw *hw) +{ + struct clk_sysctrl *clk = to_clk_sysctrl(hw); + if (ab8500_sysctrl_clear(clk->reg_sel[0], clk->reg_mask[0])) + dev_err(clk->dev, "clk_sysctrl: %s fail to clear %s.\n", + __func__, __clk_get_name(hw->clk)); +} + +static unsigned long clk_sysctrl_recalc_rate(struct clk_hw *hw, + unsigned long parent_rate) +{ + struct clk_sysctrl *clk = to_clk_sysctrl(hw); + return clk->rate; +} + +static int clk_sysctrl_set_parent(struct clk_hw *hw, u8 index) +{ + struct clk_sysctrl *clk = to_clk_sysctrl(hw); + u8 old_index = clk->parent_index; + int ret = 0; + + if (clk->reg_sel[old_index]) { + ret = ab8500_sysctrl_clear(clk->reg_sel[old_index], + clk->reg_mask[old_index]); + if (ret) + return ret; + } + + if (clk->reg_sel[index]) { + ret = ab8500_sysctrl_write(clk->reg_sel[index], + clk->reg_mask[index], + clk->reg_bits[index]); + if (ret) { + if (clk->reg_sel[old_index]) + ab8500_sysctrl_write(clk->reg_sel[old_index], + clk->reg_mask[old_index], + clk->reg_bits[old_index]); + return ret; + } + } + clk->parent_index = index; + + return ret; +} + +static u8 clk_sysctrl_get_parent(struct clk_hw *hw) +{ + struct clk_sysctrl *clk = to_clk_sysctrl(hw); + return clk->parent_index; +} + +static struct clk_ops clk_sysctrl_gate_ops = { + .prepare = clk_sysctrl_prepare, + .unprepare = clk_sysctrl_unprepare, +}; + +static struct clk_ops clk_sysctrl_gate_fixed_rate_ops = { + .prepare = clk_sysctrl_prepare, + .unprepare = clk_sysctrl_unprepare, + .recalc_rate = clk_sysctrl_recalc_rate, +}; + +static struct clk_ops clk_sysctrl_set_parent_ops = { + .set_parent = clk_sysctrl_set_parent, + .get_parent = clk_sysctrl_get_parent, +}; + +static struct clk *clk_reg_sysctrl(struct device *dev, + const char *name, + const char **parent_names, + u8 num_parents, + u16 *reg_sel, + u8 *reg_mask, + u8 *reg_bits, + unsigned long rate, + unsigned long enable_delay_us, + unsigned long flags, + struct clk_ops *clk_sysctrl_ops) +{ + struct clk_sysctrl *clk; + struct clk_init_data clk_sysctrl_init; + struct clk *clk_reg; + int i; + + if (!dev) + return ERR_PTR(-EINVAL); + + if (!name || (num_parents > SYSCTRL_MAX_NUM_PARENTS)) { + dev_err(dev, "clk_sysctrl: invalid arguments passed\n"); + return ERR_PTR(-EINVAL); + } + + clk = devm_kzalloc(dev, sizeof(struct clk_sysctrl), GFP_KERNEL); + if (!clk) { + dev_err(dev, "clk_sysctrl: could not allocate clk\n"); + return ERR_PTR(-ENOMEM); + } + + for (i = 0; i < num_parents; i++) { + clk->reg_sel[i] = reg_sel[i]; + clk->reg_bits[i] = reg_bits[i]; + clk->reg_mask[i] = reg_mask[i]; + } + + clk->parent_index = 0; + clk->rate = rate; + clk->enable_delay_us = enable_delay_us; + clk->dev = dev; + + clk_sysctrl_init.name = name; + clk_sysctrl_init.ops = clk_sysctrl_ops; + clk_sysctrl_init.flags = flags; + clk_sysctrl_init.parent_names = parent_names; + clk_sysctrl_init.num_parents = num_parents; + clk->hw.init = &clk_sysctrl_init; + + clk_reg = devm_clk_register(clk->dev, &clk->hw); + if (IS_ERR_OR_NULL(clk_reg)) { + dev_err(dev, "clk_sysctrl: clk_register failed\n"); + return ERR_PTR(-ENOMEM); + } + + return clk_reg; +} + +struct clk *clk_reg_sysctrl_gate(struct device *dev, + const char *name, + const char *parent_name, + u16 reg_sel, + u8 reg_mask, + u8 reg_bits, + unsigned long enable_delay_us, + unsigned long flags) +{ + const char **parent_names = (parent_name ? &parent_name : NULL); + u8 num_parents = (parent_name ? 1 : 0); + + return clk_reg_sysctrl(dev, name, parent_names, num_parents, + ®_sel, ®_mask, ®_bits, 0, enable_delay_us, + flags, &clk_sysctrl_gate_ops); +} + +struct clk *clk_reg_sysctrl_gate_fixed_rate(struct device *dev, + const char *name, + const char *parent_name, + u16 reg_sel, + u8 reg_mask, + u8 reg_bits, + unsigned long rate, + unsigned long enable_delay_us, + unsigned long flags) +{ + const char **parent_names = (parent_name ? &parent_name : NULL); + u8 num_parents = (parent_name ? 1 : 0); + + return clk_reg_sysctrl(dev, name, parent_names, num_parents, + ®_sel, ®_mask, ®_bits, + rate, enable_delay_us, flags, + &clk_sysctrl_gate_fixed_rate_ops); +} + +struct clk *clk_reg_sysctrl_set_parent(struct device *dev, + const char *name, + const char **parent_names, + u8 num_parents, + u16 *reg_sel, + u8 *reg_mask, + u8 *reg_bits, + unsigned long flags) +{ + return clk_reg_sysctrl(dev, name, parent_names, num_parents, + reg_sel, reg_mask, reg_bits, 0, 0, flags, + &clk_sysctrl_set_parent_ops); +} diff --git a/drivers/clk/ux500/clk.h b/drivers/clk/ux500/clk.h index c3e4491..3d2dfdc 100644 --- a/drivers/clk/ux500/clk.h +++ b/drivers/clk/ux500/clk.h @@ -11,6 +11,7 @@ #define __UX500_CLK_H #include <linux/clk.h> +#include <linux/device.h> struct clk *clk_reg_prcc_pclk(const char *name, const char *parent_name, @@ -57,4 +58,32 @@ struct clk *clk_reg_prcmu_opp_volt_scalable(const char *name, unsigned long rate, unsigned long flags); +struct clk *clk_reg_sysctrl_gate(struct device *dev, + const char *name, + const char *parent_name, + u16 reg_sel, + u8 reg_mask, + u8 reg_bits, + unsigned long enable_delay_us, + unsigned long flags); + +struct clk *clk_reg_sysctrl_gate_fixed_rate(struct device *dev, + const char *name, + const char *parent_name, + u16 reg_sel, + u8 reg_mask, + u8 reg_bits, + unsigned long rate, + unsigned long enable_delay_us, + unsigned long flags); + +struct clk *clk_reg_sysctrl_set_parent(struct device *dev, + const char *name, + const char **parent_names, + u8 num_parents, + u16 *reg_sel, + u8 *reg_mask, + u8 *reg_bits, + unsigned long flags); + #endif /* __UX500_CLK_H */ -- 1.7.10 ^ permalink raw reply related [flat|nested] 9+ messages in thread
* [PATCH 1/3] clk: ux500: Add support for sysctrl clocks 2013-04-02 23:06 ` [PATCH 1/3] clk: ux500: Add support for sysctrl clocks Ulf Hansson @ 2013-04-02 23:26 ` Mike Turquette 0 siblings, 0 replies; 9+ messages in thread From: Mike Turquette @ 2013-04-02 23:26 UTC (permalink / raw) To: linux-arm-kernel Quoting Ulf Hansson (2013-04-02 16:06:25) > From: Ulf Hansson <ulf.hansson@linaro.org> > > The abx500 sysctrl clocks are using the ab8500 sysctrl driver to > modify the clock hardware. Sysctrl clocks are represented by a > ab8500 sysctrl register and with a corresponding bitmask. > > The sysctrl clocks are slow path clocks, which means clk_prepare > and clk_unprepare will be used to gate|ungate these clocks. > > Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org> > --- > drivers/clk/ux500/Makefile | 1 + > drivers/clk/ux500/clk-sysctrl.c | 224 +++++++++++++++++++++++++++++++++++++++ > drivers/clk/ux500/clk.h | 29 +++++ > 3 files changed, 254 insertions(+) > create mode 100644 drivers/clk/ux500/clk-sysctrl.c > > diff --git a/drivers/clk/ux500/Makefile b/drivers/clk/ux500/Makefile > index bcc0c11..c6a806e 100644 > --- a/drivers/clk/ux500/Makefile > +++ b/drivers/clk/ux500/Makefile > @@ -5,6 +5,7 @@ > # Clock types > obj-y += clk-prcc.o > obj-y += clk-prcmu.o > +obj-y += clk-sysctrl.o > > # Clock definitions > obj-y += u8500_clk.o > diff --git a/drivers/clk/ux500/clk-sysctrl.c b/drivers/clk/ux500/clk-sysctrl.c > new file mode 100644 > index 0000000..72c826d > --- /dev/null > +++ b/drivers/clk/ux500/clk-sysctrl.c > @@ -0,0 +1,224 @@ > +/* > + * Sysctrl clock implementation for ux500 platform. > + * > + * Copyright (C) 2013 ST-Ericsson SA > + * Author: Ulf Hansson <ulf.hansson@linaro.org> > + * > + * License terms: GNU General Public License (GPL) version 2 > + */ > + > +#include <linux/clk-provider.h> > +#include <linux/clk-private.h> I think the above header accidentally slipped in. Regards, Mike ^ permalink raw reply [flat|nested] 9+ messages in thread
* [PATCH 2/3] clk: ux500: abx500: Define clock tree for ab850x 2013-04-02 23:06 [PATCH 0/3] clk: ux500: Add support for ab850x clocks Ulf Hansson 2013-04-02 23:06 ` [PATCH 1/3] clk: ux500: Add support for sysctrl clocks Ulf Hansson @ 2013-04-02 23:06 ` Ulf Hansson 2013-04-04 14:08 ` Fabio Baltieri ` (2 more replies) 2013-04-02 23:06 ` [PATCH 3/3] mfd: ab8500: sysctrl: Initialize driver at arch_initcall Ulf Hansson 2 siblings, 3 replies; 9+ messages in thread From: Ulf Hansson @ 2013-04-02 23:06 UTC (permalink / raw) To: linux-arm-kernel From: Ulf Hansson <ulf.hansson@linaro.org> The patch setups the first version of the clock tree for ab850x, which is used by u8500 platforms. Mainly sysctrl clocks are used. Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org> --- drivers/clk/ux500/abx500-clk.c | 71 ++++++++++++++++++++++++++++++++++++++-- 1 file changed, 68 insertions(+), 3 deletions(-) diff --git a/drivers/clk/ux500/abx500-clk.c b/drivers/clk/ux500/abx500-clk.c index 9f7400d..a0fca00 100644 --- a/drivers/clk/ux500/abx500-clk.c +++ b/drivers/clk/ux500/abx500-clk.c @@ -12,13 +12,78 @@ #include <linux/device.h> #include <linux/platform_device.h> #include <linux/mfd/abx500/ab8500.h> - -/* TODO: Add clock implementations here */ - +#include <linux/mfd/abx500/ab8500-sysctrl.h> +#include <linux/clk.h> +#include <linux/clkdev.h> +#include <linux/clk-provider.h> +#include <linux/mfd/dbx500-prcmu.h> +#include "clk.h" /* Clock definitions for ab8500 */ static int ab8500_reg_clks(struct device *dev) { + int ret; + struct clk *clk; + + const char *intclk_parents[] = {"ab8500_sysclk", "ulpclk"}; + u16 intclk_reg_sel[] = {0 , AB8500_SYSULPCLKCTRL1}; + u8 intclk_reg_mask[] = {0 , AB8500_SYSULPCLKCTRL1_SYSULPCLKINTSEL_MASK}; + u8 intclk_reg_bits[] = { + 0 , + (1 << AB8500_SYSULPCLKCTRL1_SYSULPCLKINTSEL_SHIFT) + }; + + dev_info(dev, "register clocks for ab850x\n"); + + /* Enable SWAT */ + ret = ab8500_sysctrl_set(AB8500_SWATCTRL, AB8500_SWATCTRL_SWATENABLE); + if (ret) + return ret; + + /* ab8500_sysclk */ + clk = clk_reg_prcmu_gate("ab8500_sysclk", NULL, PRCMU_SYSCLK, + CLK_IS_ROOT); + clk_register_clkdev(clk, "sysclk", "ab8500-usb.0"); + clk_register_clkdev(clk, "sysclk", "ab-iddet.0"); + clk_register_clkdev(clk, "sysclk", "ab85xx-codec.0"); + clk_register_clkdev(clk, "sysclk", "shrm_bus"); + + /* ab8500_sysclk2 */ + clk = clk_reg_sysctrl_gate(dev , "ab8500_sysclk2", "ab8500_sysclk", + AB8500_SYSULPCLKCTRL1, AB8500_SYSULPCLKCTRL1_SYSCLKBUF2REQ, + AB8500_SYSULPCLKCTRL1_SYSCLKBUF2REQ, 0, 0); + clk_register_clkdev(clk, "sysclk", "0-0070"); + + /* ab8500_sysclk3 */ + clk = clk_reg_sysctrl_gate(dev , "ab8500_sysclk3", "ab8500_sysclk", + AB8500_SYSULPCLKCTRL1, AB8500_SYSULPCLKCTRL1_SYSCLKBUF3REQ, + AB8500_SYSULPCLKCTRL1_SYSCLKBUF3REQ, 0, 0); + clk_register_clkdev(clk, "sysclk", "cg1960_core.0"); + + /* ab8500_sysclk4 */ + clk = clk_reg_sysctrl_gate(dev , "ab8500_sysclk4", "ab8500_sysclk", + AB8500_SYSULPCLKCTRL1, AB8500_SYSULPCLKCTRL1_SYSCLKBUF4REQ, + AB8500_SYSULPCLKCTRL1_SYSCLKBUF4REQ, 0, 0); + + /* ab_ulpclk */ + clk = clk_reg_sysctrl_gate_fixed_rate(dev, "ulpclk", NULL, + AB8500_SYSULPCLKCTRL1, AB8500_SYSULPCLKCTRL1_ULPCLKREQ, + AB8500_SYSULPCLKCTRL1_ULPCLKREQ, + 38400000, 9000, CLK_IS_ROOT); + clk_register_clkdev(clk, "ulpclk", "ab85xx-codec.0"); + + /* ab8500_intclk */ + clk = clk_reg_sysctrl_set_parent(dev , "intclk", intclk_parents, 2, + intclk_reg_sel, intclk_reg_mask, intclk_reg_bits, 0); + clk_register_clkdev(clk, "intclk", "ab85xx-codec.0"); + clk_register_clkdev(clk, NULL, "ab8500-pwm.1"); + + /* ab8500_audioclk */ + clk = clk_reg_sysctrl_gate(dev , "audioclk", "intclk", + AB8500_SYSULPCLKCTRL1, AB8500_SYSULPCLKCTRL1_AUDIOCLKENA, + AB8500_SYSULPCLKCTRL1_AUDIOCLKENA, 0, 0); + clk_register_clkdev(clk, "audioclk", "ab85xx-codec.0"); + return 0; } -- 1.7.10 ^ permalink raw reply related [flat|nested] 9+ messages in thread
* [PATCH 2/3] clk: ux500: abx500: Define clock tree for ab850x 2013-04-02 23:06 ` [PATCH 2/3] clk: ux500: abx500: Define clock tree for ab850x Ulf Hansson @ 2013-04-04 14:08 ` Fabio Baltieri 2013-04-09 19:40 ` Mike Turquette 2013-04-10 18:29 ` Mike Turquette 2 siblings, 0 replies; 9+ messages in thread From: Fabio Baltieri @ 2013-04-04 14:08 UTC (permalink / raw) To: linux-arm-kernel Hi Ulf, On Wed, Apr 03, 2013 at 01:06:26AM +0200, Ulf Hansson wrote: > From: Ulf Hansson <ulf.hansson@linaro.org> > > The patch setups the first version of the clock tree for ab850x, which > is used by u8500 platforms. Mainly sysctrl clocks are used. I was just going to ask you if you had plans to develop this stuff, as I was missing a clock for ab8500-usb. This worked nice for me so, FWIW: Tested-by: Fabio Baltieri <fabio.baltieri@linaro.org> Thanks, Fabio > > Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org> > --- > drivers/clk/ux500/abx500-clk.c | 71 ++++++++++++++++++++++++++++++++++++++-- > 1 file changed, 68 insertions(+), 3 deletions(-) > > diff --git a/drivers/clk/ux500/abx500-clk.c b/drivers/clk/ux500/abx500-clk.c > index 9f7400d..a0fca00 100644 > --- a/drivers/clk/ux500/abx500-clk.c > +++ b/drivers/clk/ux500/abx500-clk.c > @@ -12,13 +12,78 @@ > #include <linux/device.h> > #include <linux/platform_device.h> > #include <linux/mfd/abx500/ab8500.h> > - > -/* TODO: Add clock implementations here */ > - > +#include <linux/mfd/abx500/ab8500-sysctrl.h> > +#include <linux/clk.h> > +#include <linux/clkdev.h> > +#include <linux/clk-provider.h> > +#include <linux/mfd/dbx500-prcmu.h> > +#include "clk.h" > > /* Clock definitions for ab8500 */ > static int ab8500_reg_clks(struct device *dev) > { > + int ret; > + struct clk *clk; > + > + const char *intclk_parents[] = {"ab8500_sysclk", "ulpclk"}; > + u16 intclk_reg_sel[] = {0 , AB8500_SYSULPCLKCTRL1}; > + u8 intclk_reg_mask[] = {0 , AB8500_SYSULPCLKCTRL1_SYSULPCLKINTSEL_MASK}; > + u8 intclk_reg_bits[] = { > + 0 , > + (1 << AB8500_SYSULPCLKCTRL1_SYSULPCLKINTSEL_SHIFT) > + }; > + > + dev_info(dev, "register clocks for ab850x\n"); > + > + /* Enable SWAT */ > + ret = ab8500_sysctrl_set(AB8500_SWATCTRL, AB8500_SWATCTRL_SWATENABLE); > + if (ret) > + return ret; > + > + /* ab8500_sysclk */ > + clk = clk_reg_prcmu_gate("ab8500_sysclk", NULL, PRCMU_SYSCLK, > + CLK_IS_ROOT); > + clk_register_clkdev(clk, "sysclk", "ab8500-usb.0"); > + clk_register_clkdev(clk, "sysclk", "ab-iddet.0"); > + clk_register_clkdev(clk, "sysclk", "ab85xx-codec.0"); > + clk_register_clkdev(clk, "sysclk", "shrm_bus"); > + > + /* ab8500_sysclk2 */ > + clk = clk_reg_sysctrl_gate(dev , "ab8500_sysclk2", "ab8500_sysclk", > + AB8500_SYSULPCLKCTRL1, AB8500_SYSULPCLKCTRL1_SYSCLKBUF2REQ, > + AB8500_SYSULPCLKCTRL1_SYSCLKBUF2REQ, 0, 0); > + clk_register_clkdev(clk, "sysclk", "0-0070"); > + > + /* ab8500_sysclk3 */ > + clk = clk_reg_sysctrl_gate(dev , "ab8500_sysclk3", "ab8500_sysclk", > + AB8500_SYSULPCLKCTRL1, AB8500_SYSULPCLKCTRL1_SYSCLKBUF3REQ, > + AB8500_SYSULPCLKCTRL1_SYSCLKBUF3REQ, 0, 0); > + clk_register_clkdev(clk, "sysclk", "cg1960_core.0"); > + > + /* ab8500_sysclk4 */ > + clk = clk_reg_sysctrl_gate(dev , "ab8500_sysclk4", "ab8500_sysclk", > + AB8500_SYSULPCLKCTRL1, AB8500_SYSULPCLKCTRL1_SYSCLKBUF4REQ, > + AB8500_SYSULPCLKCTRL1_SYSCLKBUF4REQ, 0, 0); > + > + /* ab_ulpclk */ > + clk = clk_reg_sysctrl_gate_fixed_rate(dev, "ulpclk", NULL, > + AB8500_SYSULPCLKCTRL1, AB8500_SYSULPCLKCTRL1_ULPCLKREQ, > + AB8500_SYSULPCLKCTRL1_ULPCLKREQ, > + 38400000, 9000, CLK_IS_ROOT); > + clk_register_clkdev(clk, "ulpclk", "ab85xx-codec.0"); > + > + /* ab8500_intclk */ > + clk = clk_reg_sysctrl_set_parent(dev , "intclk", intclk_parents, 2, > + intclk_reg_sel, intclk_reg_mask, intclk_reg_bits, 0); > + clk_register_clkdev(clk, "intclk", "ab85xx-codec.0"); > + clk_register_clkdev(clk, NULL, "ab8500-pwm.1"); > + > + /* ab8500_audioclk */ > + clk = clk_reg_sysctrl_gate(dev , "audioclk", "intclk", > + AB8500_SYSULPCLKCTRL1, AB8500_SYSULPCLKCTRL1_AUDIOCLKENA, > + AB8500_SYSULPCLKCTRL1_AUDIOCLKENA, 0, 0); > + clk_register_clkdev(clk, "audioclk", "ab85xx-codec.0"); > + > return 0; > } -- Fabio Baltieri ^ permalink raw reply [flat|nested] 9+ messages in thread
* [PATCH 2/3] clk: ux500: abx500: Define clock tree for ab850x 2013-04-02 23:06 ` [PATCH 2/3] clk: ux500: abx500: Define clock tree for ab850x Ulf Hansson 2013-04-04 14:08 ` Fabio Baltieri @ 2013-04-09 19:40 ` Mike Turquette 2013-04-10 18:29 ` Mike Turquette 2 siblings, 0 replies; 9+ messages in thread From: Mike Turquette @ 2013-04-09 19:40 UTC (permalink / raw) To: linux-arm-kernel Quoting Ulf Hansson (2013-04-02 16:06:26) > From: Ulf Hansson <ulf.hansson@linaro.org> > > The patch setups the first version of the clock tree for ab850x, which > is used by u8500 platforms. Mainly sysctrl clocks are used. > > Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org> Ulf, Does the V1 version of this patch #2 go along with the recently posted v3 version of patch #1 titled, "[PATCH V3 1/3] clk: ux500: Add support for sysctrl clocks"? Regards, Mike > --- > drivers/clk/ux500/abx500-clk.c | 71 ++++++++++++++++++++++++++++++++++++++-- > 1 file changed, 68 insertions(+), 3 deletions(-) > > diff --git a/drivers/clk/ux500/abx500-clk.c b/drivers/clk/ux500/abx500-clk.c > index 9f7400d..a0fca00 100644 > --- a/drivers/clk/ux500/abx500-clk.c > +++ b/drivers/clk/ux500/abx500-clk.c > @@ -12,13 +12,78 @@ > #include <linux/device.h> > #include <linux/platform_device.h> > #include <linux/mfd/abx500/ab8500.h> > - > -/* TODO: Add clock implementations here */ > - > +#include <linux/mfd/abx500/ab8500-sysctrl.h> > +#include <linux/clk.h> > +#include <linux/clkdev.h> > +#include <linux/clk-provider.h> > +#include <linux/mfd/dbx500-prcmu.h> > +#include "clk.h" > > /* Clock definitions for ab8500 */ > static int ab8500_reg_clks(struct device *dev) > { > + int ret; > + struct clk *clk; > + > + const char *intclk_parents[] = {"ab8500_sysclk", "ulpclk"}; > + u16 intclk_reg_sel[] = {0 , AB8500_SYSULPCLKCTRL1}; > + u8 intclk_reg_mask[] = {0 , AB8500_SYSULPCLKCTRL1_SYSULPCLKINTSEL_MASK}; > + u8 intclk_reg_bits[] = { > + 0 , > + (1 << AB8500_SYSULPCLKCTRL1_SYSULPCLKINTSEL_SHIFT) > + }; > + > + dev_info(dev, "register clocks for ab850x\n"); > + > + /* Enable SWAT */ > + ret = ab8500_sysctrl_set(AB8500_SWATCTRL, AB8500_SWATCTRL_SWATENABLE); > + if (ret) > + return ret; > + > + /* ab8500_sysclk */ > + clk = clk_reg_prcmu_gate("ab8500_sysclk", NULL, PRCMU_SYSCLK, > + CLK_IS_ROOT); > + clk_register_clkdev(clk, "sysclk", "ab8500-usb.0"); > + clk_register_clkdev(clk, "sysclk", "ab-iddet.0"); > + clk_register_clkdev(clk, "sysclk", "ab85xx-codec.0"); > + clk_register_clkdev(clk, "sysclk", "shrm_bus"); > + > + /* ab8500_sysclk2 */ > + clk = clk_reg_sysctrl_gate(dev , "ab8500_sysclk2", "ab8500_sysclk", > + AB8500_SYSULPCLKCTRL1, AB8500_SYSULPCLKCTRL1_SYSCLKBUF2REQ, > + AB8500_SYSULPCLKCTRL1_SYSCLKBUF2REQ, 0, 0); > + clk_register_clkdev(clk, "sysclk", "0-0070"); > + > + /* ab8500_sysclk3 */ > + clk = clk_reg_sysctrl_gate(dev , "ab8500_sysclk3", "ab8500_sysclk", > + AB8500_SYSULPCLKCTRL1, AB8500_SYSULPCLKCTRL1_SYSCLKBUF3REQ, > + AB8500_SYSULPCLKCTRL1_SYSCLKBUF3REQ, 0, 0); > + clk_register_clkdev(clk, "sysclk", "cg1960_core.0"); > + > + /* ab8500_sysclk4 */ > + clk = clk_reg_sysctrl_gate(dev , "ab8500_sysclk4", "ab8500_sysclk", > + AB8500_SYSULPCLKCTRL1, AB8500_SYSULPCLKCTRL1_SYSCLKBUF4REQ, > + AB8500_SYSULPCLKCTRL1_SYSCLKBUF4REQ, 0, 0); > + > + /* ab_ulpclk */ > + clk = clk_reg_sysctrl_gate_fixed_rate(dev, "ulpclk", NULL, > + AB8500_SYSULPCLKCTRL1, AB8500_SYSULPCLKCTRL1_ULPCLKREQ, > + AB8500_SYSULPCLKCTRL1_ULPCLKREQ, > + 38400000, 9000, CLK_IS_ROOT); > + clk_register_clkdev(clk, "ulpclk", "ab85xx-codec.0"); > + > + /* ab8500_intclk */ > + clk = clk_reg_sysctrl_set_parent(dev , "intclk", intclk_parents, 2, > + intclk_reg_sel, intclk_reg_mask, intclk_reg_bits, 0); > + clk_register_clkdev(clk, "intclk", "ab85xx-codec.0"); > + clk_register_clkdev(clk, NULL, "ab8500-pwm.1"); > + > + /* ab8500_audioclk */ > + clk = clk_reg_sysctrl_gate(dev , "audioclk", "intclk", > + AB8500_SYSULPCLKCTRL1, AB8500_SYSULPCLKCTRL1_AUDIOCLKENA, > + AB8500_SYSULPCLKCTRL1_AUDIOCLKENA, 0, 0); > + clk_register_clkdev(clk, "audioclk", "ab85xx-codec.0"); > + > return 0; > } > > -- > 1.7.10 ^ permalink raw reply [flat|nested] 9+ messages in thread
* [PATCH 2/3] clk: ux500: abx500: Define clock tree for ab850x 2013-04-02 23:06 ` [PATCH 2/3] clk: ux500: abx500: Define clock tree for ab850x Ulf Hansson 2013-04-04 14:08 ` Fabio Baltieri 2013-04-09 19:40 ` Mike Turquette @ 2013-04-10 18:29 ` Mike Turquette 2 siblings, 0 replies; 9+ messages in thread From: Mike Turquette @ 2013-04-10 18:29 UTC (permalink / raw) To: linux-arm-kernel Quoting Ulf Hansson (2013-04-02 16:06:26) > From: Ulf Hansson <ulf.hansson@linaro.org> > > The patch setups the first version of the clock tree for ab850x, which > is used by u8500 platforms. Mainly sysctrl clocks are used. > > Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org> Taken into clk-next. Regards, Mike > --- > drivers/clk/ux500/abx500-clk.c | 71 ++++++++++++++++++++++++++++++++++++++-- > 1 file changed, 68 insertions(+), 3 deletions(-) > > diff --git a/drivers/clk/ux500/abx500-clk.c b/drivers/clk/ux500/abx500-clk.c > index 9f7400d..a0fca00 100644 > --- a/drivers/clk/ux500/abx500-clk.c > +++ b/drivers/clk/ux500/abx500-clk.c > @@ -12,13 +12,78 @@ > #include <linux/device.h> > #include <linux/platform_device.h> > #include <linux/mfd/abx500/ab8500.h> > - > -/* TODO: Add clock implementations here */ > - > +#include <linux/mfd/abx500/ab8500-sysctrl.h> > +#include <linux/clk.h> > +#include <linux/clkdev.h> > +#include <linux/clk-provider.h> > +#include <linux/mfd/dbx500-prcmu.h> > +#include "clk.h" > > /* Clock definitions for ab8500 */ > static int ab8500_reg_clks(struct device *dev) > { > + int ret; > + struct clk *clk; > + > + const char *intclk_parents[] = {"ab8500_sysclk", "ulpclk"}; > + u16 intclk_reg_sel[] = {0 , AB8500_SYSULPCLKCTRL1}; > + u8 intclk_reg_mask[] = {0 , AB8500_SYSULPCLKCTRL1_SYSULPCLKINTSEL_MASK}; > + u8 intclk_reg_bits[] = { > + 0 , > + (1 << AB8500_SYSULPCLKCTRL1_SYSULPCLKINTSEL_SHIFT) > + }; > + > + dev_info(dev, "register clocks for ab850x\n"); > + > + /* Enable SWAT */ > + ret = ab8500_sysctrl_set(AB8500_SWATCTRL, AB8500_SWATCTRL_SWATENABLE); > + if (ret) > + return ret; > + > + /* ab8500_sysclk */ > + clk = clk_reg_prcmu_gate("ab8500_sysclk", NULL, PRCMU_SYSCLK, > + CLK_IS_ROOT); > + clk_register_clkdev(clk, "sysclk", "ab8500-usb.0"); > + clk_register_clkdev(clk, "sysclk", "ab-iddet.0"); > + clk_register_clkdev(clk, "sysclk", "ab85xx-codec.0"); > + clk_register_clkdev(clk, "sysclk", "shrm_bus"); > + > + /* ab8500_sysclk2 */ > + clk = clk_reg_sysctrl_gate(dev , "ab8500_sysclk2", "ab8500_sysclk", > + AB8500_SYSULPCLKCTRL1, AB8500_SYSULPCLKCTRL1_SYSCLKBUF2REQ, > + AB8500_SYSULPCLKCTRL1_SYSCLKBUF2REQ, 0, 0); > + clk_register_clkdev(clk, "sysclk", "0-0070"); > + > + /* ab8500_sysclk3 */ > + clk = clk_reg_sysctrl_gate(dev , "ab8500_sysclk3", "ab8500_sysclk", > + AB8500_SYSULPCLKCTRL1, AB8500_SYSULPCLKCTRL1_SYSCLKBUF3REQ, > + AB8500_SYSULPCLKCTRL1_SYSCLKBUF3REQ, 0, 0); > + clk_register_clkdev(clk, "sysclk", "cg1960_core.0"); > + > + /* ab8500_sysclk4 */ > + clk = clk_reg_sysctrl_gate(dev , "ab8500_sysclk4", "ab8500_sysclk", > + AB8500_SYSULPCLKCTRL1, AB8500_SYSULPCLKCTRL1_SYSCLKBUF4REQ, > + AB8500_SYSULPCLKCTRL1_SYSCLKBUF4REQ, 0, 0); > + > + /* ab_ulpclk */ > + clk = clk_reg_sysctrl_gate_fixed_rate(dev, "ulpclk", NULL, > + AB8500_SYSULPCLKCTRL1, AB8500_SYSULPCLKCTRL1_ULPCLKREQ, > + AB8500_SYSULPCLKCTRL1_ULPCLKREQ, > + 38400000, 9000, CLK_IS_ROOT); > + clk_register_clkdev(clk, "ulpclk", "ab85xx-codec.0"); > + > + /* ab8500_intclk */ > + clk = clk_reg_sysctrl_set_parent(dev , "intclk", intclk_parents, 2, > + intclk_reg_sel, intclk_reg_mask, intclk_reg_bits, 0); > + clk_register_clkdev(clk, "intclk", "ab85xx-codec.0"); > + clk_register_clkdev(clk, NULL, "ab8500-pwm.1"); > + > + /* ab8500_audioclk */ > + clk = clk_reg_sysctrl_gate(dev , "audioclk", "intclk", > + AB8500_SYSULPCLKCTRL1, AB8500_SYSULPCLKCTRL1_AUDIOCLKENA, > + AB8500_SYSULPCLKCTRL1_AUDIOCLKENA, 0, 0); > + clk_register_clkdev(clk, "audioclk", "ab85xx-codec.0"); > + > return 0; > } > > -- > 1.7.10 ^ permalink raw reply [flat|nested] 9+ messages in thread
* [PATCH 3/3] mfd: ab8500: sysctrl: Initialize driver at arch_initcall 2013-04-02 23:06 [PATCH 0/3] clk: ux500: Add support for ab850x clocks Ulf Hansson 2013-04-02 23:06 ` [PATCH 1/3] clk: ux500: Add support for sysctrl clocks Ulf Hansson 2013-04-02 23:06 ` [PATCH 2/3] clk: ux500: abx500: Define clock tree for ab850x Ulf Hansson @ 2013-04-02 23:06 ` Ulf Hansson 2013-04-09 10:07 ` Samuel Ortiz 2 siblings, 1 reply; 9+ messages in thread From: Ulf Hansson @ 2013-04-02 23:06 UTC (permalink / raw) To: linux-arm-kernel From: Ulf Hansson <ulf.hansson@linaro.org> The abx500-clk driver is initiated at arch_initcall level. Moreover it is relying on the ab8500-sysctrl API to be available. Therefore move ab8500-sysctrl to arch_initcall level as well. The device is already added before the abx500 clk device, thus it will be probed before as well, which is exactly what we want. Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org> Cc: Samuel Ortiz <sameo@linux.intel.com> --- drivers/mfd/ab8500-sysctrl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/mfd/ab8500-sysctrl.c b/drivers/mfd/ab8500-sysctrl.c index 108fd86..3b65053 100644 --- a/drivers/mfd/ab8500-sysctrl.c +++ b/drivers/mfd/ab8500-sysctrl.c @@ -166,7 +166,7 @@ static int __init ab8500_sysctrl_init(void) { return platform_driver_register(&ab8500_sysctrl_driver); } -subsys_initcall(ab8500_sysctrl_init); +arch_initcall(ab8500_sysctrl_init); MODULE_AUTHOR("Mattias Nilsson <mattias.i.nilsson@stericsson.com"); MODULE_DESCRIPTION("AB8500 system control driver"); -- 1.7.10 ^ permalink raw reply related [flat|nested] 9+ messages in thread
* [PATCH 3/3] mfd: ab8500: sysctrl: Initialize driver at arch_initcall 2013-04-02 23:06 ` [PATCH 3/3] mfd: ab8500: sysctrl: Initialize driver at arch_initcall Ulf Hansson @ 2013-04-09 10:07 ` Samuel Ortiz 0 siblings, 0 replies; 9+ messages in thread From: Samuel Ortiz @ 2013-04-09 10:07 UTC (permalink / raw) To: linux-arm-kernel Hi Ulf, On Wed, Apr 03, 2013 at 01:06:27AM +0200, Ulf Hansson wrote: > From: Ulf Hansson <ulf.hansson@linaro.org> > > The abx500-clk driver is initiated at arch_initcall level. Moreover it > is relying on the ab8500-sysctrl API to be available. Therefore move > ab8500-sysctrl to arch_initcall level as well. The device is already > added before the abx500 clk device, thus it will be probed before as > well, which is exactly what we want. > > Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org> > Cc: Samuel Ortiz <sameo@linux.intel.com> > --- > drivers/mfd/ab8500-sysctrl.c | 2 +- > 1 file changed, 1 insertion(+), 1 deletion(-) Applied, thanks. Cheers, Samuel. -- Intel Open Source Technology Centre http://oss.intel.com/ ^ permalink raw reply [flat|nested] 9+ messages in thread
end of thread, other threads:[~2013-04-10 18:29 UTC | newest] Thread overview: 9+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2013-04-02 23:06 [PATCH 0/3] clk: ux500: Add support for ab850x clocks Ulf Hansson 2013-04-02 23:06 ` [PATCH 1/3] clk: ux500: Add support for sysctrl clocks Ulf Hansson 2013-04-02 23:26 ` Mike Turquette 2013-04-02 23:06 ` [PATCH 2/3] clk: ux500: abx500: Define clock tree for ab850x Ulf Hansson 2013-04-04 14:08 ` Fabio Baltieri 2013-04-09 19:40 ` Mike Turquette 2013-04-10 18:29 ` Mike Turquette 2013-04-02 23:06 ` [PATCH 3/3] mfd: ab8500: sysctrl: Initialize driver at arch_initcall Ulf Hansson 2013-04-09 10:07 ` Samuel Ortiz
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).