All of lore.kernel.org
 help / color / mirror / Atom feed
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

  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: link
Be 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.