From: Carlo Caione <carlo@caione.org> To: robh+dt@kernel.org, devicetree@vger.kernel.org, linux-arm-kernel@lists.infradead.org, mturquette@baylibre.com, linux-clk@vger.kernel.org, linux@arm.linux.org.uk, linux-meson@googlegroups.com, drake@endlessm.com, jerry.cao@amlogic.com, victor.wan@amlogic.com, pawel.moll@arm.com, arnd@arndb.de Cc: Carlo Caione <carlo@endlessm.com> Subject: [PATCH v2 3/7] clk: Amlogic: Add reset controller for CPU cores for Meson8b Date: Wed, 2 Dec 2015 18:22:29 +0100 [thread overview] Message-ID: <1449076953-5058-4-git-send-email-carlo@caione.org> (raw) In-Reply-To: <1449076953-5058-1-git-send-email-carlo@caione.org> From: Carlo Caione <carlo@endlessm.com> In the Amlogic Meson8b SoC we need to soft reset the CPU cores during the boot to enable the SMP support. With this patch we extend the clock controller adding a small reset controller in charge of resetting the cores. Signed-off-by: Carlo Caione <carlo@endlessm.com> --- drivers/clk/meson/clk-cpu.c | 60 +++++++++++++++++++++++++++++++- drivers/clk/meson/clkc.c | 5 +-- drivers/clk/meson/clkc.h | 6 ++-- drivers/clk/meson/meson8b-clkc.c | 4 +-- include/dt-bindings/clock/meson8b-clkc.h | 5 +++ 5 files changed, 73 insertions(+), 7 deletions(-) diff --git a/drivers/clk/meson/clk-cpu.c b/drivers/clk/meson/clk-cpu.c index f7c30ea..8836fa9 100644 --- a/drivers/clk/meson/clk-cpu.c +++ b/drivers/clk/meson/clk-cpu.c @@ -37,9 +37,14 @@ #include <linux/slab.h> #include <linux/clk.h> #include <linux/clk-provider.h> +#include <linux/reset.h> +#include <linux/reset-controller.h> #define MESON_CPU_CLK_CNTL1 0x00 #define MESON_CPU_CLK_CNTL 0x40 +#define MESON_CPU_CLK_CNTL_CPU 0x19c + +#define MESON_MAX_CPU_RST 4 #define MESON_CPU_CLK_MUX1 BIT(7) #define MESON_CPU_CLK_MUX2 BIT(0) @@ -51,6 +56,11 @@ #include "clkc.h" +struct meson_reset_cpu { + void __iomem *reset_base; + struct reset_controller_dev rcdev; +}; + struct meson_clk_cpu { struct notifier_block clk_nb; const struct clk_div_table *div_table; @@ -182,13 +192,50 @@ static const struct clk_ops meson_clk_cpu_ops = { .set_rate = meson_clk_cpu_set_rate, }; -struct clk *meson_clk_register_cpu(const struct clk_conf *clk_conf, +static int meson_reset_cpu_assert(struct reset_controller_dev *rcdev, + unsigned long id) +{ + u32 reg; + struct meson_reset_cpu *reset_cpu = container_of(rcdev, + struct meson_reset_cpu, + rcdev); + + reg = readl(reset_cpu->reset_base); + reg |= BIT(id + 24); + writel(reg, reset_cpu->reset_base); + + return 0; +} + +static int meson_reset_cpu_deassert(struct reset_controller_dev *rcdev, + unsigned long id) +{ + u32 reg; + struct meson_reset_cpu *reset_cpu = container_of(rcdev, + struct meson_reset_cpu, + rcdev); + + reg = readl(reset_cpu->reset_base); + reg &= ~BIT(id + 24); + writel(reg, reset_cpu->reset_base); + + return 0; +} + +static struct reset_control_ops meson_cpu_reset_ops = { + .assert = meson_reset_cpu_assert, + .deassert = meson_reset_cpu_deassert, +}; + +struct clk *meson_clk_register_cpu(struct device_node *np, + const struct clk_conf *clk_conf, void __iomem *reg_base, spinlock_t *lock) { struct clk *clk; struct clk *pclk; struct meson_clk_cpu *clk_cpu; + struct meson_reset_cpu *reset_cpu; struct clk_init_data init; int ret; @@ -231,6 +278,17 @@ struct clk *meson_clk_register_cpu(const struct clk_conf *clk_conf, goto unregister_clk_nb; } + reset_cpu = kzalloc(sizeof(*reset_cpu), GFP_KERNEL); + if (!reset_cpu) + goto out; + + reset_cpu->reset_base = reg_base + MESON_CPU_CLK_CNTL_CPU; + reset_cpu->rcdev.nr_resets = MESON_MAX_CPU_RST; + reset_cpu->rcdev.ops = &meson_cpu_reset_ops; + reset_cpu->rcdev.of_node = np; + reset_controller_register(&reset_cpu->rcdev); + +out: return clk; unregister_clk_nb: diff --git a/drivers/clk/meson/clkc.c b/drivers/clk/meson/clkc.c index c83ae13..df71e82 100644 --- a/drivers/clk/meson/clkc.c +++ b/drivers/clk/meson/clkc.c @@ -197,7 +197,8 @@ meson_clk_register_fixed_rate(const struct clk_conf *clk_conf, return clk; } -void __init meson_clk_register_clks(const struct clk_conf *clk_confs, +void __init meson_clk_register_clks(struct device_node *np, + const struct clk_conf *clk_confs, size_t nr_confs, void __iomem *clk_base) { @@ -221,7 +222,7 @@ void __init meson_clk_register_clks(const struct clk_conf *clk_confs, clk_base); break; case CLK_CPU: - clk = meson_clk_register_cpu(clk_conf, clk_base, + clk = meson_clk_register_cpu(np, clk_conf, clk_base, &clk_lock); break; case CLK_PLL: diff --git a/drivers/clk/meson/clkc.h b/drivers/clk/meson/clkc.h index 609ae92..648d41d 100644 --- a/drivers/clk/meson/clkc.h +++ b/drivers/clk/meson/clkc.h @@ -177,9 +177,11 @@ struct clk_conf { } \ struct clk **meson_clk_init(struct device_node *np, unsigned long nr_clks); -void meson_clk_register_clks(const struct clk_conf *clk_confs, +void meson_clk_register_clks(struct device_node *np, + const struct clk_conf *clk_confs, unsigned int nr_confs, void __iomem *clk_base); -struct clk *meson_clk_register_cpu(const struct clk_conf *clk_conf, +struct clk *meson_clk_register_cpu(struct device_node *np, + const struct clk_conf *clk_conf, void __iomem *reg_base, spinlock_t *lock); struct clk *meson_clk_register_pll(const struct clk_conf *clk_conf, void __iomem *reg_base, spinlock_t *lock); diff --git a/drivers/clk/meson/meson8b-clkc.c b/drivers/clk/meson/meson8b-clkc.c index 61f6d55..98f1ebd 100644 --- a/drivers/clk/meson/meson8b-clkc.c +++ b/drivers/clk/meson/meson8b-clkc.c @@ -179,7 +179,7 @@ static void __init meson8b_clkc_init(struct device_node *np) return; } - meson_clk_register_clks(&meson8b_xtal_conf, 1, clk_base); + meson_clk_register_clks(np, &meson8b_xtal_conf, 1, clk_base); iounmap(clk_base); /* Generic clocks and PLLs */ @@ -189,7 +189,7 @@ static void __init meson8b_clkc_init(struct device_node *np) return; } - meson_clk_register_clks(meson8b_clk_confs, + meson_clk_register_clks(np, meson8b_clk_confs, ARRAY_SIZE(meson8b_clk_confs), clk_base); } diff --git a/include/dt-bindings/clock/meson8b-clkc.h b/include/dt-bindings/clock/meson8b-clkc.h index bd2720d..bbdadca 100644 --- a/include/dt-bindings/clock/meson8b-clkc.h +++ b/include/dt-bindings/clock/meson8b-clkc.h @@ -5,6 +5,11 @@ #ifndef __MESON8B_CLKC_H #define __MESON8B_CLKC_H +#define RST_CORE0 0 +#define RST_CORE1 1 +#define RST_CORE2 2 +#define RST_CORE3 3 + #define CLKID_UNUSED 0 #define CLKID_XTAL 1 #define CLKID_PLL_FIXED 2 -- 2.5.0
WARNING: multiple messages have this Message-ID (diff)
From: carlo@caione.org (Carlo Caione) To: linux-arm-kernel@lists.infradead.org Subject: [PATCH v2 3/7] clk: Amlogic: Add reset controller for CPU cores for Meson8b Date: Wed, 2 Dec 2015 18:22:29 +0100 [thread overview] Message-ID: <1449076953-5058-4-git-send-email-carlo@caione.org> (raw) In-Reply-To: <1449076953-5058-1-git-send-email-carlo@caione.org> From: Carlo Caione <carlo@endlessm.com> In the Amlogic Meson8b SoC we need to soft reset the CPU cores during the boot to enable the SMP support. With this patch we extend the clock controller adding a small reset controller in charge of resetting the cores. Signed-off-by: Carlo Caione <carlo@endlessm.com> --- drivers/clk/meson/clk-cpu.c | 60 +++++++++++++++++++++++++++++++- drivers/clk/meson/clkc.c | 5 +-- drivers/clk/meson/clkc.h | 6 ++-- drivers/clk/meson/meson8b-clkc.c | 4 +-- include/dt-bindings/clock/meson8b-clkc.h | 5 +++ 5 files changed, 73 insertions(+), 7 deletions(-) diff --git a/drivers/clk/meson/clk-cpu.c b/drivers/clk/meson/clk-cpu.c index f7c30ea..8836fa9 100644 --- a/drivers/clk/meson/clk-cpu.c +++ b/drivers/clk/meson/clk-cpu.c @@ -37,9 +37,14 @@ #include <linux/slab.h> #include <linux/clk.h> #include <linux/clk-provider.h> +#include <linux/reset.h> +#include <linux/reset-controller.h> #define MESON_CPU_CLK_CNTL1 0x00 #define MESON_CPU_CLK_CNTL 0x40 +#define MESON_CPU_CLK_CNTL_CPU 0x19c + +#define MESON_MAX_CPU_RST 4 #define MESON_CPU_CLK_MUX1 BIT(7) #define MESON_CPU_CLK_MUX2 BIT(0) @@ -51,6 +56,11 @@ #include "clkc.h" +struct meson_reset_cpu { + void __iomem *reset_base; + struct reset_controller_dev rcdev; +}; + struct meson_clk_cpu { struct notifier_block clk_nb; const struct clk_div_table *div_table; @@ -182,13 +192,50 @@ static const struct clk_ops meson_clk_cpu_ops = { .set_rate = meson_clk_cpu_set_rate, }; -struct clk *meson_clk_register_cpu(const struct clk_conf *clk_conf, +static int meson_reset_cpu_assert(struct reset_controller_dev *rcdev, + unsigned long id) +{ + u32 reg; + struct meson_reset_cpu *reset_cpu = container_of(rcdev, + struct meson_reset_cpu, + rcdev); + + reg = readl(reset_cpu->reset_base); + reg |= BIT(id + 24); + writel(reg, reset_cpu->reset_base); + + return 0; +} + +static int meson_reset_cpu_deassert(struct reset_controller_dev *rcdev, + unsigned long id) +{ + u32 reg; + struct meson_reset_cpu *reset_cpu = container_of(rcdev, + struct meson_reset_cpu, + rcdev); + + reg = readl(reset_cpu->reset_base); + reg &= ~BIT(id + 24); + writel(reg, reset_cpu->reset_base); + + return 0; +} + +static struct reset_control_ops meson_cpu_reset_ops = { + .assert = meson_reset_cpu_assert, + .deassert = meson_reset_cpu_deassert, +}; + +struct clk *meson_clk_register_cpu(struct device_node *np, + const struct clk_conf *clk_conf, void __iomem *reg_base, spinlock_t *lock) { struct clk *clk; struct clk *pclk; struct meson_clk_cpu *clk_cpu; + struct meson_reset_cpu *reset_cpu; struct clk_init_data init; int ret; @@ -231,6 +278,17 @@ struct clk *meson_clk_register_cpu(const struct clk_conf *clk_conf, goto unregister_clk_nb; } + reset_cpu = kzalloc(sizeof(*reset_cpu), GFP_KERNEL); + if (!reset_cpu) + goto out; + + reset_cpu->reset_base = reg_base + MESON_CPU_CLK_CNTL_CPU; + reset_cpu->rcdev.nr_resets = MESON_MAX_CPU_RST; + reset_cpu->rcdev.ops = &meson_cpu_reset_ops; + reset_cpu->rcdev.of_node = np; + reset_controller_register(&reset_cpu->rcdev); + +out: return clk; unregister_clk_nb: diff --git a/drivers/clk/meson/clkc.c b/drivers/clk/meson/clkc.c index c83ae13..df71e82 100644 --- a/drivers/clk/meson/clkc.c +++ b/drivers/clk/meson/clkc.c @@ -197,7 +197,8 @@ meson_clk_register_fixed_rate(const struct clk_conf *clk_conf, return clk; } -void __init meson_clk_register_clks(const struct clk_conf *clk_confs, +void __init meson_clk_register_clks(struct device_node *np, + const struct clk_conf *clk_confs, size_t nr_confs, void __iomem *clk_base) { @@ -221,7 +222,7 @@ void __init meson_clk_register_clks(const struct clk_conf *clk_confs, clk_base); break; case CLK_CPU: - clk = meson_clk_register_cpu(clk_conf, clk_base, + clk = meson_clk_register_cpu(np, clk_conf, clk_base, &clk_lock); break; case CLK_PLL: diff --git a/drivers/clk/meson/clkc.h b/drivers/clk/meson/clkc.h index 609ae92..648d41d 100644 --- a/drivers/clk/meson/clkc.h +++ b/drivers/clk/meson/clkc.h @@ -177,9 +177,11 @@ struct clk_conf { } \ struct clk **meson_clk_init(struct device_node *np, unsigned long nr_clks); -void meson_clk_register_clks(const struct clk_conf *clk_confs, +void meson_clk_register_clks(struct device_node *np, + const struct clk_conf *clk_confs, unsigned int nr_confs, void __iomem *clk_base); -struct clk *meson_clk_register_cpu(const struct clk_conf *clk_conf, +struct clk *meson_clk_register_cpu(struct device_node *np, + const struct clk_conf *clk_conf, void __iomem *reg_base, spinlock_t *lock); struct clk *meson_clk_register_pll(const struct clk_conf *clk_conf, void __iomem *reg_base, spinlock_t *lock); diff --git a/drivers/clk/meson/meson8b-clkc.c b/drivers/clk/meson/meson8b-clkc.c index 61f6d55..98f1ebd 100644 --- a/drivers/clk/meson/meson8b-clkc.c +++ b/drivers/clk/meson/meson8b-clkc.c @@ -179,7 +179,7 @@ static void __init meson8b_clkc_init(struct device_node *np) return; } - meson_clk_register_clks(&meson8b_xtal_conf, 1, clk_base); + meson_clk_register_clks(np, &meson8b_xtal_conf, 1, clk_base); iounmap(clk_base); /* Generic clocks and PLLs */ @@ -189,7 +189,7 @@ static void __init meson8b_clkc_init(struct device_node *np) return; } - meson_clk_register_clks(meson8b_clk_confs, + meson_clk_register_clks(np, meson8b_clk_confs, ARRAY_SIZE(meson8b_clk_confs), clk_base); } diff --git a/include/dt-bindings/clock/meson8b-clkc.h b/include/dt-bindings/clock/meson8b-clkc.h index bd2720d..bbdadca 100644 --- a/include/dt-bindings/clock/meson8b-clkc.h +++ b/include/dt-bindings/clock/meson8b-clkc.h @@ -5,6 +5,11 @@ #ifndef __MESON8B_CLKC_H #define __MESON8B_CLKC_H +#define RST_CORE0 0 +#define RST_CORE1 1 +#define RST_CORE2 2 +#define RST_CORE3 3 + #define CLKID_UNUSED 0 #define CLKID_XTAL 1 #define CLKID_PLL_FIXED 2 -- 2.5.0
next prev parent reply other threads:[~2015-12-02 17:22 UTC|newest] Thread overview: 27+ messages / expand[flat|nested] mbox.gz Atom feed top 2015-12-02 17:22 [PATCH v2 0/7] Add basic SMP support for Amlogic Meson8b Carlo Caione 2015-12-02 17:22 ` Carlo Caione 2015-12-02 17:22 ` [PATCH v2 1/7] ARM: DTS: Amlogic: Extend L2 cache controller node for Meson8b Carlo Caione 2015-12-02 17:22 ` Carlo Caione 2015-12-02 17:22 ` [PATCH v2 2/7] dt-bindings: Amlogic: Document the CPU reset controller " Carlo Caione 2015-12-02 17:22 ` Carlo Caione 2015-12-04 14:49 ` Rob Herring 2015-12-04 14:49 ` Rob Herring 2015-12-02 17:22 ` Carlo Caione [this message] 2015-12-02 17:22 ` [PATCH v2 3/7] clk: Amlogic: Add reset controller for CPU cores " Carlo Caione 2015-12-02 19:39 ` Arnd Bergmann 2015-12-02 19:39 ` Arnd Bergmann 2015-12-02 17:22 ` [PATCH v2 4/7] ARM: DTS: Amlogic: Enable reset controller " Carlo Caione 2015-12-02 17:22 ` Carlo Caione [not found] ` <1449076953-5058-1-git-send-email-carlo-KA+7E9HrN00dnm+yROfE0A@public.gmane.org> 2015-12-02 17:22 ` [PATCH v2 5/7] dt-bindings: Amlogic: Add SMP related documentation Carlo Caione 2015-12-02 17:22 ` Carlo Caione 2015-12-02 17:22 ` Carlo Caione 2015-12-04 14:52 ` Rob Herring 2015-12-04 14:52 ` Rob Herring 2015-12-02 17:22 ` [PATCH v2 6/7] ARM: Amlogic: Add SMP bringup code for Meson8b Carlo Caione 2015-12-02 17:22 ` Carlo Caione 2015-12-02 17:22 ` Carlo Caione 2015-12-02 17:22 ` [PATCH v2 7/7] ARM: DTS: Amlogic: Add SMP related nodes " Carlo Caione 2015-12-02 17:22 ` Carlo Caione 2015-12-02 17:22 ` Carlo Caione 2015-12-04 14:53 ` Rob Herring 2015-12-04 14:53 ` Rob Herring
Reply instructions: You may reply publicly to this message via plain-text email using any one of the following methods: * Save the following mbox file, import it into your mail client, and reply-to-all from there: mbox Avoid top-posting and favor interleaved quoting: https://en.wikipedia.org/wiki/Posting_style#Interleaved_style * Reply using the --to, --cc, and --in-reply-to switches of git-send-email(1): git send-email \ --in-reply-to=1449076953-5058-4-git-send-email-carlo@caione.org \ --to=carlo@caione.org \ --cc=arnd@arndb.de \ --cc=carlo@endlessm.com \ --cc=devicetree@vger.kernel.org \ --cc=drake@endlessm.com \ --cc=jerry.cao@amlogic.com \ --cc=linux-arm-kernel@lists.infradead.org \ --cc=linux-clk@vger.kernel.org \ --cc=linux-meson@googlegroups.com \ --cc=linux@arm.linux.org.uk \ --cc=mturquette@baylibre.com \ --cc=pawel.moll@arm.com \ --cc=robh+dt@kernel.org \ --cc=victor.wan@amlogic.com \ /path/to/YOUR_REPLY https://kernel.org/pub/software/scm/git/docs/git-send-email.html * If your mail client supports setting the In-Reply-To header via mailto: links, try the mailto: linkBe sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes, see mirroring instructions on how to clone and mirror all data and code used by this external index.