mail archive of the barebox mailing list
 help / color / mirror / Atom feed
* [PATCH 00/14] Add initial STMicroelectronics MP1 support
@ 2019-03-11  9:31 Sascha Hauer
  2019-03-11  9:31 ` [PATCH 01/14] clk: clk-composite: return parent_rate if no rate clk Sascha Hauer
                   ` (13 more replies)
  0 siblings, 14 replies; 17+ messages in thread
From: Sascha Hauer @ 2019-03-11  9:31 UTC (permalink / raw)
  To: Barebox List

This adds very basic STMicroelectronics MP1 support. No 1st stage so
far, only the clock driver and UART driver have been ported. the only
supported board right now is the DK2 development board. This is
basically a "Let's see how far I can get in a single day" effort. Stay
tuned for more, but currently this is more of a low priority
project.

Sascha

Sascha Hauer (14):
  clk: clk-composite: return parent_rate if no rate clk
  clk: parent_names should be const
  clk: export clk_gate_is_enabled()
  clk: Make CLK_IGNORE_UNUSED generic
  clk: Support CLK_IS_CRITICAL flag
  clk: divider: pass divider flags
  clk: divider: Support CLK_DIVIDER_READ_ONLY flag
  clk: mux: Support mux specific flags
  clk: mux: Support CLK_MUX_READ_ONLY flag
  clk: mux: Support CLK_SET_RATE_NO_REPARENT flag
  ARM: stm32mp1: Add clk driver
  ARM: stm32mp1: Add serial driver
  clocksource: Enable architected timer support for CPU_V7
  ARM: Add initial STM32MP1 support

 arch/arm/Kconfig                              |   11 +
 arch/arm/Makefile                             |    1 +
 arch/arm/boards/Makefile                      |    1 +
 arch/arm/boards/stm32mp157c-dk2/Makefile      |    2 +
 arch/arm/boards/stm32mp157c-dk2/board.c       |   16 +
 arch/arm/boards/stm32mp157c-dk2/lowlevel.c    |   18 +
 arch/arm/configs/stm32mp1_defconfig           |   98 +
 arch/arm/dts/Makefile                         |    1 +
 arch/arm/dts/stm32mp157a-dk1.dts              |   62 +
 arch/arm/dts/stm32mp157c-dk2.dts              |   14 +
 arch/arm/dts/stm32mp157c.dtsi                 |    7 +
 arch/arm/include/asm/system.h                 |   19 +
 arch/arm/mach-clps711x/clock.c                |    4 +-
 arch/arm/mach-stm32mp1/Kconfig                |   10 +
 arch/arm/mach-stm32mp1/Makefile               |    1 +
 .../arm/mach-stm32mp1/include/mach/debug_ll.h |   28 +
 arch/arm/mach-stm32mp1/include/mach/stm32.h   |   35 +
 drivers/clk/Makefile                          |    1 +
 drivers/clk/clk-composite.c                   |    7 +-
 drivers/clk/clk-divider.c                     |   35 +-
 drivers/clk/clk-gate.c                        |    2 +-
 drivers/clk/clk-mux.c                         |   24 +-
 drivers/clk/clk-stm32mp1.c                    | 1988 +++++++++++++++++
 drivers/clk/clk.c                             |    3 +
 drivers/clk/imx/clk-vf610.c                   |    2 +-
 drivers/clk/imx/clk.h                         |   33 +-
 drivers/clk/mxs/clk.h                         |    2 +-
 drivers/clk/rockchip/clk-pll.c                |    3 +-
 drivers/clk/rockchip/clk-rk3188.c             |    3 -
 drivers/clk/rockchip/clk-rk3288.c             |    3 -
 drivers/clk/rockchip/clk.c                    |   16 +-
 drivers/clk/rockchip/clk.h                    |    1 -
 drivers/clk/tegra/clk-periph.c                |    2 +-
 drivers/clocksource/Kconfig                   |    2 +-
 drivers/clocksource/armv8-timer.c             |    1 +
 drivers/serial/Kconfig                        |    4 +
 drivers/serial/Makefile                       |    1 +
 drivers/serial/serial_stm32.c                 |  246 ++
 drivers/serial/serial_stm32.h                 |   48 +
 images/Makefile                               |    1 +
 images/Makefile.stm32mp1                      |    8 +
 include/linux/clk.h                           |   41 +-
 42 files changed, 2732 insertions(+), 73 deletions(-)
 create mode 100644 arch/arm/boards/stm32mp157c-dk2/Makefile
 create mode 100644 arch/arm/boards/stm32mp157c-dk2/board.c
 create mode 100644 arch/arm/boards/stm32mp157c-dk2/lowlevel.c
 create mode 100644 arch/arm/configs/stm32mp1_defconfig
 create mode 100644 arch/arm/dts/stm32mp157a-dk1.dts
 create mode 100644 arch/arm/dts/stm32mp157c-dk2.dts
 create mode 100644 arch/arm/dts/stm32mp157c.dtsi
 create mode 100644 arch/arm/mach-stm32mp1/Kconfig
 create mode 100644 arch/arm/mach-stm32mp1/Makefile
 create mode 100644 arch/arm/mach-stm32mp1/include/mach/debug_ll.h
 create mode 100644 arch/arm/mach-stm32mp1/include/mach/stm32.h
 create mode 100644 drivers/clk/clk-stm32mp1.c
 create mode 100644 drivers/serial/serial_stm32.c
 create mode 100644 drivers/serial/serial_stm32.h
 create mode 100644 images/Makefile.stm32mp1

-- 
2.20.1


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 17+ messages in thread

* [PATCH 01/14] clk: clk-composite: return parent_rate if no rate clk
  2019-03-11  9:31 [PATCH 00/14] Add initial STMicroelectronics MP1 support Sascha Hauer
@ 2019-03-11  9:31 ` Sascha Hauer
  2019-03-11  9:31 ` [PATCH 02/14] clk: parent_names should be const Sascha Hauer
                   ` (12 subsequent siblings)
  13 siblings, 0 replies; 17+ messages in thread
From: Sascha Hauer @ 2019-03-11  9:31 UTC (permalink / raw)
  To: Barebox List

When a composite clock has no rate clock then it should output the
parents rate.

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
 drivers/clk/clk-composite.c | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/drivers/clk/clk-composite.c b/drivers/clk/clk-composite.c
index 5d21a0e7e1..716f6805f3 100644
--- a/drivers/clk/clk-composite.c
+++ b/drivers/clk/clk-composite.c
@@ -54,7 +54,10 @@ static unsigned long clk_composite_recalc_rate(struct clk *clk,
 	struct clk_composite *composite = to_clk_composite(clk);
 	struct clk *rate_clk = composite->rate_clk;
 
-	return rate_clk ? rate_clk->ops->recalc_rate(rate_clk, parent_rate) : 0;
+	if (rate_clk)
+		return rate_clk->ops->recalc_rate(rate_clk, parent_rate);
+
+	return parent_rate;
 }
 
 static long clk_composite_round_rate(struct clk *clk, unsigned long rate,
-- 
2.20.1


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 17+ messages in thread

* [PATCH 02/14] clk: parent_names should be const
  2019-03-11  9:31 [PATCH 00/14] Add initial STMicroelectronics MP1 support Sascha Hauer
  2019-03-11  9:31 ` [PATCH 01/14] clk: clk-composite: return parent_rate if no rate clk Sascha Hauer
@ 2019-03-11  9:31 ` Sascha Hauer
  2019-03-11  9:31 ` [PATCH 03/14] clk: export clk_gate_is_enabled() Sascha Hauer
                   ` (11 subsequent siblings)
  13 siblings, 0 replies; 17+ messages in thread
From: Sascha Hauer @ 2019-03-11  9:31 UTC (permalink / raw)
  To: Barebox List

Not only the array of pointers should be const, but also the strings
they point to. Add missing const.

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
 drivers/clk/clk-composite.c | 2 +-
 drivers/clk/clk-mux.c       | 4 ++--
 include/linux/clk.h         | 8 ++++----
 3 files changed, 7 insertions(+), 7 deletions(-)

diff --git a/drivers/clk/clk-composite.c b/drivers/clk/clk-composite.c
index 716f6805f3..e21ab98453 100644
--- a/drivers/clk/clk-composite.c
+++ b/drivers/clk/clk-composite.c
@@ -116,7 +116,7 @@ static struct clk_ops clk_composite_ops = {
 };
 
 struct clk *clk_register_composite(const char *name,
-			const char **parent_names, int num_parents,
+			const char * const *parent_names, int num_parents,
 			struct clk *mux_clk,
 			struct clk *rate_clk,
 			struct clk *gate_clk,
diff --git a/drivers/clk/clk-mux.c b/drivers/clk/clk-mux.c
index d5fe640dce..a108a72d63 100644
--- a/drivers/clk/clk-mux.c
+++ b/drivers/clk/clk-mux.c
@@ -52,7 +52,7 @@ struct clk_ops clk_mux_ops = {
 };
 
 struct clk *clk_mux_alloc(const char *name, void __iomem *reg,
-		u8 shift, u8 width, const char **parents, u8 num_parents,
+		u8 shift, u8 width, const char * const *parents, u8 num_parents,
 		unsigned flags)
 {
 	struct clk_mux *m = xzalloc(sizeof(*m));
@@ -77,7 +77,7 @@ void clk_mux_free(struct clk *clk_mux)
 }
 
 struct clk *clk_mux(const char *name, void __iomem *reg,
-		u8 shift, u8 width, const char **parents, u8 num_parents, unsigned flags)
+		u8 shift, u8 width, const char * const *parents, u8 num_parents, unsigned flags)
 {
 	struct clk *m;
 	int ret;
diff --git a/include/linux/clk.h b/include/linux/clk.h
index ee888dc083..1f20eb2772 100644
--- a/include/linux/clk.h
+++ b/include/linux/clk.h
@@ -310,7 +310,7 @@ struct clk {
 	int enable_count;
 	struct list_head list;
 	const char *name;
-	const char **parent_names;
+	const char * const *parent_names;
 	int num_parents;
 
 	struct clk **parents;
@@ -384,11 +384,11 @@ struct clk_mux {
 extern struct clk_ops clk_mux_ops;
 
 struct clk *clk_mux_alloc(const char *name, void __iomem *reg,
-		u8 shift, u8 width, const char **parents, u8 num_parents,
+		u8 shift, u8 width, const char * const *parents, u8 num_parents,
 		unsigned flags);
 void clk_mux_free(struct clk *clk_mux);
 struct clk *clk_mux(const char *name, void __iomem *reg,
-		u8 shift, u8 width, const char **parents, u8 num_parents,
+		u8 shift, u8 width, const char * const *parents, u8 num_parents,
 		unsigned flags);
 
 struct clk_gate {
@@ -429,7 +429,7 @@ struct clk *clk_lookup(const char *name);
 void clk_dump(int verbose);
 
 struct clk *clk_register_composite(const char *name,
-			const char **parent_names, int num_parents,
+			const char * const *parent_names, int num_parents,
 			struct clk *mux_clk,
 			struct clk *rate_clk,
 			struct clk *gate_clk,
-- 
2.20.1


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 17+ messages in thread

* [PATCH 03/14] clk: export clk_gate_is_enabled()
  2019-03-11  9:31 [PATCH 00/14] Add initial STMicroelectronics MP1 support Sascha Hauer
  2019-03-11  9:31 ` [PATCH 01/14] clk: clk-composite: return parent_rate if no rate clk Sascha Hauer
  2019-03-11  9:31 ` [PATCH 02/14] clk: parent_names should be const Sascha Hauer
@ 2019-03-11  9:31 ` Sascha Hauer
  2019-03-11  9:31 ` [PATCH 04/14] clk: Make CLK_IGNORE_UNUSED generic Sascha Hauer
                   ` (10 subsequent siblings)
  13 siblings, 0 replies; 17+ messages in thread
From: Sascha Hauer @ 2019-03-11  9:31 UTC (permalink / raw)
  To: Barebox List

Will be needed by stm32 clk support.

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
 drivers/clk/clk-gate.c | 2 +-
 include/linux/clk.h    | 2 ++
 2 files changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/clk/clk-gate.c b/drivers/clk/clk-gate.c
index 89240ff794..b2b160555e 100644
--- a/drivers/clk/clk-gate.c
+++ b/drivers/clk/clk-gate.c
@@ -56,7 +56,7 @@ static void clk_gate_disable(struct clk *clk)
 	clk_gate_endisable(clk, 0);
 }
 
-static int clk_gate_is_enabled(struct clk *clk)
+int clk_gate_is_enabled(struct clk *clk)
 {
 	struct clk_gate *g = container_of(clk, struct clk_gate, clk);
 	u32 val;
diff --git a/include/linux/clk.h b/include/linux/clk.h
index 1f20eb2772..6081a1af87 100644
--- a/include/linux/clk.h
+++ b/include/linux/clk.h
@@ -399,6 +399,8 @@ struct clk_gate {
 	unsigned flags;
 };
 
+int clk_gate_is_enabled(struct clk *clk);
+
 #define to_clk_gate(_clk) container_of(_clk, struct clk_gate, clk)
 
 extern struct clk_ops clk_gate_ops;
-- 
2.20.1


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 17+ messages in thread

* [PATCH 04/14] clk: Make CLK_IGNORE_UNUSED generic
  2019-03-11  9:31 [PATCH 00/14] Add initial STMicroelectronics MP1 support Sascha Hauer
                   ` (2 preceding siblings ...)
  2019-03-11  9:31 ` [PATCH 03/14] clk: export clk_gate_is_enabled() Sascha Hauer
@ 2019-03-11  9:31 ` Sascha Hauer
  2019-03-11  9:31 ` [PATCH 05/14] clk: Support CLK_IS_CRITICAL flag Sascha Hauer
                   ` (9 subsequent siblings)
  13 siblings, 0 replies; 17+ messages in thread
From: Sascha Hauer @ 2019-03-11  9:31 UTC (permalink / raw)
  To: Barebox List

barebox will never disable unused clocks, so add CLK_IGNORE_UNUSED as a
no-op flag. With this we can keep the changes to the imported kernel
code smaller.

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
 drivers/clk/rockchip/clk.h | 1 -
 include/linux/clk.h        | 1 +
 2 files changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/clk/rockchip/clk.h b/drivers/clk/rockchip/clk.h
index aa52638f70..d6798a9055 100644
--- a/drivers/clk/rockchip/clk.h
+++ b/drivers/clk/rockchip/clk.h
@@ -27,7 +27,6 @@
 #include <linux/clk.h>
 
 /* To keep changes from kernel smaller */
-#define CLK_IGNORE_UNUSED 0
 #define CLK_GATE_SET_TO_DISABLE	CLK_GATE_INVERTED
 #define CLK_GET_RATE_NOCACHE 0
 
diff --git a/include/linux/clk.h b/include/linux/clk.h
index 6081a1af87..5b0a93095d 100644
--- a/include/linux/clk.h
+++ b/include/linux/clk.h
@@ -285,6 +285,7 @@ static inline void clk_put(struct clk *clk)
 #include <linux/list.h>
 
 #define CLK_SET_RATE_PARENT     (1 << 0) /* propagate rate change up one level */
+#define CLK_IGNORE_UNUSED       (1 << 3) /* do not gate even if unused */
 /* parents need enable during gate/ungate, set rate and re-parent */
 #define CLK_OPS_PARENT_ENABLE   (1 << 12)
 
-- 
2.20.1


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 17+ messages in thread

* [PATCH 05/14] clk: Support CLK_IS_CRITICAL flag
  2019-03-11  9:31 [PATCH 00/14] Add initial STMicroelectronics MP1 support Sascha Hauer
                   ` (3 preceding siblings ...)
  2019-03-11  9:31 ` [PATCH 04/14] clk: Make CLK_IGNORE_UNUSED generic Sascha Hauer
@ 2019-03-11  9:31 ` Sascha Hauer
  2019-03-11  9:31 ` [PATCH 06/14] clk: divider: pass divider flags Sascha Hauer
                   ` (8 subsequent siblings)
  13 siblings, 0 replies; 17+ messages in thread
From: Sascha Hauer @ 2019-03-11  9:31 UTC (permalink / raw)
  To: Barebox List

Support CLK_IS_CRITICAL flag. Simply do not disable the clock even when
the enable count is zero.

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
 drivers/clk/clk.c   | 3 +++
 include/linux/clk.h | 1 +
 2 files changed, 4 insertions(+)

diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c
index 6a2d8ad178..ea3304bc7c 100644
--- a/drivers/clk/clk.c
+++ b/drivers/clk/clk.c
@@ -87,6 +87,9 @@ void clk_disable(struct clk *clk)
 	clk->enable_count--;
 
 	if (!clk->enable_count) {
+		if (clk->flags & CLK_IS_CRITICAL)
+			return;
+
 		if (clk->ops->disable)
 			clk->ops->disable(clk);
 
diff --git a/include/linux/clk.h b/include/linux/clk.h
index 5b0a93095d..5ad12c571c 100644
--- a/include/linux/clk.h
+++ b/include/linux/clk.h
@@ -286,6 +286,7 @@ static inline void clk_put(struct clk *clk)
 
 #define CLK_SET_RATE_PARENT     (1 << 0) /* propagate rate change up one level */
 #define CLK_IGNORE_UNUSED       (1 << 3) /* do not gate even if unused */
+#define CLK_IS_CRITICAL         (1 << 11) /* do not gate, ever */
 /* parents need enable during gate/ungate, set rate and re-parent */
 #define CLK_OPS_PARENT_ENABLE   (1 << 12)
 
-- 
2.20.1


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 17+ messages in thread

* [PATCH 06/14] clk: divider: pass divider flags
  2019-03-11  9:31 [PATCH 00/14] Add initial STMicroelectronics MP1 support Sascha Hauer
                   ` (4 preceding siblings ...)
  2019-03-11  9:31 ` [PATCH 05/14] clk: Support CLK_IS_CRITICAL flag Sascha Hauer
@ 2019-03-11  9:31 ` Sascha Hauer
  2019-03-11  9:31 ` [PATCH 07/14] clk: divider: Support CLK_DIVIDER_READ_ONLY flag Sascha Hauer
                   ` (7 subsequent siblings)
  13 siblings, 0 replies; 17+ messages in thread
From: Sascha Hauer @ 2019-03-11  9:31 UTC (permalink / raw)
  To: Barebox List

The generic clk divider needs clock flags and divider flags. Fix
prototypes to take both as separate arguments.

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
 arch/arm/mach-clps711x/clock.c |  4 ++--
 drivers/clk/clk-divider.c      | 28 +++++++++++++++++-----------
 drivers/clk/imx/clk-vf610.c    |  2 +-
 drivers/clk/imx/clk.h          | 14 ++++++++------
 drivers/clk/rockchip/clk.c     |  6 +++---
 include/linux/clk.h            | 16 ++++++++++------
 6 files changed, 41 insertions(+), 29 deletions(-)

diff --git a/arch/arm/mach-clps711x/clock.c b/arch/arm/mach-clps711x/clock.c
index 4d6403b92e..2c5137c582 100644
--- a/arch/arm/mach-clps711x/clock.c
+++ b/arch/arm/mach-clps711x/clock.c
@@ -71,9 +71,9 @@ static __init int clps711x_clk_init(void)
 	clks[CLPS711X_CLK_BUS] = clk_fixed("bus", f_bus);
 	clks[CLPS711X_CLK_UART] = clk_fixed("uart", f_uart);
 	clks[CLPS711X_CLK_TIMERREF] = clk_fixed("timer_ref", f_timer_ref);
-	clks[CLPS711X_CLK_TIMER1] = clk_divider_table("timer1", "timer_ref",
+	clks[CLPS711X_CLK_TIMER1] = clk_divider_table("timer1", "timer_ref", 0,
 		IOMEM(SYSCON1), 5, 1, tdiv_tbl, ARRAY_SIZE(tdiv_tbl));
-	clks[CLPS711X_CLK_TIMER2] = clk_divider_table("timer2", "timer_ref",
+	clks[CLPS711X_CLK_TIMER2] = clk_divider_table("timer2", "timer_ref", 0,
 		IOMEM(SYSCON1), 7, 1, tdiv_tbl, ARRAY_SIZE(tdiv_tbl));
 
 	clkdev_add_physbase(clks[CLPS711X_CLK_UART], UARTDR1, NULL);
diff --git a/drivers/clk/clk-divider.c b/drivers/clk/clk-divider.c
index 7b1bdde1ce..407aae78ea 100644
--- a/drivers/clk/clk-divider.c
+++ b/drivers/clk/clk-divider.c
@@ -249,7 +249,8 @@ struct clk_ops clk_divider_ops = {
 };
 
 struct clk *clk_divider_alloc(const char *name, const char *parent,
-		void __iomem *reg, u8 shift, u8 width, unsigned flags)
+			      unsigned clk_flags, void __iomem *reg, u8 shift,
+			      u8 width, unsigned div_flags)
 {
 	struct clk_divider *div = xzalloc(sizeof(*div));
 
@@ -257,9 +258,10 @@ struct clk *clk_divider_alloc(const char *name, const char *parent,
 	div->reg = reg;
 	div->width = width;
 	div->parent = parent;
+	div->flags = div_flags;
 	div->clk.ops = &clk_divider_ops;
 	div->clk.name = name;
-	div->clk.flags = flags;
+	div->clk.flags = clk_flags;
 	div->clk.parent_names = &div->parent;
 	div->clk.num_parents = 1;
 
@@ -273,13 +275,14 @@ void clk_divider_free(struct clk *clk)
 	free(d);
 }
 
-struct clk *clk_divider(const char *name, const char *parent,
-		void __iomem *reg, u8 shift, u8 width, unsigned flags)
+struct clk *clk_divider(const char *name, const char *parent, unsigned clk_flags,
+			void __iomem *reg, u8 shift, u8 width, unsigned div_flags)
 {
 	struct clk *d;
 	int ret;
 
-	d = clk_divider_alloc(name , parent, reg, shift, width, flags);
+	d = clk_divider_alloc(name , parent, clk_flags, reg, shift, width,
+			      div_flags);
 
 	ret = clk_register(d);
 	if (ret) {
@@ -291,12 +294,13 @@ struct clk *clk_divider(const char *name, const char *parent,
 }
 
 struct clk *clk_divider_one_based(const char *name, const char *parent,
-		void __iomem *reg, u8 shift, u8 width, unsigned flags)
+				  unsigned clk_flags, void __iomem *reg, u8 shift,
+				  u8 width, unsigned div_flags)
 {
 	struct clk_divider *div;
 	struct clk *clk;
 
-	clk = clk_divider(name, parent, reg, shift, width, flags);
+	clk = clk_divider(name, parent, clk_flags, reg, shift, width, div_flags);
 	if (IS_ERR(clk))
 		return clk;
 
@@ -306,9 +310,10 @@ struct clk *clk_divider_one_based(const char *name, const char *parent,
 	return clk;
 }
 
-struct clk *clk_divider_table(const char *name,
-		const char *parent, void __iomem *reg, u8 shift, u8 width,
-		const struct clk_div_table *table, unsigned flags)
+struct clk *clk_divider_table(const char *name, const char *parent,
+			      unsigned clk_flags, void __iomem *reg, u8 shift,
+			      u8 width, const struct clk_div_table *table,
+			      unsigned div_flags)
 {
 	struct clk_divider *div = xzalloc(sizeof(*div));
 	const struct clk_div_table *clkt;
@@ -318,9 +323,10 @@ struct clk *clk_divider_table(const char *name,
 	div->reg = reg;
 	div->width = width;
 	div->parent = parent;
+	div->flags = div_flags;
 	div->clk.ops = &clk_divider_ops;
 	div->clk.name = name;
-	div->clk.flags = flags;
+	div->clk.flags = clk_flags;
 	div->clk.parent_names = &div->parent;
 	div->clk.num_parents = 1;
 	div->table = table;
diff --git a/drivers/clk/imx/clk-vf610.c b/drivers/clk/imx/clk-vf610.c
index 49d66fb592..1b1b881052 100644
--- a/drivers/clk/imx/clk-vf610.c
+++ b/drivers/clk/imx/clk-vf610.c
@@ -252,7 +252,7 @@ static void __init vf610_clocks_init(struct device_node *ccm_node)
 	clk[VF610_CLK_IPG_BUS] = imx_clk_divider("ipg_bus", "platform_bus", CCM_CACRR, 11, 2);
 
 	clk[VF610_CLK_PLL3_MAIN_DIV] = imx_clk_divider("pll3_usb_otg_div", "pll3_usb_otg", CCM_CACRR, 20, 1);
-	clk[VF610_CLK_PLL4_MAIN_DIV] = clk_divider_table("pll4_audio_div", "pll4_audio", CCM_CACRR, 6, 3, pll4_audio_div_table, 0);
+	clk[VF610_CLK_PLL4_MAIN_DIV] = clk_divider_table("pll4_audio_div", "pll4_audio", 0, CCM_CACRR, 6, 3, pll4_audio_div_table, 0);
 	clk[VF610_CLK_PLL6_MAIN_DIV] = imx_clk_divider("pll6_video_div", "pll6_video", CCM_CACRR, 21, 1);
 
 	clk[VF610_CLK_DDRMC] = imx_clk_gate2_cgr("ddrmc", "ddr_sel", CCM_CCGR6, CCM_CCGRx_CGn(14), 0x2);
diff --git a/drivers/clk/imx/clk.h b/drivers/clk/imx/clk.h
index 945671cbad..60fe36c6c6 100644
--- a/drivers/clk/imx/clk.h
+++ b/drivers/clk/imx/clk.h
@@ -7,34 +7,36 @@ struct clk *clk_gate2(const char *name, const char *parent, void __iomem *reg,
 static inline struct clk *imx_clk_divider(const char *name, const char *parent,
 		void __iomem *reg, u8 shift, u8 width)
 {
-	return clk_divider(name, parent, reg, shift, width, CLK_SET_RATE_PARENT);
+	return clk_divider(name, parent, CLK_SET_RATE_PARENT, reg, shift, width,
+			   0);
 }
 
 static inline struct clk *imx_clk_divider_flags(const char *name,
                 const char *parent, void __iomem *reg, u8 shift, u8 width,
                 unsigned long flags)
 {
-	return clk_divider(name, parent, reg, shift, width, flags);
+	return clk_divider(name, parent, flags, reg, shift, width, 0);
 }
 
 static inline struct clk *imx_clk_divider_np(const char *name, const char *parent,
 		void __iomem *reg, u8 shift, u8 width)
 {
-	return clk_divider(name, parent, reg, shift, width, 0);
+	return clk_divider(name, parent, 0, reg, shift, width, 0);
 }
 
 static inline struct clk *imx_clk_divider2(const char *name, const char *parent,
 		void __iomem *reg, u8 shift, u8 width)
 {
-	return clk_divider(name, parent, reg, shift, width, CLK_OPS_PARENT_ENABLE);
+	return clk_divider(name, parent, CLK_OPS_PARENT_ENABLE, reg, shift,
+			   width, 0);
 }
 
 static inline struct clk *imx_clk_divider_table(const char *name,
 		const char *parent, void __iomem *reg, u8 shift, u8 width,
 		const struct clk_div_table *table)
 {
-	return clk_divider_table(name, parent, reg, shift, width, table,
-			CLK_SET_RATE_PARENT);
+	return clk_divider_table(name, parent, CLK_SET_RATE_PARENT, reg, shift,
+				 width, table, 0);
 }
 
 static inline struct clk *imx_clk_fixed_factor(const char *name,
diff --git a/drivers/clk/rockchip/clk.c b/drivers/clk/rockchip/clk.c
index 3222a4e09e..35729e0cfc 100644
--- a/drivers/clk/rockchip/clk.c
+++ b/drivers/clk/rockchip/clk.c
@@ -64,7 +64,7 @@ static struct clk *rockchip_clk_register_branch(const char *name,
 	}
 
 	if (div_width > 0) {
-		div = clk_divider_alloc(name, *parent_names,
+		div = clk_divider_alloc(name, *parent_names, 0,
 		    base + muxdiv_offset, div_shift, div_width, div_flags);
 		if (!div)
 			return ERR_PTR(-ENOMEM);
@@ -188,13 +188,13 @@ void __init rockchip_clk_register_branches(
 		case branch_divider:
 			if (list->div_table)
 				clk = clk_divider_table(list->name,
-				    list->parent_names[0],
+				    list->parent_names[0], flags,
 				    reg_base + list->muxdiv_offset,
 				    list->div_shift, list->div_width,
 				    list->div_table, list->div_flags);
 			else
 				clk = clk_divider(list->name,
-				    list->parent_names[0],
+				    list->parent_names[0], flags,
 				    reg_base + list->muxdiv_offset,
 				    list->div_shift, list->div_width,
 				    list->div_flags);
diff --git a/include/linux/clk.h b/include/linux/clk.h
index 5ad12c571c..65d163c78d 100644
--- a/include/linux/clk.h
+++ b/include/linux/clk.h
@@ -352,15 +352,19 @@ unsigned long divider_recalc_rate(struct clk *clk, unsigned long parent_rate,
 		unsigned long flags, unsigned long width);
 
 struct clk *clk_divider_alloc(const char *name, const char *parent,
-		void __iomem *reg, u8 shift, u8 width, unsigned flags);
+			      unsigned clk_flags, void __iomem *reg,
+			      u8 shift, u8 width, unsigned div_flags);
 void clk_divider_free(struct clk *clk_divider);
 struct clk *clk_divider(const char *name, const char *parent,
-		void __iomem *reg, u8 shift, u8 width, unsigned flags);
+			unsigned clk_flags, void __iomem *reg, u8 shift,
+			u8 width, unsigned div_flags);
 struct clk *clk_divider_one_based(const char *name, const char *parent,
-		void __iomem *reg, u8 shift, u8 width, unsigned flags);
-struct clk *clk_divider_table(const char *name,
-		const char *parent, void __iomem *reg, u8 shift, u8 width,
-		const struct clk_div_table *table, unsigned flags);
+				  unsigned clk_flags, void __iomem *reg,
+				  u8 shift, u8 width, unsigned div_flags);
+struct clk *clk_divider_table(const char *name, const char *parent,
+			      unsigned clk_flags, void __iomem *reg, u8 shift,
+			      u8 width, const struct clk_div_table *table,
+			      unsigned div_flags);
 struct clk *clk_fixed_factor(const char *name,
 		const char *parent, unsigned int mult, unsigned int div,
 		unsigned flags);
-- 
2.20.1


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 17+ messages in thread

* [PATCH 07/14] clk: divider: Support CLK_DIVIDER_READ_ONLY flag
  2019-03-11  9:31 [PATCH 00/14] Add initial STMicroelectronics MP1 support Sascha Hauer
                   ` (5 preceding siblings ...)
  2019-03-11  9:31 ` [PATCH 06/14] clk: divider: pass divider flags Sascha Hauer
@ 2019-03-11  9:31 ` Sascha Hauer
  2019-03-11  9:31 ` [PATCH 08/14] clk: mux: Support mux specific flags Sascha Hauer
                   ` (6 subsequent siblings)
  13 siblings, 0 replies; 17+ messages in thread
From: Sascha Hauer @ 2019-03-11  9:31 UTC (permalink / raw)
  To: Barebox List

To support a readonly divider add the CLK_DIVIDER_READ_ONLY flag.

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
 drivers/clk/clk-divider.c         | 7 +++++++
 drivers/clk/rockchip/clk-rk3188.c | 1 -
 drivers/clk/rockchip/clk-rk3288.c | 1 -
 include/linux/clk.h               | 1 +
 4 files changed, 8 insertions(+), 2 deletions(-)

diff --git a/drivers/clk/clk-divider.c b/drivers/clk/clk-divider.c
index 407aae78ea..d9d3407e75 100644
--- a/drivers/clk/clk-divider.c
+++ b/drivers/clk/clk-divider.c
@@ -203,8 +203,12 @@ static int clk_divider_bestdiv(struct clk *clk, unsigned long rate,
 static long clk_divider_round_rate(struct clk *clk, unsigned long rate,
 		unsigned long *parent_rate)
 {
+	struct clk_divider *divider = container_of(clk, struct clk_divider, clk);
 	int div;
 
+	if (divider->flags & CLK_DIVIDER_READ_ONLY)
+		return clk_divider_recalc_rate(clk, *parent_rate);
+
 	div = clk_divider_bestdiv(clk, rate, parent_rate);
 
 	return *parent_rate / div;
@@ -217,6 +221,9 @@ static int clk_divider_set_rate(struct clk *clk, unsigned long rate,
 	unsigned int div, value;
 	u32 val;
 
+	if (divider->flags & CLK_DIVIDER_READ_ONLY)
+		return 0;
+
 	if (clk->flags & CLK_SET_RATE_PARENT) {
 		unsigned long best_parent_rate = parent_rate;
 		div = clk_divider_bestdiv(clk, rate, &best_parent_rate);
diff --git a/drivers/clk/rockchip/clk-rk3188.c b/drivers/clk/rockchip/clk-rk3188.c
index 7dda2963e3..8ed3a6d894 100644
--- a/drivers/clk/rockchip/clk-rk3188.c
+++ b/drivers/clk/rockchip/clk-rk3188.c
@@ -26,7 +26,6 @@
 #define RK3188_GRF_SOC_STATUS	0xac
 
 #define CLK_SET_RATE_NO_REPARENT 0
-#define CLK_DIVIDER_READ_ONLY 0
 
 enum rk3188_plls {
 	apll, cpll, dpll, gpll,
diff --git a/drivers/clk/rockchip/clk-rk3288.c b/drivers/clk/rockchip/clk-rk3288.c
index bb111e1e0b..e7cc9c1b5b 100644
--- a/drivers/clk/rockchip/clk-rk3288.c
+++ b/drivers/clk/rockchip/clk-rk3288.c
@@ -26,7 +26,6 @@
 #define RK3288_GRF_SOC_STATUS1	0x284
 
 #define CLK_SET_RATE_NO_REPARENT 0
-#define CLK_DIVIDER_READ_ONLY 0
 
 enum rk3288_plls {
 	apll, dpll, cpll, gpll, npll,
diff --git a/include/linux/clk.h b/include/linux/clk.h
index 65d163c78d..2de963e7e9 100644
--- a/include/linux/clk.h
+++ b/include/linux/clk.h
@@ -341,6 +341,7 @@ struct clk_divider {
 
 #define CLK_DIVIDER_POWER_OF_TWO	(1 << 1)
 #define CLK_DIVIDER_HIWORD_MASK		(1 << 3)
+#define CLK_DIVIDER_READ_ONLY		(1 << 5)
 
 #define CLK_MUX_HIWORD_MASK		(1 << 2)
 
-- 
2.20.1


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 17+ messages in thread

* [PATCH 08/14] clk: mux: Support mux specific flags
  2019-03-11  9:31 [PATCH 00/14] Add initial STMicroelectronics MP1 support Sascha Hauer
                   ` (6 preceding siblings ...)
  2019-03-11  9:31 ` [PATCH 07/14] clk: divider: Support CLK_DIVIDER_READ_ONLY flag Sascha Hauer
@ 2019-03-11  9:31 ` Sascha Hauer
  2019-03-11  9:31 ` [PATCH 09/14] clk: mux: Support CLK_MUX_READ_ONLY flag Sascha Hauer
                   ` (5 subsequent siblings)
  13 siblings, 0 replies; 17+ messages in thread
From: Sascha Hauer @ 2019-03-11  9:31 UTC (permalink / raw)
  To: Barebox List

We'll need mux specific flags in the future, so add a parameter to
the mux initialization functions.

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
 drivers/clk/clk-mux.c          | 15 +++++++++------
 drivers/clk/imx/clk.h          | 19 +++++++++++--------
 drivers/clk/mxs/clk.h          |  2 +-
 drivers/clk/rockchip/clk-pll.c |  3 ++-
 drivers/clk/rockchip/clk.c     | 10 +++-------
 drivers/clk/tegra/clk-periph.c |  2 +-
 include/linux/clk.h            | 14 ++++++++------
 7 files changed, 35 insertions(+), 30 deletions(-)

diff --git a/drivers/clk/clk-mux.c b/drivers/clk/clk-mux.c
index a108a72d63..ebf736bdff 100644
--- a/drivers/clk/clk-mux.c
+++ b/drivers/clk/clk-mux.c
@@ -51,18 +51,19 @@ struct clk_ops clk_mux_ops = {
 	.set_parent = clk_mux_set_parent,
 };
 
-struct clk *clk_mux_alloc(const char *name, void __iomem *reg,
+struct clk *clk_mux_alloc(const char *name, unsigned clk_flags, void __iomem *reg,
 		u8 shift, u8 width, const char * const *parents, u8 num_parents,
-		unsigned flags)
+		unsigned mux_flags)
 {
 	struct clk_mux *m = xzalloc(sizeof(*m));
 
 	m->reg = reg;
 	m->shift = shift;
 	m->width = width;
+	m->flags = mux_flags;
 	m->clk.ops = &clk_mux_ops;
 	m->clk.name = name;
-	m->clk.flags = flags;
+	m->clk.flags = clk_flags;
 	m->clk.parent_names = parents;
 	m->clk.num_parents = num_parents;
 
@@ -76,13 +77,15 @@ void clk_mux_free(struct clk *clk_mux)
 	free(m);
 }
 
-struct clk *clk_mux(const char *name, void __iomem *reg,
-		u8 shift, u8 width, const char * const *parents, u8 num_parents, unsigned flags)
+struct clk *clk_mux(const char *name, unsigned clk_flags, void __iomem *reg,
+		    u8 shift, u8 width, const char * const *parents,
+		    u8 num_parents, unsigned mux_flags)
 {
 	struct clk *m;
 	int ret;
 
-	m = clk_mux_alloc(name, reg, shift, width, parents, num_parents, flags);
+	m = clk_mux_alloc(name, clk_flags, reg, shift, width, parents,
+			  num_parents, mux_flags);
 
 	ret = clk_register(m);
 	if (ret) {
diff --git a/drivers/clk/imx/clk.h b/drivers/clk/imx/clk.h
index 60fe36c6c6..875c76a8b3 100644
--- a/drivers/clk/imx/clk.h
+++ b/drivers/clk/imx/clk.h
@@ -48,35 +48,38 @@ static inline struct clk *imx_clk_fixed_factor(const char *name,
 static inline struct clk *imx_clk_mux_flags(const char *name, void __iomem *reg,
 					    u8 shift, u8 width,
 					    const char **parents, u8 num_parents,
-					    unsigned long flags)
+					    unsigned long clk_flags)
 {
-	return clk_mux(name, reg, shift, width, parents, num_parents, flags);
+	return clk_mux(name, clk_flags, reg, shift, width, parents, num_parents,
+		       0);
 }
 
 static inline struct clk *imx_clk_mux2_flags(const char *name,
 		void __iomem *reg, u8 shift, u8 width, const char **parents,
-		int num_parents, unsigned long flags)
+		int num_parents, unsigned long clk_flags)
 {
-	return clk_mux(name, reg, shift, width, parents, num_parents,
-		       flags | CLK_OPS_PARENT_ENABLE);
+	return clk_mux(name, clk_flags | CLK_OPS_PARENT_ENABLE, reg, shift,
+		       width, parents, num_parents, 0);
 }
 
 static inline struct clk *imx_clk_mux(const char *name, void __iomem *reg,
 		u8 shift, u8 width, const char **parents, u8 num_parents)
 {
-	return clk_mux(name, reg, shift, width, parents, num_parents, 0);
+	return clk_mux(name, 0, reg, shift, width, parents, num_parents, 0);
 }
 
 static inline struct clk *imx_clk_mux2(const char *name, void __iomem *reg,
 		u8 shift, u8 width, const char **parents, u8 num_parents)
 {
-	return clk_mux(name, reg, shift, width, parents, num_parents, CLK_OPS_PARENT_ENABLE);
+	return clk_mux(name, CLK_OPS_PARENT_ENABLE, reg, shift, width, parents,
+		       num_parents, 0);
 }
 
 static inline struct clk *imx_clk_mux_p(const char *name, void __iomem *reg,
 		u8 shift, u8 width, const char **parents, u8 num_parents)
 {
-	return clk_mux(name, reg, shift, width, parents, num_parents, CLK_SET_RATE_PARENT);
+	return clk_mux(name, CLK_SET_RATE_PARENT, reg, shift, width, parents,
+		       num_parents, 0);
 }
 
 static inline struct clk *imx_clk_gate(const char *name, const char *parent,
diff --git a/drivers/clk/mxs/clk.h b/drivers/clk/mxs/clk.h
index 7bab7b5e6e..00895de507 100644
--- a/drivers/clk/mxs/clk.h
+++ b/drivers/clk/mxs/clk.h
@@ -40,7 +40,7 @@ static inline struct clk *mxs_clk_gate(const char *name,
 static inline struct clk *mxs_clk_mux(const char *name, void __iomem *reg,
 		u8 shift, u8 width, const char **parent_names, int num_parents)
 {
-	return clk_mux(name, reg, shift, width, parent_names, num_parents, 0);
+	return clk_mux(name, 0, reg, shift, width, parent_names, num_parents, 0);
 }
 
 static inline struct clk *mxs_clk_fixed_factor(const char *name,
diff --git a/drivers/clk/rockchip/clk-pll.c b/drivers/clk/rockchip/clk-pll.c
index 87a3969c28..39ccf0a226 100644
--- a/drivers/clk/rockchip/clk-pll.c
+++ b/drivers/clk/rockchip/clk-pll.c
@@ -352,7 +352,8 @@ struct clk *rockchip_clk_register_pll(enum rockchip_pll_type pll_type,
 	pll_parents[1] = pll->pll_name;
 	pll_parents[2] = parent_names[1];
 
-	pll_mux = clk_mux_alloc(name, base + mode_offset, mode_shift, PLL_MODE_MASK, pll_parents, 3, CLK_SET_RATE_PARENT);
+	pll_mux = clk_mux_alloc(name, CLK_SET_RATE_PARENT, base + mode_offset, mode_shift,
+				PLL_MODE_MASK, pll_parents, 3, 0);
 	pll->pll_mux_ops = pll_mux->ops;
 	mux_clk = pll_mux;
 
diff --git a/drivers/clk/rockchip/clk.c b/drivers/clk/rockchip/clk.c
index 35729e0cfc..9e0cbadd57 100644
--- a/drivers/clk/rockchip/clk.c
+++ b/drivers/clk/rockchip/clk.c
@@ -50,7 +50,7 @@ static struct clk *rockchip_clk_register_branch(const char *name,
 	struct clk *div = NULL;
 
 	if (num_parents > 1) {
-		mux = clk_mux_alloc(name, base + muxdiv_offset, mux_shift,
+		mux = clk_mux_alloc(name, 0, base + muxdiv_offset, mux_shift,
 		    mux_width, parent_names, num_parents, mux_flags);
 		if (!mux)
 			return ERR_PTR(-ENOMEM);
@@ -176,14 +176,10 @@ void __init rockchip_clk_register_branches(
 		/* catch simple muxes */
 		switch (list->branch_type) {
 		case branch_mux:
-			/*
-			 * mux_flags and flags are ored, this is safe,
-			 * since there is no value clash, but isn't that elegant
-			 */
-			clk = clk_mux(list->name,
+			clk = clk_mux(list->name, flags,
 			    reg_base + list->muxdiv_offset, list->mux_shift,
 			    list->mux_width, list->parent_names,
-			    list->num_parents, list->mux_flags | flags);
+			    list->num_parents, list->mux_flags);
 			break;
 		case branch_divider:
 			if (list->div_table)
diff --git a/drivers/clk/tegra/clk-periph.c b/drivers/clk/tegra/clk-periph.c
index fd1e2ed2c6..b4182861e7 100644
--- a/drivers/clk/tegra/clk-periph.c
+++ b/drivers/clk/tegra/clk-periph.c
@@ -123,7 +123,7 @@ static struct clk *_tegra_clk_register_periph(const char *name,
 		goto out_periph;
 	}
 
-	periph->mux = clk_mux_alloc(NULL, clk_base + reg_offset, 32 - mux_size,
+	periph->mux = clk_mux_alloc(NULL, 0, clk_base + reg_offset, 32 - mux_size,
 				    mux_size, parent_names, num_parents, 0);
 	if (!periph->mux)
 		goto out_mux;
diff --git a/include/linux/clk.h b/include/linux/clk.h
index 2de963e7e9..2e698e2ea6 100644
--- a/include/linux/clk.h
+++ b/include/linux/clk.h
@@ -384,19 +384,21 @@ struct clk_mux {
 	void __iomem *reg;
 	int shift;
 	int width;
+	unsigned flags;
 };
 
 #define to_clk_mux(_clk) container_of(_clk, struct clk_mux, clk)
 
 extern struct clk_ops clk_mux_ops;
 
-struct clk *clk_mux_alloc(const char *name, void __iomem *reg,
-		u8 shift, u8 width, const char * const *parents, u8 num_parents,
-		unsigned flags);
+struct clk *clk_mux_alloc(const char *name, unsigned clk_flags,
+			  void __iomem *reg, u8 shift, u8 width,
+			  const char * const *parents, u8 num_parents,
+			  unsigned mux_flags);
 void clk_mux_free(struct clk *clk_mux);
-struct clk *clk_mux(const char *name, void __iomem *reg,
-		u8 shift, u8 width, const char * const *parents, u8 num_parents,
-		unsigned flags);
+struct clk *clk_mux(const char *name, unsigned clk_flags, void __iomem *reg,
+		    u8 shift, u8 width, const char * const *parents,
+		    u8 num_parents, unsigned mux_flags);
 
 struct clk_gate {
 	struct clk clk;
-- 
2.20.1


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 17+ messages in thread

* [PATCH 09/14] clk: mux: Support CLK_MUX_READ_ONLY flag
  2019-03-11  9:31 [PATCH 00/14] Add initial STMicroelectronics MP1 support Sascha Hauer
                   ` (7 preceding siblings ...)
  2019-03-11  9:31 ` [PATCH 08/14] clk: mux: Support mux specific flags Sascha Hauer
@ 2019-03-11  9:31 ` Sascha Hauer
  2019-03-11  9:31 ` [PATCH 10/14] clk: mux: Support CLK_SET_RATE_NO_REPARENT flag Sascha Hauer
                   ` (4 subsequent siblings)
  13 siblings, 0 replies; 17+ messages in thread
From: Sascha Hauer @ 2019-03-11  9:31 UTC (permalink / raw)
  To: Barebox List

Support readonly dividers using the CLK_MUX_READ_ONLY flag.

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
 drivers/clk/clk-mux.c | 7 +++++++
 include/linux/clk.h   | 1 +
 2 files changed, 8 insertions(+)

diff --git a/drivers/clk/clk-mux.c b/drivers/clk/clk-mux.c
index ebf736bdff..e9cb614005 100644
--- a/drivers/clk/clk-mux.c
+++ b/drivers/clk/clk-mux.c
@@ -33,6 +33,13 @@ static int clk_mux_set_parent(struct clk *clk, u8 idx)
 	struct clk_mux *m = container_of(clk, struct clk_mux, clk);
 	u32 val;
 
+	if (m->flags & CLK_MUX_READ_ONLY) {
+		if (clk_mux_get_parent(clk) != idx)
+			return -EPERM;
+		else
+			return 0;
+	}
+
 	val = readl(m->reg);
 	val &= ~(((1 << m->width) - 1) << m->shift);
 	val |= idx << m->shift;
diff --git a/include/linux/clk.h b/include/linux/clk.h
index 2e698e2ea6..2492608a15 100644
--- a/include/linux/clk.h
+++ b/include/linux/clk.h
@@ -344,6 +344,7 @@ struct clk_divider {
 #define CLK_DIVIDER_READ_ONLY		(1 << 5)
 
 #define CLK_MUX_HIWORD_MASK		(1 << 2)
+#define CLK_MUX_READ_ONLY		(1 << 3) /* mux can't be changed */
 
 extern struct clk_ops clk_divider_ops;
 
-- 
2.20.1


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 17+ messages in thread

* [PATCH 10/14] clk: mux: Support CLK_SET_RATE_NO_REPARENT flag
  2019-03-11  9:31 [PATCH 00/14] Add initial STMicroelectronics MP1 support Sascha Hauer
                   ` (8 preceding siblings ...)
  2019-03-11  9:31 ` [PATCH 09/14] clk: mux: Support CLK_MUX_READ_ONLY flag Sascha Hauer
@ 2019-03-11  9:31 ` Sascha Hauer
  2019-03-11  9:31 ` [PATCH 11/14] ARM: stm32mp1: Add clk driver Sascha Hauer
                   ` (3 subsequent siblings)
  13 siblings, 0 replies; 17+ messages in thread
From: Sascha Hauer @ 2019-03-11  9:31 UTC (permalink / raw)
  To: Barebox List

Since barebox doesn't do reparenting on rate changes we only have
to define the flag.

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
 drivers/clk/rockchip/clk-rk3188.c | 2 --
 drivers/clk/rockchip/clk-rk3288.c | 2 --
 include/linux/clk.h               | 1 +
 3 files changed, 1 insertion(+), 4 deletions(-)

diff --git a/drivers/clk/rockchip/clk-rk3188.c b/drivers/clk/rockchip/clk-rk3188.c
index 8ed3a6d894..9340739945 100644
--- a/drivers/clk/rockchip/clk-rk3188.c
+++ b/drivers/clk/rockchip/clk-rk3188.c
@@ -25,8 +25,6 @@
 #define RK3066_GRF_SOC_STATUS	0x15c
 #define RK3188_GRF_SOC_STATUS	0xac
 
-#define CLK_SET_RATE_NO_REPARENT 0
-
 enum rk3188_plls {
 	apll, cpll, dpll, gpll,
 };
diff --git a/drivers/clk/rockchip/clk-rk3288.c b/drivers/clk/rockchip/clk-rk3288.c
index e7cc9c1b5b..dcfaae2407 100644
--- a/drivers/clk/rockchip/clk-rk3288.c
+++ b/drivers/clk/rockchip/clk-rk3288.c
@@ -25,8 +25,6 @@
 #define RK3288_GRF_SOC_CON(x)	(0x244 + x * 4)
 #define RK3288_GRF_SOC_STATUS1	0x284
 
-#define CLK_SET_RATE_NO_REPARENT 0
-
 enum rk3288_plls {
 	apll, dpll, cpll, gpll, npll,
 };
diff --git a/include/linux/clk.h b/include/linux/clk.h
index 2492608a15..b9c5e0ab04 100644
--- a/include/linux/clk.h
+++ b/include/linux/clk.h
@@ -286,6 +286,7 @@ static inline void clk_put(struct clk *clk)
 
 #define CLK_SET_RATE_PARENT     (1 << 0) /* propagate rate change up one level */
 #define CLK_IGNORE_UNUSED       (1 << 3) /* do not gate even if unused */
+#define CLK_SET_RATE_NO_REPARENT (1 << 7) /* don't re-parent on rate change */
 #define CLK_IS_CRITICAL         (1 << 11) /* do not gate, ever */
 /* parents need enable during gate/ungate, set rate and re-parent */
 #define CLK_OPS_PARENT_ENABLE   (1 << 12)
-- 
2.20.1


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 17+ messages in thread

* [PATCH 11/14] ARM: stm32mp1: Add clk driver
  2019-03-11  9:31 [PATCH 00/14] Add initial STMicroelectronics MP1 support Sascha Hauer
                   ` (9 preceding siblings ...)
  2019-03-11  9:31 ` [PATCH 10/14] clk: mux: Support CLK_SET_RATE_NO_REPARENT flag Sascha Hauer
@ 2019-03-11  9:31 ` Sascha Hauer
  2019-03-11  9:31 ` [PATCH 12/14] ARM: stm32mp1: Add serial driver Sascha Hauer
                   ` (2 subsequent siblings)
  13 siblings, 0 replies; 17+ messages in thread
From: Sascha Hauer @ 2019-03-11  9:31 UTC (permalink / raw)
  To: Barebox List

Taken from Linux v5.0-rc2. Mostly as-is, only adopted to the differences
between the Linux and barebox clk API.

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
 drivers/clk/Makefile       |    1 +
 drivers/clk/clk-stm32mp1.c | 1988 ++++++++++++++++++++++++++++++++++++
 2 files changed, 1989 insertions(+)
 create mode 100644 drivers/clk/clk-stm32mp1.c

diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile
index 34c44fff9b..5bf76a4535 100644
--- a/drivers/clk/Makefile
+++ b/drivers/clk/Makefile
@@ -14,4 +14,5 @@ obj-$(CONFIG_SOC_QCA_AR9331)	+= clk-ar933x.o
 obj-$(CONFIG_SOC_QCA_AR9344)	+= clk-ar9344.o
 obj-$(CONFIG_ARCH_IMX)		+= imx/
 obj-$(CONFIG_COMMON_CLK_AT91)	+= at91/
+obj-$(CONFIG_ARCH_STM32MP)	+= clk-stm32mp1.o
 obj-$(CONFIG_MACH_VEXPRESS)	+= vexpress/
diff --git a/drivers/clk/clk-stm32mp1.c b/drivers/clk/clk-stm32mp1.c
new file mode 100644
index 0000000000..6016c5bfd0
--- /dev/null
+++ b/drivers/clk/clk-stm32mp1.c
@@ -0,0 +1,1988 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) STMicroelectronics 2018 - All Rights Reserved
+ * Author: Olivier Bideau <olivier.bideau@st.com> for STMicroelectronics.
+ * Author: Gabriel Fernandez <gabriel.fernandez@st.com> for STMicroelectronics.
+ */
+
+#include <linux/clk.h>
+#include <linux/err.h>
+#include <io.h>
+#include <of.h>
+#include <of_address.h>
+#include <asm-generic/div64.h>
+
+#include <dt-bindings/clock/stm32mp1-clks.h>
+
+#define RCC_OCENSETR		0x0C
+#define RCC_HSICFGR		0x18
+#define RCC_RDLSICR		0x144
+#define RCC_PLL1CR		0x80
+#define RCC_PLL1CFGR1		0x84
+#define RCC_PLL1CFGR2		0x88
+#define RCC_PLL2CR		0x94
+#define RCC_PLL2CFGR1		0x98
+#define RCC_PLL2CFGR2		0x9C
+#define RCC_PLL3CR		0x880
+#define RCC_PLL3CFGR1		0x884
+#define RCC_PLL3CFGR2		0x888
+#define RCC_PLL4CR		0x894
+#define RCC_PLL4CFGR1		0x898
+#define RCC_PLL4CFGR2		0x89C
+#define RCC_APB1ENSETR		0xA00
+#define RCC_APB2ENSETR		0xA08
+#define RCC_APB3ENSETR		0xA10
+#define RCC_APB4ENSETR		0x200
+#define RCC_APB5ENSETR		0x208
+#define RCC_AHB2ENSETR		0xA18
+#define RCC_AHB3ENSETR		0xA20
+#define RCC_AHB4ENSETR		0xA28
+#define RCC_AHB5ENSETR		0x210
+#define RCC_AHB6ENSETR		0x218
+#define RCC_AHB6LPENSETR	0x318
+#define RCC_RCK12SELR		0x28
+#define RCC_RCK3SELR		0x820
+#define RCC_RCK4SELR		0x824
+#define RCC_MPCKSELR		0x20
+#define RCC_ASSCKSELR		0x24
+#define RCC_MSSCKSELR		0x48
+#define RCC_SPI6CKSELR		0xC4
+#define RCC_SDMMC12CKSELR	0x8F4
+#define RCC_SDMMC3CKSELR	0x8F8
+#define RCC_FMCCKSELR		0x904
+#define RCC_I2C46CKSELR		0xC0
+#define RCC_I2C12CKSELR		0x8C0
+#define RCC_I2C35CKSELR		0x8C4
+#define RCC_UART1CKSELR		0xC8
+#define RCC_QSPICKSELR		0x900
+#define RCC_ETHCKSELR		0x8FC
+#define RCC_RNG1CKSELR		0xCC
+#define RCC_RNG2CKSELR		0x920
+#define RCC_GPUCKSELR		0x938
+#define RCC_USBCKSELR		0x91C
+#define RCC_STGENCKSELR		0xD4
+#define RCC_SPDIFCKSELR		0x914
+#define RCC_SPI2S1CKSELR	0x8D8
+#define RCC_SPI2S23CKSELR	0x8DC
+#define RCC_SPI2S45CKSELR	0x8E0
+#define RCC_CECCKSELR		0x918
+#define RCC_LPTIM1CKSELR	0x934
+#define RCC_LPTIM23CKSELR	0x930
+#define RCC_LPTIM45CKSELR	0x92C
+#define RCC_UART24CKSELR	0x8E8
+#define RCC_UART35CKSELR	0x8EC
+#define RCC_UART6CKSELR		0x8E4
+#define RCC_UART78CKSELR	0x8F0
+#define RCC_FDCANCKSELR		0x90C
+#define RCC_SAI1CKSELR		0x8C8
+#define RCC_SAI2CKSELR		0x8CC
+#define RCC_SAI3CKSELR		0x8D0
+#define RCC_SAI4CKSELR		0x8D4
+#define RCC_ADCCKSELR		0x928
+#define RCC_MPCKDIVR		0x2C
+#define RCC_DSICKSELR		0x924
+#define RCC_CPERCKSELR		0xD0
+#define RCC_MCO1CFGR		0x800
+#define RCC_MCO2CFGR		0x804
+#define RCC_BDCR		0x140
+#define RCC_AXIDIVR		0x30
+#define RCC_MCUDIVR		0x830
+#define RCC_APB1DIVR		0x834
+#define RCC_APB2DIVR		0x838
+#define RCC_APB3DIVR		0x83C
+#define RCC_APB4DIVR		0x3C
+#define RCC_APB5DIVR		0x40
+#define RCC_TIMG1PRER		0x828
+#define RCC_TIMG2PRER		0x82C
+#define RCC_RTCDIVR		0x44
+#define RCC_DBGCFGR		0x80C
+
+#define RCC_CLR	0x4
+
+static const char * const ref12_parents[] = {
+	"ck_hsi", "ck_hse"
+};
+
+static const char * const ref3_parents[] = {
+	"ck_hsi", "ck_hse", "ck_csi"
+};
+
+static const char * const ref4_parents[] = {
+	"ck_hsi", "ck_hse", "ck_csi"
+};
+
+static const char * const cpu_src[] = {
+	"ck_hsi", "ck_hse", "pll1_p"
+};
+
+static const char * const axi_src[] = {
+	"ck_hsi", "ck_hse", "pll2_p", "pll3_p"
+};
+
+static const char * const per_src[] = {
+	"ck_hsi", "ck_csi", "ck_hse"
+};
+
+static const char * const mcu_src[] = {
+	"ck_hsi", "ck_hse", "ck_csi", "pll3_p"
+};
+
+static const char * const sdmmc12_src[] = {
+	"ck_axi", "pll3_r", "pll4_p", "ck_hsi"
+};
+
+static const char * const sdmmc3_src[] = {
+	"ck_mcu", "pll3_r", "pll4_p", "ck_hsi"
+};
+
+static const char * const fmc_src[] = {
+	"ck_axi", "pll3_r", "pll4_p", "ck_per"
+};
+
+static const char * const qspi_src[] = {
+	"ck_axi", "pll3_r", "pll4_p", "ck_per"
+};
+
+static const char * const eth_src[] = {
+	"pll4_p", "pll3_q"
+};
+
+static const char * const rng_src[] = {
+	"ck_csi", "pll4_r", "ck_lse", "ck_lsi"
+};
+
+static const char * const usbphy_src[] = {
+	"ck_hse", "pll4_r", "clk-hse-div2"
+};
+
+static const char * const usbo_src[] = {
+	"pll4_r", "ck_usbo_48m"
+};
+
+static const char * const stgen_src[] = {
+	"ck_hsi", "ck_hse"
+};
+
+static const char * const spdif_src[] = {
+	"pll4_p", "pll3_q", "ck_hsi"
+};
+
+static const char * const spi123_src[] = {
+	"pll4_p", "pll3_q", "i2s_ckin", "ck_per", "pll3_r"
+};
+
+static const char * const spi45_src[] = {
+	"pclk2", "pll4_q", "ck_hsi", "ck_csi", "ck_hse"
+};
+
+static const char * const spi6_src[] = {
+	"pclk5", "pll4_q", "ck_hsi", "ck_csi", "ck_hse", "pll3_q"
+};
+
+static const char * const cec_src[] = {
+	"ck_lse", "ck_lsi", "ck_csi"
+};
+
+static const char * const i2c12_src[] = {
+	"pclk1", "pll4_r", "ck_hsi", "ck_csi"
+};
+
+static const char * const i2c35_src[] = {
+	"pclk1", "pll4_r", "ck_hsi", "ck_csi"
+};
+
+static const char * const i2c46_src[] = {
+	"pclk5", "pll3_q", "ck_hsi", "ck_csi"
+};
+
+static const char * const lptim1_src[] = {
+	"pclk1", "pll4_p", "pll3_q", "ck_lse", "ck_lsi", "ck_per"
+};
+
+static const char * const lptim23_src[] = {
+	"pclk3", "pll4_q", "ck_per", "ck_lse", "ck_lsi"
+};
+
+static const char * const lptim45_src[] = {
+	"pclk3", "pll4_p", "pll3_q", "ck_lse", "ck_lsi", "ck_per"
+};
+
+static const char * const usart1_src[] = {
+	"pclk5", "pll3_q", "ck_hsi", "ck_csi", "pll4_q", "ck_hse"
+};
+
+static const char * const usart234578_src[] = {
+	"pclk1", "pll4_q", "ck_hsi", "ck_csi", "ck_hse"
+};
+
+static const char * const usart6_src[] = {
+	"pclk2", "pll4_q", "ck_hsi", "ck_csi", "ck_hse"
+};
+
+static const char * const fdcan_src[] = {
+	"ck_hse", "pll3_q", "pll4_q"
+};
+
+static const char * const sai_src[] = {
+	"pll4_q", "pll3_q", "i2s_ckin", "ck_per"
+};
+
+static const char * const sai2_src[] = {
+	"pll4_q", "pll3_q", "i2s_ckin", "ck_per", "spdif_ck_symb"
+};
+
+static const char * const adc12_src[] = {
+	"pll4_q", "ck_per"
+};
+
+static const char * const dsi_src[] = {
+	"ck_dsi_phy", "pll4_p"
+};
+
+static const char * const rtc_src[] = {
+	"off", "ck_lse", "ck_lsi", "ck_hse_rtc"
+};
+
+static const char * const mco1_src[] = {
+	"ck_hsi", "ck_hse", "ck_csi", "ck_lsi", "ck_lse"
+};
+
+static const char * const mco2_src[] = {
+	"ck_mpu", "ck_axi", "ck_mcu", "pll4_p", "ck_hse", "ck_hsi"
+};
+
+static const char * const ck_trace_src[] = {
+	"ck_axi"
+};
+
+static const struct clk_div_table axi_div_table[] = {
+	{ 0, 1 }, { 1, 2 }, { 2, 3 }, { 3, 4 },
+	{ 4, 4 }, { 5, 4 }, { 6, 4 }, { 7, 4 },
+	{ 0 },
+};
+
+static const struct clk_div_table mcu_div_table[] = {
+	{ 0, 1 }, { 1, 2 }, { 2, 4 }, { 3, 8 },
+	{ 4, 16 }, { 5, 32 }, { 6, 64 }, { 7, 128 },
+	{ 8, 512 }, { 9, 512 }, { 10, 512}, { 11, 512 },
+	{ 12, 512 }, { 13, 512 }, { 14, 512}, { 15, 512 },
+	{ 0 },
+};
+
+static const struct clk_div_table apb_div_table[] = {
+	{ 0, 1 }, { 1, 2 }, { 2, 4 }, { 3, 8 },
+	{ 4, 16 }, { 5, 16 }, { 6, 16 }, { 7, 16 },
+	{ 0 },
+};
+
+static const struct clk_div_table ck_trace_div_table[] = {
+	{ 0, 1 }, { 1, 2 }, { 2, 4 }, { 3, 8 },
+	{ 4, 16 }, { 5, 16 }, { 6, 16 }, { 7, 16 },
+	{ 0 },
+};
+
+#define MAX_MUX_CLK 2
+
+struct stm32_mmux {
+	u8 nbr_clk;
+	struct clk *hws[MAX_MUX_CLK];
+};
+
+struct stm32_clk_mmux {
+	struct clk_mux mux;
+	struct stm32_mmux *mmux;
+};
+
+struct stm32_mgate {
+	u8 nbr_clk;
+	u32 flag;
+};
+
+struct stm32_clk_mgate {
+	struct clk_gate gate;
+	struct stm32_mgate *mgate;
+	u32 mask;
+};
+
+struct clock_config {
+	u32 id;
+	const char *name;
+	const char *parent_name;
+	const char * const *parent_names;
+	int num_parents;
+	unsigned long flags;
+	void *cfg;
+	struct clk * (*func)(void __iomem *base, const struct clock_config *cfg);
+};
+
+#define NO_ID ~0
+
+struct gate_cfg {
+	u32 reg_off;
+	u8 bit_idx;
+	u8 gate_flags;
+};
+
+struct fixed_factor_cfg {
+	unsigned int mult;
+	unsigned int div;
+};
+
+struct div_cfg {
+	u32 reg_off;
+	u8 shift;
+	u8 width;
+	u8 div_flags;
+	const struct clk_div_table *table;
+};
+
+struct mux_cfg {
+	u32 reg_off;
+	u8 shift;
+	u8 width;
+	u8 mux_flags;
+	u32 *table;
+};
+
+struct stm32_gate_cfg {
+	struct gate_cfg		*gate;
+	struct stm32_mgate	*mgate;
+	const struct clk_ops	*ops;
+};
+
+struct stm32_div_cfg {
+	struct div_cfg		*div;
+	const struct clk_ops	*ops;
+};
+
+struct stm32_mux_cfg {
+	struct mux_cfg		*mux;
+	struct stm32_mmux	*mmux;
+	const struct clk_ops	*ops;
+};
+
+/* STM32 Composite clock */
+struct stm32_composite_cfg {
+	const struct stm32_gate_cfg	*gate;
+	const struct stm32_div_cfg	*div;
+	const struct stm32_mux_cfg	*mux;
+};
+
+static struct clk *
+_clk_hw_register_gate(void __iomem *base,
+		      const struct clock_config *cfg)
+{
+	struct gate_cfg *gate_cfg = cfg->cfg;
+
+	return clk_gate(cfg->name, cfg->parent_name, gate_cfg->reg_off + base,
+			gate_cfg->bit_idx, cfg->flags, gate_cfg->gate_flags);
+}
+
+static struct clk *
+_clk_hw_register_fixed_factor(void __iomem *base,
+			      const struct clock_config *cfg)
+{
+	struct fixed_factor_cfg *ff_cfg = cfg->cfg;
+
+	return clk_fixed_factor(cfg->name, cfg->parent_name, ff_cfg->mult,
+				ff_cfg->div, cfg->flags);
+}
+
+static struct clk *
+_clk_hw_register_divider_table(void __iomem *base,
+			       const struct clock_config *cfg)
+{
+
+	struct div_cfg *div_cfg = cfg->cfg;
+
+	if (div_cfg->table)
+		return clk_divider_table(cfg->name, cfg->parent_name, cfg->flags,
+					 div_cfg->reg_off + base, div_cfg->shift,
+					 div_cfg->width, div_cfg->table,
+					 div_cfg->div_flags);
+	else
+		return clk_divider(cfg->name, cfg->parent_name, cfg->flags,
+				   div_cfg->reg_off + base, div_cfg->shift,
+		     div_cfg->width, div_cfg->div_flags);
+}
+
+static struct clk *
+_clk_hw_register_mux(void __iomem *base,
+		     const struct clock_config *cfg)
+{
+	struct mux_cfg *mux_cfg = cfg->cfg;
+
+	return clk_mux(cfg->name,cfg->flags, mux_cfg->reg_off + base, mux_cfg->shift,
+		       mux_cfg->width, cfg->parent_names, cfg->num_parents,
+		       mux_cfg->mux_flags);
+}
+
+/* MP1 Gate clock with set & clear registers */
+
+static int mp1_gate_clk_enable(struct clk *clk)
+{
+	if (!clk_gate_ops.is_enabled(clk))
+		clk_gate_ops.enable(clk);
+
+	return 0;
+}
+
+static void mp1_gate_clk_disable(struct clk *clk)
+{
+	struct clk_gate *gate = to_clk_gate(clk);
+
+	if (clk_gate_ops.is_enabled(clk)) {
+		writel(BIT(gate->shift), gate->reg + RCC_CLR);
+	}
+}
+
+static const struct clk_ops mp1_gate_clk_ops = {
+	.enable		= mp1_gate_clk_enable,
+	.disable	= mp1_gate_clk_disable,
+	.is_enabled	= clk_gate_is_enabled,
+};
+
+static struct clk *_get_stm32_mux(void __iomem *base,
+				     const struct stm32_mux_cfg *cfg)
+{
+	struct stm32_clk_mmux *mmux;
+	struct clk_mux *mux;
+	struct clk *mux_hw;
+
+	if (cfg->mmux) {
+		mmux = kzalloc(sizeof(*mmux), GFP_KERNEL);
+		if (!mmux)
+			return ERR_PTR(-ENOMEM);
+
+		mmux->mux.reg = cfg->mux->reg_off + base;
+		mmux->mux.shift = cfg->mux->shift;
+		mmux->mux.width = cfg->mux->width;
+		mmux->mmux = cfg->mmux;
+		mux_hw = &mmux->mux.clk;
+		cfg->mmux->hws[cfg->mmux->nbr_clk++] = mux_hw;
+		mux = &mmux->mux;
+	} else {
+		mux = kzalloc(sizeof(*mux), GFP_KERNEL);
+		if (!mux)
+			return ERR_PTR(-ENOMEM);
+
+		mux->reg = cfg->mux->reg_off + base;
+		mux->shift = cfg->mux->shift;
+		mux->width = cfg->mux->width;
+		mux_hw = &mux->clk;
+	}
+
+	if (cfg->ops)
+		mux->clk.ops = cfg->ops;
+	else
+		mux->clk.ops = &clk_mux_ops;
+
+	return mux_hw;
+}
+
+static struct clk *_get_stm32_div(void __iomem *base,
+				     const struct stm32_div_cfg *cfg)
+{
+	struct clk_divider *div;
+
+	div = kzalloc(sizeof(*div), GFP_KERNEL);
+	if (!div)
+		return ERR_PTR(-ENOMEM);
+
+	div->reg = cfg->div->reg_off + base;
+	div->shift = cfg->div->shift;
+	div->width = cfg->div->width;
+	div->flags = cfg->div->div_flags;
+	div->table = cfg->div->table;
+
+	if (cfg->ops)
+		div->clk.ops = cfg->ops;
+	else
+		div->clk.ops = &clk_divider_ops;
+
+	return &div->clk;
+}
+
+static struct clk_gate *
+_get_stm32_gate(void __iomem *base,
+		const struct stm32_gate_cfg *cfg)
+{
+	struct stm32_clk_mgate *mgate;
+	struct clk_gate *gate;
+
+	if (cfg->mgate) {
+		mgate = kzalloc(sizeof(*mgate), GFP_KERNEL);
+		if (!mgate)
+			return ERR_PTR(-ENOMEM);
+
+		mgate->gate.reg = cfg->gate->reg_off + base;
+		mgate->gate.shift = cfg->gate->bit_idx;
+		mgate->gate.flags = cfg->gate->gate_flags;
+		mgate->mask = BIT(cfg->mgate->nbr_clk++);
+
+		mgate->mgate = cfg->mgate;
+
+		gate = &mgate->gate;
+
+	} else {
+		gate = kzalloc(sizeof(*gate), GFP_KERNEL);
+		if (!gate)
+			return ERR_PTR(-ENOMEM);
+
+		gate->reg = cfg->gate->reg_off + base;
+		gate->shift = cfg->gate->bit_idx;
+		gate->flags = cfg->gate->gate_flags;
+	}
+	
+	if (cfg->ops)
+		gate->clk.ops = cfg->ops;
+	else
+		gate->clk.ops = &clk_gate_ops;
+
+	return gate;
+}
+
+static struct clk *
+clk_stm32_register_gate_ops(const char *name,
+			    const char *parent_name,
+			    unsigned long flags,
+			    void __iomem *base,
+			    const struct stm32_gate_cfg *cfg)
+{
+	struct clk *clk;
+	struct clk_gate *gate;
+	int ret;
+
+	gate = _get_stm32_gate(base, cfg);
+	if (IS_ERR(gate))
+		return ERR_PTR(-ENOMEM);
+
+	gate->parent = parent_name;
+	clk = &gate->clk;
+	clk->name = name;
+	clk->parent_names = &gate->parent;
+	clk->num_parents = 1;
+	clk->flags = flags;
+
+	ret = clk_register(clk);
+	if (ret)
+		clk = ERR_PTR(ret);
+
+	return clk;
+}
+
+static struct clk *
+clk_stm32_register_composite(const char *name, const char * const *parent_names,
+			     int num_parents, void __iomem *base,
+			     const struct stm32_composite_cfg *cfg,
+			     unsigned long flags)
+{
+	struct clk *mux_hw, *div_hw, *gate_hw;
+	struct clk_gate *gate;
+
+	mux_hw = NULL;
+	div_hw = NULL;
+	gate_hw = NULL;
+
+	if (cfg->mux)
+		mux_hw = _get_stm32_mux(base, cfg->mux);
+
+	if (cfg->div)
+		div_hw = _get_stm32_div(base, cfg->div);
+
+	if (cfg->gate) {
+		gate = _get_stm32_gate(base, cfg->gate);
+		gate_hw = &gate->clk;
+	}
+
+	return clk_register_composite(name, parent_names, num_parents,
+				       mux_hw, div_hw, gate_hw, flags);
+}
+
+#define to_clk_mgate(_gate) container_of(_gate, struct stm32_clk_mgate, gate)
+
+static int mp1_mgate_clk_enable(struct clk *clk)
+{
+	struct clk_gate *gate = to_clk_gate(clk);
+	struct stm32_clk_mgate *clk_mgate = to_clk_mgate(gate);
+
+	clk_mgate->mgate->flag |= clk_mgate->mask;
+
+	mp1_gate_clk_enable(clk);
+
+	return  0;
+}
+
+static void mp1_mgate_clk_disable(struct clk *clk)
+{
+	struct clk_gate *gate = to_clk_gate(clk);
+	struct stm32_clk_mgate *clk_mgate = to_clk_mgate(gate);
+
+	clk_mgate->mgate->flag &= ~clk_mgate->mask;
+
+	if (clk_mgate->mgate->flag == 0)
+		mp1_gate_clk_disable(clk);
+}
+
+static const struct clk_ops mp1_mgate_clk_ops = {
+	.enable		= mp1_mgate_clk_enable,
+	.disable	= mp1_mgate_clk_disable,
+	.is_enabled	= clk_gate_is_enabled,
+
+};
+
+#define to_clk_mmux(_mux) container_of(_mux, struct stm32_clk_mmux, mux)
+
+static int clk_mmux_get_parent(struct clk *clk)
+{
+	return clk_mux_ops.get_parent(clk);
+}
+
+static int clk_mmux_set_parent(struct clk *clk, u8 index)
+{
+	struct clk_mux *mux = to_clk_mux(clk);
+	struct stm32_clk_mmux *clk_mmux = to_clk_mmux(mux);
+	struct clk *parent;
+	int ret, n;
+
+	ret = clk_mux_ops.set_parent(clk, index);
+	if (ret)
+		return ret;
+
+	parent = clk_get_parent(clk);
+
+	for (n = 0; n < clk_mmux->mmux->nbr_clk; n++)
+		clk_set_parent(clk_mmux->mmux->hws[n], parent);
+
+	return 0;
+}
+
+static const struct clk_ops clk_mmux_ops = {
+	.get_parent	= clk_mmux_get_parent,
+	.set_parent	= clk_mmux_set_parent,
+};
+
+/* STM32 PLL */
+struct stm32_pll_obj {
+	void __iomem *reg;
+	const char *parent;
+	struct clk clk;
+};
+
+#define to_pll(clk) container_of(clk, struct stm32_pll_obj, clk)
+
+#define PLL_ON		BIT(0)
+#define PLL_RDY		BIT(1)
+#define DIVN_MASK	0x1FF
+#define DIVM_MASK	0x3F
+#define DIVM_SHIFT	16
+#define DIVN_SHIFT	0
+#define FRAC_OFFSET	0xC
+#define FRAC_MASK	0x1FFF
+#define FRAC_SHIFT	3
+#define FRACLE		BIT(16)
+
+static int __pll_is_enabled(struct clk *clk)
+{
+	struct stm32_pll_obj *clk_elem = to_pll(clk);
+
+	return readl(clk_elem->reg) & PLL_ON;
+}
+
+#define TIMEOUT 5
+
+static int pll_enable(struct clk *clk)
+{
+	struct stm32_pll_obj *clk_elem = to_pll(clk);
+	u32 reg;
+	unsigned int timeout = TIMEOUT;
+	int bit_status = 0;
+
+	if (__pll_is_enabled(clk))
+		goto unlock;
+
+	reg = readl(clk_elem->reg);
+	reg |= PLL_ON;
+	writel(reg, clk_elem->reg);
+
+	/* We can't use readl_poll_timeout() because we can be blocked if
+	 * someone enables this clock before clocksource changes.
+	 * Only jiffies counter is available. Jiffies are incremented by
+	 * interruptions and enable op does not allow to be interrupted.
+	 */
+	do {
+		bit_status = !(readl(clk_elem->reg) & PLL_RDY);
+
+		if (bit_status)
+			udelay(120);
+
+	} while (bit_status && --timeout);
+
+unlock:
+	return bit_status;
+}
+
+static void pll_disable(struct clk *clk)
+{
+	struct stm32_pll_obj *clk_elem = to_pll(clk);
+	u32 reg;
+
+	reg = readl(clk_elem->reg);
+	reg &= ~PLL_ON;
+	writel(reg, clk_elem->reg);
+}
+
+static u32 pll_frac_val(struct clk *clk)
+{
+	struct stm32_pll_obj *clk_elem = to_pll(clk);
+	u32 reg, frac = 0;
+
+	reg = readl(clk_elem->reg + FRAC_OFFSET);
+	if (reg & FRACLE)
+		frac = (reg >> FRAC_SHIFT) & FRAC_MASK;
+
+	return frac;
+}
+
+static unsigned long pll_recalc_rate(struct clk *clk,
+				     unsigned long parent_rate)
+{
+	struct stm32_pll_obj *clk_elem = to_pll(clk);
+	u32 reg;
+	u32 frac, divm, divn;
+	u64 rate, rate_frac = 0;
+
+	reg = readl(clk_elem->reg + 4);
+
+	divm = ((reg >> DIVM_SHIFT) & DIVM_MASK) + 1;
+	divn = ((reg >> DIVN_SHIFT) & DIVN_MASK) + 1;
+	rate = (u64)parent_rate * divn;
+
+	do_div(rate, divm);
+
+	frac = pll_frac_val(clk);
+	if (frac) {
+		rate_frac = (u64)parent_rate * (u64)frac;
+		do_div(rate_frac, (divm * 8192));
+	}
+
+	return rate + rate_frac;
+}
+
+static int pll_is_enabled(struct clk *clk)
+{
+	int ret;
+
+	ret = __pll_is_enabled(clk);
+
+	return ret;
+}
+
+static const struct clk_ops pll_ops = {
+	.enable		= pll_enable,
+	.disable	= pll_disable,
+	.recalc_rate	= pll_recalc_rate,
+	.is_enabled	= pll_is_enabled,
+};
+
+static struct clk *clk_register_pll(const char *name,
+				    const char *parent_name,
+				    void __iomem *reg,
+				    unsigned long flags)
+{
+	struct stm32_pll_obj *element;
+	struct clk *clk;
+	int err;
+
+	element = kzalloc(sizeof(*element), GFP_KERNEL);
+	if (!element)
+		return ERR_PTR(-ENOMEM);
+
+	element->parent = parent_name;
+
+	clk = &element->clk;
+
+	clk->name = name;
+	clk->ops = &pll_ops;
+	clk->flags = flags;
+	clk->parent_names = &element->parent;
+	clk->num_parents = 1;
+
+	element->reg = reg;
+
+	err = clk_register(clk);
+
+	if (err) {
+		kfree(element);
+		return ERR_PTR(err);
+	}
+
+	return clk;
+}
+
+/* Kernel Timer */
+struct timer_cker {
+	void __iomem *apbdiv;
+	void __iomem *timpre;
+	const char *parent;
+	struct clk clk;
+};
+
+#define to_timer_cker(_hw) container_of(_hw, struct timer_cker, clk)
+
+#define APB_DIV_MASK 0x07
+#define TIM_PRE_MASK 0x01
+
+static unsigned long __bestmult(struct clk *clk, unsigned long rate,
+				unsigned long parent_rate)
+{
+	struct timer_cker *tim_ker = to_timer_cker(clk);
+	u32 prescaler;
+	unsigned int mult = 0;
+
+	prescaler = readl(tim_ker->apbdiv) & APB_DIV_MASK;
+	if (prescaler < 2)
+		return 1;
+
+	mult = 2;
+
+	if (rate / parent_rate >= 4)
+		mult = 4;
+
+	return mult;
+}
+
+static long timer_ker_round_rate(struct clk *clk, unsigned long rate,
+				 unsigned long *parent_rate)
+{
+	unsigned long factor = __bestmult(clk, rate, *parent_rate);
+
+	return *parent_rate * factor;
+}
+
+static int timer_ker_set_rate(struct clk *clk, unsigned long rate,
+			      unsigned long parent_rate)
+{
+	struct timer_cker *tim_ker = to_timer_cker(clk);
+	unsigned long factor = __bestmult(clk, rate, parent_rate);
+	int ret = 0;
+
+	switch (factor) {
+	case 1:
+		break;
+	case 2:
+		writel(0, tim_ker->timpre);
+		break;
+	case 4:
+		writel(1, tim_ker->timpre);
+		break;
+	default:
+		ret = -EINVAL;
+	}
+
+	return ret;
+}
+
+static unsigned long timer_ker_recalc_rate(struct clk *hw,
+					   unsigned long parent_rate)
+{
+	struct timer_cker *tim_ker = to_timer_cker(hw);
+	u32 prescaler, timpre;
+	u32 mul;
+
+	prescaler = readl(tim_ker->apbdiv) & APB_DIV_MASK;
+
+	timpre = readl(tim_ker->timpre) & TIM_PRE_MASK;
+
+	if (!prescaler)
+		return parent_rate;
+
+	mul = (timpre + 1) * 2;
+
+	return parent_rate * mul;
+}
+
+static const struct clk_ops timer_ker_ops = {
+	.recalc_rate	= timer_ker_recalc_rate,
+	.round_rate	= timer_ker_round_rate,
+	.set_rate	= timer_ker_set_rate,
+
+};
+
+static struct clk *clk_register_cktim(const char *name,
+					 const char *parent_name,
+					 unsigned long flags,
+					 void __iomem *apbdiv,
+					 void __iomem *timpre)
+{
+	struct timer_cker *tim_ker;
+	struct clk *clk;
+	int err;
+
+	tim_ker = kzalloc(sizeof(*tim_ker), GFP_KERNEL);
+	if (!tim_ker)
+		return ERR_PTR(-ENOMEM);
+
+	clk = &tim_ker->clk;
+	tim_ker->parent = parent_name;
+	clk->name = name;
+	clk->parent_names = &tim_ker->parent;
+	clk->num_parents = 1;
+	clk->ops = &timer_ker_ops;
+	clk->flags = flags;
+
+	tim_ker->apbdiv = apbdiv;
+	tim_ker->timpre = timpre;
+
+	err = clk_register(clk);
+	if (err) {
+		kfree(tim_ker);
+		return ERR_PTR(err);
+	}
+
+	return clk;
+}
+
+struct stm32_pll_cfg {
+	u32 offset;
+};
+
+static struct clk *_clk_register_pll(void __iomem *base,
+				     const struct clock_config *cfg)
+{
+	struct stm32_pll_cfg *stm_pll_cfg = cfg->cfg;
+
+	return clk_register_pll(cfg->name, cfg->parent_name,
+				base + stm_pll_cfg->offset, cfg->flags);
+}
+
+struct stm32_cktim_cfg {
+	u32 offset_apbdiv;
+	u32 offset_timpre;
+};
+
+static struct clk *_clk_register_cktim(void __iomem *base,
+				       const struct clock_config *cfg)
+{
+	struct stm32_cktim_cfg *cktim_cfg = cfg->cfg;
+
+	return clk_register_cktim(cfg->name, cfg->parent_name, cfg->flags,
+				  cktim_cfg->offset_apbdiv + base,
+				  cktim_cfg->offset_timpre + base);
+}
+
+static struct clk *
+_clk_stm32_register_gate(void __iomem *base,
+			 const struct clock_config *cfg)
+{
+	return clk_stm32_register_gate_ops(cfg->name, cfg->parent_name,
+					   cfg->flags, base, cfg->cfg);
+}
+
+static struct clk *
+_clk_stm32_register_composite(void __iomem *base,
+			      const struct clock_config *cfg)
+{
+	return clk_stm32_register_composite(cfg->name, cfg->parent_names,
+					    cfg->num_parents, base, cfg->cfg,
+					    cfg->flags);
+}
+
+#define GATE(_id, _name, _parent, _flags, _offset, _bit_idx, _gate_flags)\
+{\
+	.id		= _id,\
+	.name		= _name,\
+	.parent_name	= _parent,\
+	.flags		= _flags,\
+	.cfg		=  &(struct gate_cfg) {\
+		.reg_off	= _offset,\
+		.bit_idx	= _bit_idx,\
+		.gate_flags	= _gate_flags,\
+	},\
+	.func		= _clk_hw_register_gate,\
+}
+
+#define FIXED_FACTOR(_id, _name, _parent, _flags, _mult, _div)\
+{\
+	.id		= _id,\
+	.name		= _name,\
+	.parent_name	= _parent,\
+	.flags		= _flags,\
+	.cfg		=  &(struct fixed_factor_cfg) {\
+		.mult = _mult,\
+		.div = _div,\
+	},\
+	.func		= _clk_hw_register_fixed_factor,\
+}
+
+#define DIV_TABLE(_id, _name, _parent, _flags, _offset, _shift, _width,\
+		  _div_flags, _div_table)\
+{\
+	.id		= _id,\
+	.name		= _name,\
+	.parent_name	= _parent,\
+	.flags		= _flags,\
+	.cfg		=  &(struct div_cfg) {\
+		.reg_off	= _offset,\
+		.shift		= _shift,\
+		.width		= _width,\
+		.div_flags	= _div_flags,\
+		.table		= _div_table,\
+	},\
+	.func		= _clk_hw_register_divider_table,\
+}
+
+#define DIV(_id, _name, _parent, _flags, _offset, _shift, _width, _div_flags)\
+	DIV_TABLE(_id, _name, _parent, _flags, _offset, _shift, _width,\
+		  _div_flags, NULL)
+
+#define MUX(_id, _name, _parents, _flags, _offset, _shift, _width, _mux_flags)\
+{\
+	.id		= _id,\
+	.name		= _name,\
+	.parent_names	= _parents,\
+	.num_parents	= ARRAY_SIZE(_parents),\
+	.flags		= _flags,\
+	.cfg		=  &(struct mux_cfg) {\
+		.reg_off	= _offset,\
+		.shift		= _shift,\
+		.width		= _width,\
+		.mux_flags	= _mux_flags,\
+	},\
+	.func		= _clk_hw_register_mux,\
+}
+
+#define PLL(_id, _name, _parent, _flags, _offset)\
+{\
+	.id		= _id,\
+	.name		= _name,\
+	.parent_name	= _parent,\
+	.flags		= _flags,\
+	.cfg		=  &(struct stm32_pll_cfg) {\
+		.offset = _offset,\
+	},\
+	.func		= _clk_register_pll,\
+}
+
+#define STM32_CKTIM(_name, _parent, _flags, _offset_apbdiv, _offset_timpre)\
+{\
+	.id		= NO_ID,\
+	.name		= _name,\
+	.parent_name	= _parent,\
+	.flags		= _flags,\
+	.cfg		=  &(struct stm32_cktim_cfg) {\
+		.offset_apbdiv = _offset_apbdiv,\
+		.offset_timpre = _offset_timpre,\
+	},\
+	.func		= _clk_register_cktim,\
+}
+
+#define STM32_TIM(_id, _name, _parent, _offset_set, _bit_idx)\
+		  GATE_MP1(_id, _name, _parent, CLK_SET_RATE_PARENT,\
+			   _offset_set, _bit_idx, 0)
+
+/* STM32 GATE */
+#define STM32_GATE(_id, _name, _parent, _flags, _gate)\
+{\
+	.id		= _id,\
+	.name		= _name,\
+	.parent_name	= _parent,\
+	.flags		= _flags,\
+	.cfg		= (struct stm32_gate_cfg *) {_gate},\
+	.func		= _clk_stm32_register_gate,\
+}
+
+#define _STM32_GATE(_gate_offset, _gate_bit_idx, _gate_flags, _ops)\
+	(&(struct stm32_gate_cfg) {\
+		&(struct gate_cfg) {\
+			.reg_off	= _gate_offset,\
+			.bit_idx	= _gate_bit_idx,\
+			.gate_flags	= _gate_flags,\
+		},\
+		.ops		= _ops,\
+	})
+
+#define _STM32_MGATE(_mgate)\
+	(&per_gate_cfg[_mgate])
+
+#define _GATE(_gate_offset, _gate_bit_idx, _gate_flags)\
+	_STM32_GATE(_gate_offset, _gate_bit_idx, _gate_flags,\
+		    NULL)\
+
+#define _GATE_MP1(_gate_offset, _gate_bit_idx, _gate_flags)\
+	_STM32_GATE(_gate_offset, _gate_bit_idx, _gate_flags,\
+		    &mp1_gate_clk_ops)\
+
+#define _MGATE_MP1(_mgate)\
+	.gate = &per_gate_cfg[_mgate]
+
+#define GATE_MP1(_id, _name, _parent, _flags, _offset, _bit_idx, _gate_flags)\
+	STM32_GATE(_id, _name, _parent, _flags,\
+		   _GATE_MP1(_offset, _bit_idx, _gate_flags))
+
+#define MGATE_MP1(_id, _name, _parent, _flags, _mgate)\
+	STM32_GATE(_id, _name, _parent, _flags,\
+		   _STM32_MGATE(_mgate))
+
+#define _STM32_DIV(_div_offset, _div_shift, _div_width,\
+		   _div_flags, _div_table, _ops)\
+	.div = &(struct stm32_div_cfg) {\
+		&(struct div_cfg) {\
+			.reg_off	= _div_offset,\
+			.shift		= _div_shift,\
+			.width		= _div_width,\
+			.div_flags	= _div_flags,\
+			.table		= _div_table,\
+		},\
+		.ops		= _ops,\
+	}
+
+#define _DIV(_div_offset, _div_shift, _div_width, _div_flags, _div_table)\
+	_STM32_DIV(_div_offset, _div_shift, _div_width,\
+		   _div_flags, _div_table, NULL)\
+
+#define _STM32_MUX(_offset, _shift, _width, _mux_flags, _mmux, _ops)\
+	.mux = &(struct stm32_mux_cfg) {\
+		&(struct mux_cfg) {\
+			.reg_off	= _offset,\
+			.shift		= _shift,\
+			.width		= _width,\
+			.mux_flags	= _mux_flags,\
+			.table		= NULL,\
+		},\
+		.mmux		= _mmux,\
+		.ops		= _ops,\
+	}
+
+#define _MUX(_offset, _shift, _width, _mux_flags)\
+	_STM32_MUX(_offset, _shift, _width, _mux_flags, NULL, NULL)\
+
+#define _MMUX(_mmux) .mux = &ker_mux_cfg[_mmux]
+
+#define PARENT(_parent) ((const char *[]) { _parent})
+
+#define _NO_MUX .mux = NULL
+#define _NO_DIV .div = NULL
+#define _NO_GATE .gate = NULL
+
+#define COMPOSITE(_id, _name, _parents, _flags, _gate, _mux, _div)\
+{\
+	.id		= _id,\
+	.name		= _name,\
+	.parent_names	= _parents,\
+	.num_parents	= ARRAY_SIZE(_parents),\
+	.flags		= _flags,\
+	.cfg		= &(struct stm32_composite_cfg) {\
+		_gate,\
+		_mux,\
+		_div,\
+	},\
+	.func		= _clk_stm32_register_composite,\
+}
+
+#define PCLK(_id, _name, _parent, _flags, _mgate)\
+	MGATE_MP1(_id, _name, _parent, _flags, _mgate)
+
+#define KCLK(_id, _name, _parents, _flags, _mgate, _mmux)\
+	     COMPOSITE(_id, _name, _parents, CLK_OPS_PARENT_ENABLE | _flags,\
+		  _MGATE_MP1(_mgate),\
+		  _MMUX(_mmux),\
+		  _NO_DIV)
+
+enum {
+	G_SAI1,
+	G_SAI2,
+	G_SAI3,
+	G_SAI4,
+	G_SPI1,
+	G_SPI2,
+	G_SPI3,
+	G_SPI4,
+	G_SPI5,
+	G_SPI6,
+	G_SPDIF,
+	G_I2C1,
+	G_I2C2,
+	G_I2C3,
+	G_I2C4,
+	G_I2C5,
+	G_I2C6,
+	G_USART2,
+	G_UART4,
+	G_USART3,
+	G_UART5,
+	G_USART1,
+	G_USART6,
+	G_UART7,
+	G_UART8,
+	G_LPTIM1,
+	G_LPTIM2,
+	G_LPTIM3,
+	G_LPTIM4,
+	G_LPTIM5,
+	G_LTDC,
+	G_DSI,
+	G_QSPI,
+	G_FMC,
+	G_SDMMC1,
+	G_SDMMC2,
+	G_SDMMC3,
+	G_USBO,
+	G_USBPHY,
+	G_RNG1,
+	G_RNG2,
+	G_FDCAN,
+	G_DAC12,
+	G_CEC,
+	G_ADC12,
+	G_GPU,
+	G_STGEN,
+	G_DFSDM,
+	G_ADFSDM,
+	G_TIM2,
+	G_TIM3,
+	G_TIM4,
+	G_TIM5,
+	G_TIM6,
+	G_TIM7,
+	G_TIM12,
+	G_TIM13,
+	G_TIM14,
+	G_MDIO,
+	G_TIM1,
+	G_TIM8,
+	G_TIM15,
+	G_TIM16,
+	G_TIM17,
+	G_SYSCFG,
+	G_VREF,
+	G_TMPSENS,
+	G_PMBCTRL,
+	G_HDP,
+	G_IWDG2,
+	G_STGENRO,
+	G_DMA1,
+	G_DMA2,
+	G_DMAMUX,
+	G_DCMI,
+	G_CRYP2,
+	G_HASH2,
+	G_CRC2,
+	G_HSEM,
+	G_IPCC,
+	G_GPIOA,
+	G_GPIOB,
+	G_GPIOC,
+	G_GPIOD,
+	G_GPIOE,
+	G_GPIOF,
+	G_GPIOG,
+	G_GPIOH,
+	G_GPIOI,
+	G_GPIOJ,
+	G_GPIOK,
+	G_MDMA,
+	G_ETHCK,
+	G_ETHTX,
+	G_ETHRX,
+	G_ETHMAC,
+	G_CRC1,
+	G_USBH,
+	G_ETHSTP,
+	G_RTCAPB,
+	G_TZC1,
+	G_TZC2,
+	G_TZPC,
+	G_IWDG1,
+	G_BSEC,
+	G_GPIOZ,
+	G_CRYP1,
+	G_HASH1,
+	G_BKPSRAM,
+
+	G_LAST
+};
+
+static struct stm32_mgate mp1_mgate[G_LAST];
+
+#define _K_GATE(_id, _gate_offset, _gate_bit_idx, _gate_flags,\
+	       _mgate, _ops)\
+	[_id] = {\
+		&(struct gate_cfg) {\
+			.reg_off	= _gate_offset,\
+			.bit_idx	= _gate_bit_idx,\
+			.gate_flags	= _gate_flags,\
+		},\
+		.mgate		= _mgate,\
+		.ops		= _ops,\
+	}
+
+#define K_GATE(_id, _gate_offset, _gate_bit_idx, _gate_flags)\
+	_K_GATE(_id, _gate_offset, _gate_bit_idx, _gate_flags,\
+	       NULL, &mp1_gate_clk_ops)
+
+#define K_MGATE(_id, _gate_offset, _gate_bit_idx, _gate_flags)\
+	_K_GATE(_id, _gate_offset, _gate_bit_idx, _gate_flags,\
+	       &mp1_mgate[_id], &mp1_mgate_clk_ops)
+
+/* Peripheral gates */
+static struct stm32_gate_cfg per_gate_cfg[G_LAST] = {
+	/* Multi gates */
+	K_GATE(G_MDIO,		RCC_APB1ENSETR, 31, 0),
+	K_MGATE(G_DAC12,	RCC_APB1ENSETR, 29, 0),
+	K_MGATE(G_CEC,		RCC_APB1ENSETR, 27, 0),
+	K_MGATE(G_SPDIF,	RCC_APB1ENSETR, 26, 0),
+	K_MGATE(G_I2C5,		RCC_APB1ENSETR, 24, 0),
+	K_MGATE(G_I2C3,		RCC_APB1ENSETR, 23, 0),
+	K_MGATE(G_I2C2,		RCC_APB1ENSETR, 22, 0),
+	K_MGATE(G_I2C1,		RCC_APB1ENSETR, 21, 0),
+	K_MGATE(G_UART8,	RCC_APB1ENSETR, 19, 0),
+	K_MGATE(G_UART7,	RCC_APB1ENSETR, 18, 0),
+	K_MGATE(G_UART5,	RCC_APB1ENSETR, 17, 0),
+	K_MGATE(G_UART4,	RCC_APB1ENSETR, 16, 0),
+	K_MGATE(G_USART3,	RCC_APB1ENSETR, 15, 0),
+	K_MGATE(G_USART2,	RCC_APB1ENSETR, 14, 0),
+	K_MGATE(G_SPI3,		RCC_APB1ENSETR, 12, 0),
+	K_MGATE(G_SPI2,		RCC_APB1ENSETR, 11, 0),
+	K_MGATE(G_LPTIM1,	RCC_APB1ENSETR, 9, 0),
+	K_GATE(G_TIM14,		RCC_APB1ENSETR, 8, 0),
+	K_GATE(G_TIM13,		RCC_APB1ENSETR, 7, 0),
+	K_GATE(G_TIM12,		RCC_APB1ENSETR, 6, 0),
+	K_GATE(G_TIM7,		RCC_APB1ENSETR, 5, 0),
+	K_GATE(G_TIM6,		RCC_APB1ENSETR, 4, 0),
+	K_GATE(G_TIM5,		RCC_APB1ENSETR, 3, 0),
+	K_GATE(G_TIM4,		RCC_APB1ENSETR, 2, 0),
+	K_GATE(G_TIM3,		RCC_APB1ENSETR, 1, 0),
+	K_GATE(G_TIM2,		RCC_APB1ENSETR, 0, 0),
+
+	K_MGATE(G_FDCAN,	RCC_APB2ENSETR, 24, 0),
+	K_GATE(G_ADFSDM,	RCC_APB2ENSETR, 21, 0),
+	K_GATE(G_DFSDM,		RCC_APB2ENSETR, 20, 0),
+	K_MGATE(G_SAI3,		RCC_APB2ENSETR, 18, 0),
+	K_MGATE(G_SAI2,		RCC_APB2ENSETR, 17, 0),
+	K_MGATE(G_SAI1,		RCC_APB2ENSETR, 16, 0),
+	K_MGATE(G_USART6,	RCC_APB2ENSETR, 13, 0),
+	K_MGATE(G_SPI5,		RCC_APB2ENSETR, 10, 0),
+	K_MGATE(G_SPI4,		RCC_APB2ENSETR, 9, 0),
+	K_MGATE(G_SPI1,		RCC_APB2ENSETR, 8, 0),
+	K_GATE(G_TIM17,		RCC_APB2ENSETR, 4, 0),
+	K_GATE(G_TIM16,		RCC_APB2ENSETR, 3, 0),
+	K_GATE(G_TIM15,		RCC_APB2ENSETR, 2, 0),
+	K_GATE(G_TIM8,		RCC_APB2ENSETR, 1, 0),
+	K_GATE(G_TIM1,		RCC_APB2ENSETR, 0, 0),
+
+	K_GATE(G_HDP,		RCC_APB3ENSETR, 20, 0),
+	K_GATE(G_PMBCTRL,	RCC_APB3ENSETR, 17, 0),
+	K_GATE(G_TMPSENS,	RCC_APB3ENSETR, 16, 0),
+	K_GATE(G_VREF,		RCC_APB3ENSETR, 13, 0),
+	K_GATE(G_SYSCFG,	RCC_APB3ENSETR, 11, 0),
+	K_MGATE(G_SAI4,		RCC_APB3ENSETR, 8, 0),
+	K_MGATE(G_LPTIM5,	RCC_APB3ENSETR, 3, 0),
+	K_MGATE(G_LPTIM4,	RCC_APB3ENSETR, 2, 0),
+	K_MGATE(G_LPTIM3,	RCC_APB3ENSETR, 1, 0),
+	K_MGATE(G_LPTIM2,	RCC_APB3ENSETR, 0, 0),
+
+	K_GATE(G_STGENRO,	RCC_APB4ENSETR, 20, 0),
+	K_MGATE(G_USBPHY,	RCC_APB4ENSETR, 16, 0),
+	K_GATE(G_IWDG2,		RCC_APB4ENSETR, 15, 0),
+	K_MGATE(G_DSI,		RCC_APB4ENSETR, 4, 0),
+	K_MGATE(G_LTDC,		RCC_APB4ENSETR, 0, 0),
+
+	K_GATE(G_STGEN,		RCC_APB5ENSETR, 20, 0),
+	K_GATE(G_BSEC,		RCC_APB5ENSETR, 16, 0),
+	K_GATE(G_IWDG1,		RCC_APB5ENSETR, 15, 0),
+	K_GATE(G_TZPC,		RCC_APB5ENSETR, 13, 0),
+	K_GATE(G_TZC2,		RCC_APB5ENSETR, 12, 0),
+	K_GATE(G_TZC1,		RCC_APB5ENSETR, 11, 0),
+	K_GATE(G_RTCAPB,	RCC_APB5ENSETR, 8, 0),
+	K_MGATE(G_USART1,	RCC_APB5ENSETR, 4, 0),
+	K_MGATE(G_I2C6,		RCC_APB5ENSETR, 3, 0),
+	K_MGATE(G_I2C4,		RCC_APB5ENSETR, 2, 0),
+	K_MGATE(G_SPI6,		RCC_APB5ENSETR, 0, 0),
+
+	K_MGATE(G_SDMMC3,	RCC_AHB2ENSETR, 16, 0),
+	K_MGATE(G_USBO,		RCC_AHB2ENSETR, 8, 0),
+	K_MGATE(G_ADC12,	RCC_AHB2ENSETR, 5, 0),
+	K_GATE(G_DMAMUX,	RCC_AHB2ENSETR, 2, 0),
+	K_GATE(G_DMA2,		RCC_AHB2ENSETR, 1, 0),
+	K_GATE(G_DMA1,		RCC_AHB2ENSETR, 0, 0),
+
+	K_GATE(G_IPCC,		RCC_AHB3ENSETR, 12, 0),
+	K_GATE(G_HSEM,		RCC_AHB3ENSETR, 11, 0),
+	K_GATE(G_CRC2,		RCC_AHB3ENSETR, 7, 0),
+	K_MGATE(G_RNG2,		RCC_AHB3ENSETR, 6, 0),
+	K_GATE(G_HASH2,		RCC_AHB3ENSETR, 5, 0),
+	K_GATE(G_CRYP2,		RCC_AHB3ENSETR, 4, 0),
+	K_GATE(G_DCMI,		RCC_AHB3ENSETR, 0, 0),
+
+	K_GATE(G_GPIOK,		RCC_AHB4ENSETR, 10, 0),
+	K_GATE(G_GPIOJ,		RCC_AHB4ENSETR, 9, 0),
+	K_GATE(G_GPIOI,		RCC_AHB4ENSETR, 8, 0),
+	K_GATE(G_GPIOH,		RCC_AHB4ENSETR, 7, 0),
+	K_GATE(G_GPIOG,		RCC_AHB4ENSETR, 6, 0),
+	K_GATE(G_GPIOF,		RCC_AHB4ENSETR, 5, 0),
+	K_GATE(G_GPIOE,		RCC_AHB4ENSETR, 4, 0),
+	K_GATE(G_GPIOD,		RCC_AHB4ENSETR, 3, 0),
+	K_GATE(G_GPIOC,		RCC_AHB4ENSETR, 2, 0),
+	K_GATE(G_GPIOB,		RCC_AHB4ENSETR, 1, 0),
+	K_GATE(G_GPIOA,		RCC_AHB4ENSETR, 0, 0),
+
+	K_GATE(G_BKPSRAM,	RCC_AHB5ENSETR, 8, 0),
+	K_MGATE(G_RNG1,		RCC_AHB5ENSETR, 6, 0),
+	K_GATE(G_HASH1,		RCC_AHB5ENSETR, 5, 0),
+	K_GATE(G_CRYP1,		RCC_AHB5ENSETR, 4, 0),
+	K_GATE(G_GPIOZ,		RCC_AHB5ENSETR, 0, 0),
+
+	K_GATE(G_USBH,		RCC_AHB6ENSETR, 24, 0),
+	K_GATE(G_CRC1,		RCC_AHB6ENSETR, 20, 0),
+	K_MGATE(G_SDMMC2,	RCC_AHB6ENSETR, 17, 0),
+	K_MGATE(G_SDMMC1,	RCC_AHB6ENSETR, 16, 0),
+	K_MGATE(G_QSPI,		RCC_AHB6ENSETR, 14, 0),
+	K_MGATE(G_FMC,		RCC_AHB6ENSETR, 12, 0),
+	K_GATE(G_ETHMAC,	RCC_AHB6ENSETR, 10, 0),
+	K_GATE(G_ETHRX,		RCC_AHB6ENSETR, 9, 0),
+	K_GATE(G_ETHTX,		RCC_AHB6ENSETR, 8, 0),
+	K_GATE(G_ETHCK,		RCC_AHB6ENSETR, 7, 0),
+	K_MGATE(G_GPU,		RCC_AHB6ENSETR, 5, 0),
+	K_GATE(G_MDMA,		RCC_AHB6ENSETR, 0, 0),
+	K_GATE(G_ETHSTP,	RCC_AHB6LPENSETR, 11, 0),
+};
+
+enum {
+	M_SDMMC12,
+	M_SDMMC3,
+	M_FMC,
+	M_QSPI,
+	M_RNG1,
+	M_RNG2,
+	M_USBPHY,
+	M_USBO,
+	M_STGEN,
+	M_SPDIF,
+	M_SPI1,
+	M_SPI23,
+	M_SPI45,
+	M_SPI6,
+	M_CEC,
+	M_I2C12,
+	M_I2C35,
+	M_I2C46,
+	M_LPTIM1,
+	M_LPTIM23,
+	M_LPTIM45,
+	M_USART1,
+	M_UART24,
+	M_UART35,
+	M_USART6,
+	M_UART78,
+	M_SAI1,
+	M_SAI2,
+	M_SAI3,
+	M_SAI4,
+	M_DSI,
+	M_FDCAN,
+	M_ADC12,
+	M_ETHCK,
+	M_CKPER,
+	M_LAST
+};
+
+static struct stm32_mmux ker_mux[M_LAST];
+
+#define _K_MUX(_id, _offset, _shift, _width, _mux_flags, _mmux, _ops)\
+	[_id] = {\
+		&(struct mux_cfg) {\
+			.reg_off	= _offset,\
+			.shift		= _shift,\
+			.width		= _width,\
+			.mux_flags	= _mux_flags,\
+			.table		= NULL,\
+		},\
+		.mmux		= _mmux,\
+		.ops		= _ops,\
+	}
+
+#define K_MUX(_id, _offset, _shift, _width, _mux_flags)\
+	_K_MUX(_id, _offset, _shift, _width, _mux_flags,\
+			NULL, NULL)
+
+#define K_MMUX(_id, _offset, _shift, _width, _mux_flags)\
+	_K_MUX(_id, _offset, _shift, _width, _mux_flags,\
+			&ker_mux[_id], &clk_mmux_ops)
+
+static const struct stm32_mux_cfg ker_mux_cfg[M_LAST] = {
+	/* Kernel multi mux */
+	K_MMUX(M_SDMMC12, RCC_SDMMC12CKSELR, 0, 3, 0),
+	K_MMUX(M_SPI23, RCC_SPI2S23CKSELR, 0, 3, 0),
+	K_MMUX(M_SPI45, RCC_SPI2S45CKSELR, 0, 3, 0),
+	K_MMUX(M_I2C12, RCC_I2C12CKSELR, 0, 3, 0),
+	K_MMUX(M_I2C35, RCC_I2C35CKSELR, 0, 3, 0),
+	K_MMUX(M_LPTIM23, RCC_LPTIM23CKSELR, 0, 3, 0),
+	K_MMUX(M_LPTIM45, RCC_LPTIM45CKSELR, 0, 3, 0),
+	K_MMUX(M_UART24, RCC_UART24CKSELR, 0, 3, 0),
+	K_MMUX(M_UART35, RCC_UART35CKSELR, 0, 3, 0),
+	K_MMUX(M_UART78, RCC_UART78CKSELR, 0, 3, 0),
+	K_MMUX(M_SAI1, RCC_SAI1CKSELR, 0, 3, 0),
+	K_MMUX(M_ETHCK, RCC_ETHCKSELR, 0, 2, 0),
+	K_MMUX(M_I2C46, RCC_I2C46CKSELR, 0, 3, 0),
+
+	/* Kernel simple mux */
+	K_MUX(M_RNG2, RCC_RNG2CKSELR, 0, 2, 0),
+	K_MUX(M_SDMMC3, RCC_SDMMC3CKSELR, 0, 3, 0),
+	K_MUX(M_FMC, RCC_FMCCKSELR, 0, 2, 0),
+	K_MUX(M_QSPI, RCC_QSPICKSELR, 0, 2, 0),
+	K_MUX(M_USBPHY, RCC_USBCKSELR, 0, 2, 0),
+	K_MUX(M_USBO, RCC_USBCKSELR, 4, 1, 0),
+	K_MUX(M_SPDIF, RCC_SPDIFCKSELR, 0, 2, 0),
+	K_MUX(M_SPI1, RCC_SPI2S1CKSELR, 0, 3, 0),
+	K_MUX(M_CEC, RCC_CECCKSELR, 0, 2, 0),
+	K_MUX(M_LPTIM1, RCC_LPTIM1CKSELR, 0, 3, 0),
+	K_MUX(M_USART6, RCC_UART6CKSELR, 0, 3, 0),
+	K_MUX(M_FDCAN, RCC_FDCANCKSELR, 0, 2, 0),
+	K_MUX(M_SAI2, RCC_SAI2CKSELR, 0, 3, 0),
+	K_MUX(M_SAI3, RCC_SAI3CKSELR, 0, 3, 0),
+	K_MUX(M_SAI4, RCC_SAI4CKSELR, 0, 3, 0),
+	K_MUX(M_ADC12, RCC_ADCCKSELR, 0, 2, 0),
+	K_MUX(M_DSI, RCC_DSICKSELR, 0, 1, 0),
+	K_MUX(M_CKPER, RCC_CPERCKSELR, 0, 2, 0),
+	K_MUX(M_RNG1, RCC_RNG1CKSELR, 0, 2, 0),
+	K_MUX(M_STGEN, RCC_STGENCKSELR, 0, 2, 0),
+	K_MUX(M_USART1, RCC_UART1CKSELR, 0, 3, 0),
+	K_MUX(M_SPI6, RCC_SPI6CKSELR, 0, 3, 0),
+};
+
+static const struct clock_config stm32mp1_clock_cfg[] = {
+	/* Oscillator divider */
+	DIV(NO_ID, "clk-hsi-div", "clk-hsi", 0, RCC_HSICFGR, 0, 2,
+	    CLK_DIVIDER_READ_ONLY),
+
+	/*  External / Internal Oscillators */
+	GATE_MP1(CK_HSE, "ck_hse", "clk-hse", 0, RCC_OCENSETR, 8, 0),
+	GATE_MP1(CK_CSI, "ck_csi", "clk-csi", 0, RCC_OCENSETR, 4, 0),
+	GATE_MP1(CK_HSI, "ck_hsi", "clk-hsi-div", 0, RCC_OCENSETR, 0, 0),
+	GATE(CK_LSI, "ck_lsi", "clk-lsi", 0, RCC_RDLSICR, 0, 0),
+	GATE(CK_LSE, "ck_lse", "clk-lse", 0, RCC_BDCR, 0, 0),
+
+	FIXED_FACTOR(CK_HSE_DIV2, "clk-hse-div2", "ck_hse", 0, 1, 2),
+
+	/* ref clock pll */
+	MUX(NO_ID, "ref1", ref12_parents, CLK_OPS_PARENT_ENABLE, RCC_RCK12SELR,
+	    0, 2, CLK_MUX_READ_ONLY),
+
+	MUX(NO_ID, "ref3", ref3_parents, CLK_OPS_PARENT_ENABLE, RCC_RCK3SELR,
+	    0, 2, CLK_MUX_READ_ONLY),
+
+	MUX(NO_ID, "ref4", ref4_parents, CLK_OPS_PARENT_ENABLE, RCC_RCK4SELR,
+	    0, 2, CLK_MUX_READ_ONLY),
+
+	/* PLLs */
+	PLL(PLL1, "pll1", "ref1", CLK_IGNORE_UNUSED, RCC_PLL1CR),
+	PLL(PLL2, "pll2", "ref1", CLK_IGNORE_UNUSED, RCC_PLL2CR),
+	PLL(PLL3, "pll3", "ref3", CLK_IGNORE_UNUSED, RCC_PLL3CR),
+	PLL(PLL4, "pll4", "ref4", CLK_IGNORE_UNUSED, RCC_PLL4CR),
+
+	/* ODF */
+	COMPOSITE(PLL1_P, "pll1_p", PARENT("pll1"), 0,
+		  _GATE(RCC_PLL1CR, 4, 0),
+		  _NO_MUX,
+		  _DIV(RCC_PLL1CFGR2, 0, 7, 0, NULL)),
+
+	COMPOSITE(PLL2_P, "pll2_p", PARENT("pll2"), 0,
+		  _GATE(RCC_PLL2CR, 4, 0),
+		  _NO_MUX,
+		  _DIV(RCC_PLL2CFGR2, 0, 7, 0, NULL)),
+
+	COMPOSITE(PLL2_Q, "pll2_q", PARENT("pll2"), 0,
+		  _GATE(RCC_PLL2CR, 5, 0),
+		  _NO_MUX,
+		  _DIV(RCC_PLL2CFGR2, 8, 7, 0, NULL)),
+
+	COMPOSITE(PLL2_R, "pll2_r", PARENT("pll2"), CLK_IS_CRITICAL,
+		  _GATE(RCC_PLL2CR, 6, 0),
+		  _NO_MUX,
+		  _DIV(RCC_PLL2CFGR2, 16, 7, 0, NULL)),
+
+	COMPOSITE(PLL3_P, "pll3_p", PARENT("pll3"), 0,
+		  _GATE(RCC_PLL3CR, 4, 0),
+		  _NO_MUX,
+		  _DIV(RCC_PLL3CFGR2, 0, 7, 0, NULL)),
+
+	COMPOSITE(PLL3_Q, "pll3_q", PARENT("pll3"), 0,
+		  _GATE(RCC_PLL3CR, 5, 0),
+		  _NO_MUX,
+		  _DIV(RCC_PLL3CFGR2, 8, 7, 0, NULL)),
+
+	COMPOSITE(PLL3_R, "pll3_r", PARENT("pll3"), 0,
+		  _GATE(RCC_PLL3CR, 6, 0),
+		  _NO_MUX,
+		  _DIV(RCC_PLL3CFGR2, 16, 7, 0, NULL)),
+
+	COMPOSITE(PLL4_P, "pll4_p", PARENT("pll4"), 0,
+		  _GATE(RCC_PLL4CR, 4, 0),
+		  _NO_MUX,
+		  _DIV(RCC_PLL4CFGR2, 0, 7, 0, NULL)),
+
+	COMPOSITE(PLL4_Q, "pll4_q", PARENT("pll4"), 0,
+		  _GATE(RCC_PLL4CR, 5, 0),
+		  _NO_MUX,
+		  _DIV(RCC_PLL4CFGR2, 8, 7, 0, NULL)),
+
+	COMPOSITE(PLL4_R, "pll4_r", PARENT("pll4"), 0,
+		  _GATE(RCC_PLL4CR, 6, 0),
+		  _NO_MUX,
+		  _DIV(RCC_PLL4CFGR2, 16, 7, 0, NULL)),
+
+	/* MUX system clocks */
+	MUX(CK_PER, "ck_per", per_src, CLK_OPS_PARENT_ENABLE,
+	    RCC_CPERCKSELR, 0, 2, 0),
+
+	MUX(CK_MPU, "ck_mpu", cpu_src, CLK_OPS_PARENT_ENABLE |
+	     CLK_IS_CRITICAL, RCC_MPCKSELR, 0, 2, 0),
+
+	COMPOSITE(CK_AXI, "ck_axi", axi_src, CLK_IS_CRITICAL |
+		   CLK_OPS_PARENT_ENABLE,
+		   _NO_GATE,
+		   _MUX(RCC_ASSCKSELR, 0, 2, 0),
+		   _DIV(RCC_AXIDIVR, 0, 3, 0, axi_div_table)),
+
+	COMPOSITE(CK_MCU, "ck_mcu", mcu_src, CLK_IS_CRITICAL |
+		   CLK_OPS_PARENT_ENABLE,
+		   _NO_GATE,
+		   _MUX(RCC_MSSCKSELR, 0, 2, 0),
+		   _DIV(RCC_MCUDIVR, 0, 4, 0, mcu_div_table)),
+
+	DIV_TABLE(NO_ID, "pclk1", "ck_mcu", CLK_IGNORE_UNUSED, RCC_APB1DIVR, 0,
+		  3, CLK_DIVIDER_READ_ONLY, apb_div_table),
+
+	DIV_TABLE(NO_ID, "pclk2", "ck_mcu", CLK_IGNORE_UNUSED, RCC_APB2DIVR, 0,
+		  3, CLK_DIVIDER_READ_ONLY, apb_div_table),
+
+	DIV_TABLE(NO_ID, "pclk3", "ck_mcu", CLK_IGNORE_UNUSED, RCC_APB3DIVR, 0,
+		  3, CLK_DIVIDER_READ_ONLY, apb_div_table),
+
+	DIV_TABLE(NO_ID, "pclk4", "ck_axi", CLK_IGNORE_UNUSED, RCC_APB4DIVR, 0,
+		  3, CLK_DIVIDER_READ_ONLY, apb_div_table),
+
+	DIV_TABLE(NO_ID, "pclk5", "ck_axi", CLK_IGNORE_UNUSED, RCC_APB5DIVR, 0,
+		  3, CLK_DIVIDER_READ_ONLY, apb_div_table),
+
+	/* Kernel Timers */
+	STM32_CKTIM("ck1_tim", "pclk1", 0, RCC_APB1DIVR, RCC_TIMG1PRER),
+	STM32_CKTIM("ck2_tim", "pclk2", 0, RCC_APB2DIVR, RCC_TIMG2PRER),
+
+	STM32_TIM(TIM2_K, "tim2_k", "ck1_tim", RCC_APB1ENSETR, 0),
+	STM32_TIM(TIM3_K, "tim3_k", "ck1_tim", RCC_APB1ENSETR, 1),
+	STM32_TIM(TIM4_K, "tim4_k", "ck1_tim", RCC_APB1ENSETR, 2),
+	STM32_TIM(TIM5_K, "tim5_k", "ck1_tim", RCC_APB1ENSETR, 3),
+	STM32_TIM(TIM6_K, "tim6_k", "ck1_tim", RCC_APB1ENSETR, 4),
+	STM32_TIM(TIM7_K, "tim7_k", "ck1_tim", RCC_APB1ENSETR, 5),
+	STM32_TIM(TIM12_K, "tim12_k", "ck1_tim", RCC_APB1ENSETR, 6),
+	STM32_TIM(TIM13_K, "tim13_k", "ck1_tim", RCC_APB1ENSETR, 7),
+	STM32_TIM(TIM14_K, "tim14_k", "ck1_tim", RCC_APB1ENSETR, 8),
+	STM32_TIM(TIM1_K, "tim1_k", "ck2_tim", RCC_APB2ENSETR, 0),
+	STM32_TIM(TIM8_K, "tim8_k", "ck2_tim", RCC_APB2ENSETR, 1),
+	STM32_TIM(TIM15_K, "tim15_k", "ck2_tim", RCC_APB2ENSETR, 2),
+	STM32_TIM(TIM16_K, "tim16_k", "ck2_tim", RCC_APB2ENSETR, 3),
+	STM32_TIM(TIM17_K, "tim17_k", "ck2_tim", RCC_APB2ENSETR, 4),
+
+	/* Peripheral clocks */
+	PCLK(TIM2, "tim2", "pclk1", CLK_IGNORE_UNUSED, G_TIM2),
+	PCLK(TIM3, "tim3", "pclk1", CLK_IGNORE_UNUSED, G_TIM3),
+	PCLK(TIM4, "tim4", "pclk1", CLK_IGNORE_UNUSED, G_TIM4),
+	PCLK(TIM5, "tim5", "pclk1", CLK_IGNORE_UNUSED, G_TIM5),
+	PCLK(TIM6, "tim6", "pclk1", CLK_IGNORE_UNUSED, G_TIM6),
+	PCLK(TIM7, "tim7", "pclk1", CLK_IGNORE_UNUSED, G_TIM7),
+	PCLK(TIM12, "tim12", "pclk1", CLK_IGNORE_UNUSED, G_TIM12),
+	PCLK(TIM13, "tim13", "pclk1", CLK_IGNORE_UNUSED, G_TIM13),
+	PCLK(TIM14, "tim14", "pclk1", CLK_IGNORE_UNUSED, G_TIM14),
+	PCLK(LPTIM1, "lptim1", "pclk1", 0, G_LPTIM1),
+	PCLK(SPI2, "spi2", "pclk1", 0, G_SPI2),
+	PCLK(SPI3, "spi3", "pclk1", 0, G_SPI3),
+	PCLK(USART2, "usart2", "pclk1", 0, G_USART2),
+	PCLK(USART3, "usart3", "pclk1", 0, G_USART3),
+	PCLK(UART4, "uart4", "pclk1", 0, G_UART4),
+	PCLK(UART5, "uart5", "pclk1", 0, G_UART5),
+	PCLK(UART7, "uart7", "pclk1", 0, G_UART7),
+	PCLK(UART8, "uart8", "pclk1", 0, G_UART8),
+	PCLK(I2C1, "i2c1", "pclk1", 0, G_I2C1),
+	PCLK(I2C2, "i2c2", "pclk1", 0, G_I2C2),
+	PCLK(I2C3, "i2c3", "pclk1", 0, G_I2C3),
+	PCLK(I2C5, "i2c5", "pclk1", 0, G_I2C5),
+	PCLK(SPDIF, "spdif", "pclk1", 0, G_SPDIF),
+	PCLK(CEC, "cec", "pclk1", 0, G_CEC),
+	PCLK(DAC12, "dac12", "pclk1", 0, G_DAC12),
+	PCLK(MDIO, "mdio", "pclk1", 0, G_MDIO),
+	PCLK(TIM1, "tim1", "pclk2", CLK_IGNORE_UNUSED, G_TIM1),
+	PCLK(TIM8, "tim8", "pclk2", CLK_IGNORE_UNUSED, G_TIM8),
+	PCLK(TIM15, "tim15", "pclk2", CLK_IGNORE_UNUSED, G_TIM15),
+	PCLK(TIM16, "tim16", "pclk2", CLK_IGNORE_UNUSED, G_TIM16),
+	PCLK(TIM17, "tim17", "pclk2", CLK_IGNORE_UNUSED, G_TIM17),
+	PCLK(SPI1, "spi1", "pclk2", 0, G_SPI1),
+	PCLK(SPI4, "spi4", "pclk2", 0, G_SPI4),
+	PCLK(SPI5, "spi5", "pclk2", 0, G_SPI5),
+	PCLK(USART6, "usart6", "pclk2", 0, G_USART6),
+	PCLK(SAI1, "sai1", "pclk2", 0, G_SAI1),
+	PCLK(SAI2, "sai2", "pclk2", 0, G_SAI2),
+	PCLK(SAI3, "sai3", "pclk2", 0, G_SAI3),
+	PCLK(DFSDM, "dfsdm", "pclk2", 0, G_DFSDM),
+	PCLK(FDCAN, "fdcan", "pclk2", 0, G_FDCAN),
+	PCLK(LPTIM2, "lptim2", "pclk3", 0, G_LPTIM2),
+	PCLK(LPTIM3, "lptim3", "pclk3", 0, G_LPTIM3),
+	PCLK(LPTIM4, "lptim4", "pclk3", 0, G_LPTIM4),
+	PCLK(LPTIM5, "lptim5", "pclk3", 0, G_LPTIM5),
+	PCLK(SAI4, "sai4", "pclk3", 0, G_SAI4),
+	PCLK(SYSCFG, "syscfg", "pclk3", 0, G_SYSCFG),
+	PCLK(VREF, "vref", "pclk3", 13, G_VREF),
+	PCLK(TMPSENS, "tmpsens", "pclk3", 0, G_TMPSENS),
+	PCLK(PMBCTRL, "pmbctrl", "pclk3", 0, G_PMBCTRL),
+	PCLK(HDP, "hdp", "pclk3", 0, G_HDP),
+	PCLK(LTDC, "ltdc", "pclk4", 0, G_LTDC),
+	PCLK(DSI, "dsi", "pclk4", 0, G_DSI),
+	PCLK(IWDG2, "iwdg2", "pclk4", 0, G_IWDG2),
+	PCLK(USBPHY, "usbphy", "pclk4", 0, G_USBPHY),
+	PCLK(STGENRO, "stgenro", "pclk4", 0, G_STGENRO),
+	PCLK(SPI6, "spi6", "pclk5", 0, G_SPI6),
+	PCLK(I2C4, "i2c4", "pclk5", 0, G_I2C4),
+	PCLK(I2C6, "i2c6", "pclk5", 0, G_I2C6),
+	PCLK(USART1, "usart1", "pclk5", 0, G_USART1),
+	PCLK(RTCAPB, "rtcapb", "pclk5", CLK_IGNORE_UNUSED |
+	     CLK_IS_CRITICAL, G_RTCAPB),
+	PCLK(TZC1, "tzc1", "ck_axi", CLK_IGNORE_UNUSED, G_TZC1),
+	PCLK(TZC2, "tzc2", "ck_axi", CLK_IGNORE_UNUSED, G_TZC2),
+	PCLK(TZPC, "tzpc", "pclk5", CLK_IGNORE_UNUSED, G_TZPC),
+	PCLK(IWDG1, "iwdg1", "pclk5", 0, G_IWDG1),
+	PCLK(BSEC, "bsec", "pclk5", CLK_IGNORE_UNUSED, G_BSEC),
+	PCLK(STGEN, "stgen", "pclk5", CLK_IGNORE_UNUSED, G_STGEN),
+	PCLK(DMA1, "dma1", "ck_mcu", 0, G_DMA1),
+	PCLK(DMA2, "dma2", "ck_mcu",  0, G_DMA2),
+	PCLK(DMAMUX, "dmamux", "ck_mcu", 0, G_DMAMUX),
+	PCLK(ADC12, "adc12", "ck_mcu", 0, G_ADC12),
+	PCLK(USBO, "usbo", "ck_mcu", 0, G_USBO),
+	PCLK(SDMMC3, "sdmmc3", "ck_mcu", 0, G_SDMMC3),
+	PCLK(DCMI, "dcmi", "ck_mcu", 0, G_DCMI),
+	PCLK(CRYP2, "cryp2", "ck_mcu", 0, G_CRYP2),
+	PCLK(HASH2, "hash2", "ck_mcu", 0, G_HASH2),
+	PCLK(RNG2, "rng2", "ck_mcu", 0, G_RNG2),
+	PCLK(CRC2, "crc2", "ck_mcu", 0, G_CRC2),
+	PCLK(HSEM, "hsem", "ck_mcu", 0, G_HSEM),
+	PCLK(IPCC, "ipcc", "ck_mcu", 0, G_IPCC),
+	PCLK(GPIOA, "gpioa", "ck_mcu", 0, G_GPIOA),
+	PCLK(GPIOB, "gpiob", "ck_mcu", 0, G_GPIOB),
+	PCLK(GPIOC, "gpioc", "ck_mcu", 0, G_GPIOC),
+	PCLK(GPIOD, "gpiod", "ck_mcu", 0, G_GPIOD),
+	PCLK(GPIOE, "gpioe", "ck_mcu", 0, G_GPIOE),
+	PCLK(GPIOF, "gpiof", "ck_mcu", 0, G_GPIOF),
+	PCLK(GPIOG, "gpiog", "ck_mcu", 0, G_GPIOG),
+	PCLK(GPIOH, "gpioh", "ck_mcu", 0, G_GPIOH),
+	PCLK(GPIOI, "gpioi", "ck_mcu", 0, G_GPIOI),
+	PCLK(GPIOJ, "gpioj", "ck_mcu", 0, G_GPIOJ),
+	PCLK(GPIOK, "gpiok", "ck_mcu", 0, G_GPIOK),
+	PCLK(GPIOZ, "gpioz", "ck_axi", CLK_IGNORE_UNUSED, G_GPIOZ),
+	PCLK(CRYP1, "cryp1", "ck_axi", CLK_IGNORE_UNUSED, G_CRYP1),
+	PCLK(HASH1, "hash1", "ck_axi", CLK_IGNORE_UNUSED, G_HASH1),
+	PCLK(RNG1, "rng1", "ck_axi", 0, G_RNG1),
+	PCLK(BKPSRAM, "bkpsram", "ck_axi", CLK_IGNORE_UNUSED, G_BKPSRAM),
+	PCLK(MDMA, "mdma", "ck_axi", 0, G_MDMA),
+	PCLK(GPU, "gpu", "ck_axi", 0, G_GPU),
+	PCLK(ETHTX, "ethtx", "ck_axi", 0, G_ETHTX),
+	PCLK(ETHRX, "ethrx", "ck_axi", 0, G_ETHRX),
+	PCLK(ETHMAC, "ethmac", "ck_axi", 0, G_ETHMAC),
+	PCLK(FMC, "fmc", "ck_axi", CLK_IGNORE_UNUSED, G_FMC),
+	PCLK(QSPI, "qspi", "ck_axi", CLK_IGNORE_UNUSED, G_QSPI),
+	PCLK(SDMMC1, "sdmmc1", "ck_axi", 0, G_SDMMC1),
+	PCLK(SDMMC2, "sdmmc2", "ck_axi", 0, G_SDMMC2),
+	PCLK(CRC1, "crc1", "ck_axi", 0, G_CRC1),
+	PCLK(USBH, "usbh", "ck_axi", 0, G_USBH),
+	PCLK(ETHSTP, "ethstp", "ck_axi", 0, G_ETHSTP),
+
+	/* Kernel clocks */
+	KCLK(SDMMC1_K, "sdmmc1_k", sdmmc12_src, 0, G_SDMMC1, M_SDMMC12),
+	KCLK(SDMMC2_K, "sdmmc2_k", sdmmc12_src, 0, G_SDMMC2, M_SDMMC12),
+	KCLK(SDMMC3_K, "sdmmc3_k", sdmmc3_src, 0, G_SDMMC3, M_SDMMC3),
+	KCLK(FMC_K, "fmc_k", fmc_src, 0, G_FMC, M_FMC),
+	KCLK(QSPI_K, "qspi_k", qspi_src, 0, G_QSPI, M_QSPI),
+	KCLK(RNG1_K, "rng1_k", rng_src, 0, G_RNG1, M_RNG1),
+	KCLK(RNG2_K, "rng2_k", rng_src, 0, G_RNG2, M_RNG2),
+	KCLK(USBPHY_K, "usbphy_k", usbphy_src, 0, G_USBPHY, M_USBPHY),
+	KCLK(STGEN_K, "stgen_k", stgen_src, CLK_IS_CRITICAL, G_STGEN, M_STGEN),
+	KCLK(SPDIF_K, "spdif_k", spdif_src, 0, G_SPDIF, M_SPDIF),
+	KCLK(SPI1_K, "spi1_k", spi123_src, 0, G_SPI1, M_SPI1),
+	KCLK(SPI2_K, "spi2_k", spi123_src, 0, G_SPI2, M_SPI23),
+	KCLK(SPI3_K, "spi3_k", spi123_src, 0, G_SPI3, M_SPI23),
+	KCLK(SPI4_K, "spi4_k", spi45_src, 0, G_SPI4, M_SPI45),
+	KCLK(SPI5_K, "spi5_k", spi45_src, 0, G_SPI5, M_SPI45),
+	KCLK(SPI6_K, "spi6_k", spi6_src, 0, G_SPI6, M_SPI6),
+	KCLK(CEC_K, "cec_k", cec_src, 0, G_CEC, M_CEC),
+	KCLK(I2C1_K, "i2c1_k", i2c12_src, 0, G_I2C1, M_I2C12),
+	KCLK(I2C2_K, "i2c2_k", i2c12_src, 0, G_I2C2, M_I2C12),
+	KCLK(I2C3_K, "i2c3_k", i2c35_src, 0, G_I2C3, M_I2C35),
+	KCLK(I2C5_K, "i2c5_k", i2c35_src, 0, G_I2C5, M_I2C35),
+	KCLK(I2C4_K, "i2c4_k", i2c46_src, 0, G_I2C4, M_I2C46),
+	KCLK(I2C6_K, "i2c6_k", i2c46_src, 0, G_I2C6, M_I2C46),
+	KCLK(LPTIM1_K, "lptim1_k", lptim1_src, 0, G_LPTIM1, M_LPTIM1),
+	KCLK(LPTIM2_K, "lptim2_k", lptim23_src, 0, G_LPTIM2, M_LPTIM23),
+	KCLK(LPTIM3_K, "lptim3_k", lptim23_src, 0, G_LPTIM3, M_LPTIM23),
+	KCLK(LPTIM4_K, "lptim4_k", lptim45_src, 0, G_LPTIM4, M_LPTIM45),
+	KCLK(LPTIM5_K, "lptim5_k", lptim45_src, 0, G_LPTIM5, M_LPTIM45),
+	KCLK(USART1_K, "usart1_k", usart1_src, 0, G_USART1, M_USART1),
+	KCLK(USART2_K, "usart2_k", usart234578_src, 0, G_USART2, M_UART24),
+	KCLK(USART3_K, "usart3_k", usart234578_src, 0, G_USART3, M_UART35),
+	KCLK(UART4_K, "uart4_k", usart234578_src, 0, G_UART4, M_UART24),
+	KCLK(UART5_K, "uart5_k", usart234578_src, 0, G_UART5, M_UART35),
+	KCLK(USART6_K, "uart6_k", usart6_src, 0, G_USART6, M_USART6),
+	KCLK(UART7_K, "uart7_k", usart234578_src, 0, G_UART7, M_UART78),
+	KCLK(UART8_K, "uart8_k", usart234578_src, 0, G_UART8, M_UART78),
+	KCLK(FDCAN_K, "fdcan_k", fdcan_src, 0, G_FDCAN, M_FDCAN),
+	KCLK(SAI1_K, "sai1_k", sai_src, 0, G_SAI1, M_SAI1),
+	KCLK(SAI2_K, "sai2_k", sai2_src, 0, G_SAI2, M_SAI2),
+	KCLK(SAI3_K, "sai3_k", sai_src, 0, G_SAI3, M_SAI3),
+	KCLK(SAI4_K, "sai4_k", sai_src, 0, G_SAI4, M_SAI4),
+	KCLK(ADC12_K, "adc12_k", adc12_src, 0, G_ADC12, M_ADC12),
+	KCLK(DSI_K, "dsi_k", dsi_src, 0, G_DSI, M_DSI),
+	KCLK(ADFSDM_K, "adfsdm_k", sai_src, 0, G_ADFSDM, M_SAI1),
+	KCLK(USBO_K, "usbo_k", usbo_src, 0, G_USBO, M_USBO),
+	KCLK(ETHCK_K, "ethck_k", eth_src, 0, G_ETHCK, M_ETHCK),
+
+	/* Particulary Kernel Clocks (no mux or no gate) */
+	MGATE_MP1(DFSDM_K, "dfsdm_k", "ck_mcu", 0, G_DFSDM),
+	MGATE_MP1(DSI_PX, "dsi_px", "pll4_q", CLK_SET_RATE_PARENT, G_DSI),
+	MGATE_MP1(LTDC_PX, "ltdc_px", "pll4_q", CLK_SET_RATE_PARENT, G_LTDC),
+	MGATE_MP1(GPU_K, "gpu_k", "pll2_q", 0, G_GPU),
+	MGATE_MP1(DAC12_K, "dac12_k", "ck_lsi", 0, G_DAC12),
+
+	COMPOSITE(ETHPTP_K, "ethptp_k", eth_src, CLK_OPS_PARENT_ENABLE,
+		  _NO_GATE,
+		  _MMUX(M_ETHCK),
+		  _DIV(RCC_ETHCKSELR, 4, 4, 0, NULL)),
+
+	/* RTC clock */
+	DIV(NO_ID, "ck_hse_rtc", "ck_hse", 0, RCC_RTCDIVR, 0, 7, 0),
+
+	COMPOSITE(RTC, "ck_rtc", rtc_src, CLK_OPS_PARENT_ENABLE |
+		   CLK_SET_RATE_PARENT,
+		  _GATE(RCC_BDCR, 20, 0),
+		  _MUX(RCC_BDCR, 16, 2, 0),
+		  _NO_DIV),
+
+	/* MCO clocks */
+	COMPOSITE(CK_MCO1, "ck_mco1", mco1_src, CLK_OPS_PARENT_ENABLE |
+		  CLK_SET_RATE_NO_REPARENT,
+		  _GATE(RCC_MCO1CFGR, 12, 0),
+		  _MUX(RCC_MCO1CFGR, 0, 3, 0),
+		  _DIV(RCC_MCO1CFGR, 4, 4, 0, NULL)),
+
+	COMPOSITE(CK_MCO2, "ck_mco2", mco2_src, CLK_OPS_PARENT_ENABLE |
+		  CLK_SET_RATE_NO_REPARENT,
+		  _GATE(RCC_MCO2CFGR, 12, 0),
+		  _MUX(RCC_MCO2CFGR, 0, 3, 0),
+		  _DIV(RCC_MCO2CFGR, 4, 4, 0, NULL)),
+
+	/* Debug clocks */
+	GATE(CK_DBG, "ck_sys_dbg", "ck_axi", CLK_IGNORE_UNUSED,
+	     RCC_DBGCFGR, 8, 0),
+
+	COMPOSITE(CK_TRACE, "ck_trace", ck_trace_src, CLK_OPS_PARENT_ENABLE,
+		  _GATE(RCC_DBGCFGR, 9, 0),
+		  _NO_MUX,
+		  _DIV(RCC_DBGCFGR, 0, 3, 0, ck_trace_div_table)),
+};
+
+struct stm32_clock_match_data {
+	const struct clock_config *cfg;
+	unsigned int num;
+	unsigned int maxbinding;
+};
+
+static struct stm32_clock_match_data stm32mp1_data = {
+	.cfg		= stm32mp1_clock_cfg,
+	.num		= ARRAY_SIZE(stm32mp1_clock_cfg),
+	.maxbinding	= STM32MP1_LAST_CLK,
+};
+
+static const struct of_device_id stm32mp1_match_data[] = {
+	{
+		.compatible = "st,stm32mp1-rcc",
+		.data = &stm32mp1_data,
+	},
+	{ }
+};
+
+static int stm32_register_hw_clk(struct clk_onecell_data *clk_data,
+				 void __iomem *base,
+				 const struct clock_config *cfg)
+{
+	struct clk *clk = ERR_PTR(-ENOENT);
+
+	if (cfg->func)
+		clk = (*cfg->func)(base, cfg);
+
+	if (IS_ERR(clk)) {
+		pr_err("Unable to register %s\n", cfg->name);
+		return  PTR_ERR(clk);
+	}
+
+	if (cfg->id != NO_ID)
+		clk_data->clks[cfg->id] = clk;
+
+	return 0;
+}
+
+static int stm32_rcc_init(struct device_node *np,
+			  void __iomem *base,
+			  const struct of_device_id *match_data)
+{
+	struct clk_onecell_data *clk_data;
+	struct clk **clks;
+	const struct of_device_id *match;
+	const struct stm32_clock_match_data *data;
+	int err, n, max_binding;
+
+	match = of_match_node(match_data, np);
+	if (!match) {
+		pr_err("%s: match data not found\n", __func__);
+		return -ENODEV;
+	}
+
+	data = match->data;
+
+	max_binding = data->maxbinding;
+
+	clk_data = xzalloc(sizeof(*clk_data));
+	clk_data->clks = xzalloc(sizeof(void *) * max_binding);
+	clk_data->clk_num = max_binding;
+
+	clks = clk_data->clks;
+
+	for (n = 0; n < max_binding; n++)
+		clks[n] = ERR_PTR(-ENOENT);
+
+	for (n = 0; n < data->num; n++) {
+		err = stm32_register_hw_clk(clk_data, base,
+					    &data->cfg[n]);
+		if (err) {
+			pr_err("%s: can't register  %s\n", __func__,
+			       data->cfg[n].name);
+
+			kfree(clk_data);
+
+			return err;
+		}
+	}
+
+	return of_clk_add_provider(np, of_clk_src_onecell_get, clk_data);
+}
+
+static void stm32mp1_rcc_init(struct device_node *np)
+{
+	void __iomem *base;
+
+	base = of_iomap(np, 0);
+	if (!base) {
+		pr_err("%pOFn: unable to map resource", np);
+		return;
+	}
+
+	stm32_rcc_init(np, base, stm32mp1_match_data);
+}
+
+CLK_OF_DECLARE_DRIVER(stm32mp1_rcc, "st,stm32mp1-rcc", stm32mp1_rcc_init);
-- 
2.20.1


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 17+ messages in thread

* [PATCH 12/14] ARM: stm32mp1: Add serial driver
  2019-03-11  9:31 [PATCH 00/14] Add initial STMicroelectronics MP1 support Sascha Hauer
                   ` (10 preceding siblings ...)
  2019-03-11  9:31 ` [PATCH 11/14] ARM: stm32mp1: Add clk driver Sascha Hauer
@ 2019-03-11  9:31 ` Sascha Hauer
  2019-03-11  9:31 ` [PATCH 13/14] clocksource: Enable architected timer support for CPU_V7 Sascha Hauer
  2019-03-11  9:31 ` [PATCH 14/14] ARM: Add initial STM32MP1 support Sascha Hauer
  13 siblings, 0 replies; 17+ messages in thread
From: Sascha Hauer @ 2019-03-11  9:31 UTC (permalink / raw)
  To: Barebox List

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
 drivers/serial/Kconfig        |   4 +
 drivers/serial/Makefile       |   1 +
 drivers/serial/serial_stm32.c | 246 ++++++++++++++++++++++++++++++++++
 drivers/serial/serial_stm32.h |  48 +++++++
 4 files changed, 299 insertions(+)
 create mode 100644 drivers/serial/serial_stm32.c
 create mode 100644 drivers/serial/serial_stm32.h

diff --git a/drivers/serial/Kconfig b/drivers/serial/Kconfig
index d462c11c16..f12ff93f6a 100644
--- a/drivers/serial/Kconfig
+++ b/drivers/serial/Kconfig
@@ -37,6 +37,10 @@ config DRIVER_SERIAL_IMX
 	default y
 	bool "i.MX serial driver"
 
+config DRIVER_SERIAL_STM32
+	depends on ARCH_STM32MP
+	bool "stm32mp serial driver"
+
 config DRIVER_SERIAL_STM378X
 	depends on ARCH_MXS
 	default y
diff --git a/drivers/serial/Makefile b/drivers/serial/Makefile
index 3d9f735ed2..4174cc1ffb 100644
--- a/drivers/serial/Makefile
+++ b/drivers/serial/Makefile
@@ -13,6 +13,7 @@ obj-$(CONFIG_DRIVER_SERIAL_CLPS711X)		+= serial_clps711x.o
 obj-$(CONFIG_DRIVER_SERIAL_NS16550)		+= serial_ns16550.o
 obj-$(CONFIG_DRIVER_SERIAL_PL010)		+= serial_pl010.o
 obj-$(CONFIG_DRIVER_SERIAL_S3C)			+= serial_s3c.o
+obj-$(CONFIG_DRIVER_SERIAL_STM32)		+= serial_stm32.o
 obj-$(CONFIG_DRIVER_SERIAL_ALTERA)		+= serial_altera.o
 obj-$(CONFIG_DRIVER_SERIAL_ALTERA_JTAG)		+= serial_altera_jtag.o
 obj-$(CONFIG_DRIVER_SERIAL_PXA)			+= serial_pxa.o
diff --git a/drivers/serial/serial_stm32.c b/drivers/serial/serial_stm32.c
new file mode 100644
index 0000000000..a84e64e974
--- /dev/null
+++ b/drivers/serial/serial_stm32.c
@@ -0,0 +1,246 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2016, STMicroelectronics - All Rights Reserved
+ * Author(s): Vikas Manocha, <vikas.manocha@st.com> for STMicroelectronics.
+ */
+
+#include <common.h>
+#include <console.h>
+#include <io.h>
+#include <linux/clk.h>
+#include <init.h>
+#include <driver.h>
+#include "serial_stm32.h"
+
+struct stm32_uart_info {
+	u8 uart_enable_bit;	/* UART_CR1_UE */
+	bool stm32f4;		/* true for STM32F4, false otherwise */
+	bool has_fifo;
+};
+
+struct stm32_uart {
+	struct console_device cdev;
+	void __iomem *base;
+	struct clk *clk;
+	bool stm32f4;
+	bool has_fifo;
+	int uart_enable_bit;
+};
+
+static struct stm32_uart *to_stm32_uart(struct console_device *cdev)
+{
+	return container_of(cdev, struct stm32_uart, cdev);
+}
+
+static int stm32_serial_setbaudrate(struct console_device *cdev, int baudrate)
+{
+	struct stm32_uart *stm32 = to_stm32_uart(cdev);
+	void __iomem *base = stm32->base;
+	bool stm32f4 = stm32->stm32f4;
+	u32 int_div, mantissa, fraction, oversampling;
+	unsigned long clock_rate;
+
+	clock_rate = clk_get_rate(stm32->clk);
+
+	int_div = DIV_ROUND_CLOSEST(clock_rate, baudrate);
+
+	if (int_div < 16) {
+		oversampling = 8;
+		setbits_le32(base + CR1_OFFSET(stm32f4), USART_CR1_OVER8);
+	} else {
+		oversampling = 16;
+		clrbits_le32(base + CR1_OFFSET(stm32f4), USART_CR1_OVER8);
+	}
+
+	mantissa = (int_div / oversampling) << USART_BRR_M_SHIFT;
+	fraction = int_div % oversampling;
+
+	writel(mantissa | fraction, base + BRR_OFFSET(stm32f4));
+
+	return 0;
+}
+
+static int stm32_serial_getc(struct console_device *cdev)
+{
+	struct stm32_uart *stm32 = to_stm32_uart(cdev);
+	void __iomem *base = stm32->base;
+	bool stm32f4 = stm32->stm32f4;
+	u32 isr = readl(base + ISR_OFFSET(stm32f4));
+
+	if ((isr & USART_ISR_RXNE) == 0)
+		return -EAGAIN;
+
+	if (isr & (USART_ISR_PE | USART_ISR_ORE)) {
+		if (!stm32f4)
+			setbits_le32(base + ICR_OFFSET,
+				     USART_ICR_PCECF | USART_ICR_ORECF);
+		else
+			readl(base + RDR_OFFSET(stm32f4));
+		return -EIO;
+	}
+
+	return readl(base + RDR_OFFSET(stm32f4));
+}
+
+static void stm32_serial_putc(struct console_device *cdev, char c)
+{
+	struct stm32_uart *stm32 = to_stm32_uart(cdev);
+	void __iomem *base = stm32->base;
+	bool stm32f4 = stm32->stm32f4;
+
+	while ((readl(base + ISR_OFFSET(stm32f4)) & USART_ISR_TXE) == 0);
+
+	writel(c, base + TDR_OFFSET(stm32f4));
+}
+
+static int stm32_serial_tstc(struct console_device *cdev)
+{
+	struct stm32_uart *stm32 = to_stm32_uart(cdev);
+	void __iomem *base = stm32->base;
+	bool stm32f4 = stm32->stm32f4;
+
+	return readl(base + ISR_OFFSET(stm32f4)) & USART_ISR_RXNE ? 1 : 0;
+}
+
+static void stm32_serial_flush(struct console_device *cdev)
+{
+	struct stm32_uart *stm32 = to_stm32_uart(cdev);
+	void __iomem *base = stm32->base;
+	bool stm32f4 = stm32->stm32f4;
+
+	while (!(readl(base + ISR_OFFSET(stm32f4)) & USART_ISR_TXE));
+}
+
+static void stm32_serial_init(struct console_device *cdev)
+{
+	struct stm32_uart *stm32 = to_stm32_uart(cdev);
+	void __iomem *base = stm32->base;
+	bool stm32f4 = stm32->stm32f4;
+	u8 uart_enable_bit = stm32->uart_enable_bit;
+	u32 cr1;
+
+	cr1 = readl(base + CR1_OFFSET(stm32f4));
+
+	/* Disable uart-> enable fifo -> enable uart */
+	cr1 &= ~(USART_CR1_RE | USART_CR1_TE | BIT(uart_enable_bit));
+
+	writel(cr1, base + CR1_OFFSET(stm32f4));
+
+	if (stm32->has_fifo)
+		cr1 |= USART_CR1_FIFOEN;
+
+	cr1 &= ~(USART_CR1_PCE | USART_CR1_PS | USART_CR1_M1 | USART_CR1_M0);
+
+	cr1 |= USART_CR1_RE | USART_CR1_TE | BIT(uart_enable_bit);
+
+	writel(cr1, base + CR1_OFFSET(stm32f4));
+}
+
+static int stm32_serial_probe(struct device_d *dev)
+{
+	int ret;
+	struct console_device *cdev;
+	struct stm32_uart *stm32;
+	const char *devname;
+	struct resource *res;
+	struct stm32_uart_info *info;
+
+	ret = dev_get_drvdata(dev, (const void **)&info);
+	if (ret)
+		return ret;
+
+	stm32 = xzalloc(sizeof(*stm32));
+	cdev = &stm32->cdev;
+
+	res = dev_request_mem_resource(dev, 0);
+	if (IS_ERR(res)) {
+		ret = PTR_ERR(res);
+		goto err_free;
+	}
+	stm32->base = IOMEM(res->start);
+
+	stm32->has_fifo = info->has_fifo;
+	stm32->stm32f4 = info->stm32f4;
+	stm32->uart_enable_bit = info->uart_enable_bit;
+
+	stm32->clk = clk_get(dev, NULL);
+	if (IS_ERR(stm32->clk)) {
+		ret = PTR_ERR(stm32->clk);
+		dev_err(dev, "Failed to get UART clock %d\n", ret);
+		goto io_release;
+	}
+
+	ret = clk_enable(stm32->clk);
+	if (ret) {
+		dev_err(dev, "Failed to enable UART clock %d\n", ret);
+		goto io_release;
+	}
+
+	cdev->dev    = dev;
+	cdev->tstc   = stm32_serial_tstc;
+	cdev->putc   = stm32_serial_putc;
+	cdev->getc   = stm32_serial_getc;
+	cdev->flush  = stm32_serial_flush;
+	cdev->setbrg = stm32_serial_setbaudrate;
+
+	if (dev->device_node) {
+		devname = of_alias_get(dev->device_node);
+		if (devname) {
+			cdev->devname = xstrdup(devname);
+			cdev->devid   = DEVICE_ID_SINGLE;
+		}
+	}
+
+	stm32_serial_init(cdev);
+
+	ret = console_register(cdev);
+	if (!ret)
+		return 0;
+
+	clk_put(stm32->clk);
+io_release:
+	release_region(res);
+err_free:
+	free(stm32);
+
+	return ret;
+}
+
+struct stm32_uart_info stm32f4_info = {
+	.stm32f4 = true,
+	.uart_enable_bit = 13,
+	.has_fifo = false,
+};
+
+struct stm32_uart_info stm32f7_info = {
+	.uart_enable_bit = 0,
+	.stm32f4 = false,
+	.has_fifo = true,
+};
+
+struct stm32_uart_info stm32h7_info = {
+	.uart_enable_bit = 0,
+	.stm32f4 = false,
+	.has_fifo = true,
+};
+
+static struct of_device_id stm32_serial_dt_ids[] = {
+	{
+		.compatible = "st,stm32-uart",
+		.data = &stm32f4_info
+	}, {
+		.compatible = "st,stm32f7-uart",
+		.data = &stm32f7_info
+	}, {
+		.compatible = "st,stm32h7-uart",
+		.data = &stm32h7_info
+	}, {
+	}
+};
+
+static struct driver_d stm32_serial_driver = {
+	.name   = "stm32-serial",
+	.probe  = stm32_serial_probe,
+	.of_compatible = DRV_OF_COMPAT(stm32_serial_dt_ids),
+};
+console_platform_driver(stm32_serial_driver);
diff --git a/drivers/serial/serial_stm32.h b/drivers/serial/serial_stm32.h
new file mode 100644
index 0000000000..dd3e930c93
--- /dev/null
+++ b/drivers/serial/serial_stm32.h
@@ -0,0 +1,48 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Copyright (C) 2016, STMicroelectronics - All Rights Reserved
+ * Author(s): Vikas Manocha, <vikas.manocha@st.com> for STMicroelectronics.
+ */
+
+#ifndef _SERIAL_STM32_
+#define _SERIAL_STM32_
+
+#define CR1_OFFSET(x)	(x ? 0x0c : 0x00)
+#define CR3_OFFSET(x)	(x ? 0x14 : 0x08)
+#define BRR_OFFSET(x)	(x ? 0x08 : 0x0c)
+#define ISR_OFFSET(x)	(x ? 0x00 : 0x1c)
+
+#define ICR_OFFSET	0x20
+
+/*
+ * STM32F4 has one Data Register (DR) for received or transmitted
+ * data, so map Receive Data Register (RDR) and Transmit Data
+ * Register (TDR) at the same offset
+ */
+#define RDR_OFFSET(x)	(x ? 0x04 : 0x24)
+#define TDR_OFFSET(x)	(x ? 0x04 : 0x28)
+
+#define USART_CR1_FIFOEN		BIT(29)
+#define USART_CR1_M1			BIT(28)
+#define USART_CR1_OVER8			BIT(15)
+#define USART_CR1_M0			BIT(12)
+#define USART_CR1_PCE			BIT(10)
+#define USART_CR1_PS			BIT(9)
+#define USART_CR1_TE			BIT(3)
+#define USART_CR1_RE			BIT(2)
+
+#define USART_CR3_OVRDIS		BIT(12)
+
+#define USART_ISR_TXE			BIT(7)
+#define USART_ISR_RXNE			BIT(5)
+#define USART_ISR_ORE			BIT(3)
+#define USART_ISR_PE			BIT(0)
+
+#define USART_BRR_F_MASK		GENMASK(7, 0)
+#define USART_BRR_M_SHIFT		4
+#define USART_BRR_M_MASK		GENMASK(15, 4)
+
+#define USART_ICR_ORECF			BIT(3)
+#define USART_ICR_PCECF			BIT(0)
+
+#endif
-- 
2.20.1


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 17+ messages in thread

* [PATCH 13/14] clocksource: Enable architected timer support for CPU_V7
  2019-03-11  9:31 [PATCH 00/14] Add initial STMicroelectronics MP1 support Sascha Hauer
                   ` (11 preceding siblings ...)
  2019-03-11  9:31 ` [PATCH 12/14] ARM: stm32mp1: Add serial driver Sascha Hauer
@ 2019-03-11  9:31 ` Sascha Hauer
  2019-03-11  9:31 ` [PATCH 14/14] ARM: Add initial STM32MP1 support Sascha Hauer
  13 siblings, 0 replies; 17+ messages in thread
From: Sascha Hauer @ 2019-03-11  9:31 UTC (permalink / raw)
  To: Barebox List

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
 arch/arm/include/asm/system.h     | 19 +++++++++++++++++++
 drivers/clocksource/Kconfig       |  2 +-
 drivers/clocksource/armv8-timer.c |  1 +
 3 files changed, 21 insertions(+), 1 deletion(-)

diff --git a/arch/arm/include/asm/system.h b/arch/arm/include/asm/system.h
index 45eeb6e62c..e55b19a13c 100644
--- a/arch/arm/include/asm/system.h
+++ b/arch/arm/include/asm/system.h
@@ -126,6 +126,25 @@ static inline unsigned long get_cntpct(void)
 
 	return cntpct;
 }
+#else
+static inline unsigned int get_cntfrq(void)
+{
+	unsigned int val;
+
+	asm volatile("mrc p15, 0, %0, c14, c0, 0" : "=r" (val));
+
+	return val;
+}
+
+static inline unsigned long long get_cntpct(void)
+{
+	unsigned long long cval;
+
+	isb();
+	asm volatile("mrrc p15, 0, %Q0, %R0, c14" : "=r" (cval));
+
+	return cval;
+}
 
 #endif
 static inline unsigned int get_cr(void)
diff --git a/drivers/clocksource/Kconfig b/drivers/clocksource/Kconfig
index b0502c3036..43c5bfc973 100644
--- a/drivers/clocksource/Kconfig
+++ b/drivers/clocksource/Kconfig
@@ -73,7 +73,7 @@ config CLOCKSOURCE_ATMEL_PIT
 config CLOCKSOURCE_ARMV8_TIMER
 	bool
 	default y
-	depends on ARM && CPU_64v8
+	depends on ARM && (CPU_64v8 || CPU_V7)
 
 config CLOCKSOURCE_ARM_GLOBAL_TIMER
 	bool
diff --git a/drivers/clocksource/armv8-timer.c b/drivers/clocksource/armv8-timer.c
index 918232e0e0..3095f8cfc4 100644
--- a/drivers/clocksource/armv8-timer.c
+++ b/drivers/clocksource/armv8-timer.c
@@ -39,6 +39,7 @@ static int armv8_timer_probe(struct device_d *dev)
 }
 
 static struct of_device_id armv8_timer_dt_ids[] = {
+	{ .compatible = "arm,armv7-timer", },
 	{ .compatible = "arm,armv8-timer", },
 	{ }
 };
-- 
2.20.1


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 17+ messages in thread

* [PATCH 14/14] ARM: Add initial STM32MP1 support
  2019-03-11  9:31 [PATCH 00/14] Add initial STMicroelectronics MP1 support Sascha Hauer
                   ` (12 preceding siblings ...)
  2019-03-11  9:31 ` [PATCH 13/14] clocksource: Enable architected timer support for CPU_V7 Sascha Hauer
@ 2019-03-11  9:31 ` Sascha Hauer
  2019-03-12  1:41   ` Andrey Smirnov
  13 siblings, 1 reply; 17+ messages in thread
From: Sascha Hauer @ 2019-03-11  9:31 UTC (permalink / raw)
  To: Barebox List

This adds initial STMicroelectronics MP1 support along with support
for the DK2 devel board. Only very basic support:

- UART
- SDRAM memory base/size
- No 1st stage support

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
 arch/arm/Kconfig                              | 11 +++
 arch/arm/Makefile                             |  1 +
 arch/arm/boards/Makefile                      |  1 +
 arch/arm/boards/stm32mp157c-dk2/Makefile      |  2 +
 arch/arm/boards/stm32mp157c-dk2/board.c       | 16 +++
 arch/arm/boards/stm32mp157c-dk2/lowlevel.c    | 18 ++++
 arch/arm/configs/stm32mp1_defconfig           | 98 +++++++++++++++++++
 arch/arm/dts/Makefile                         |  1 +
 arch/arm/dts/stm32mp157a-dk1.dts              | 62 ++++++++++++
 arch/arm/dts/stm32mp157c-dk2.dts              | 14 +++
 arch/arm/dts/stm32mp157c.dtsi                 |  7 ++
 arch/arm/mach-stm32mp1/Kconfig                | 10 ++
 arch/arm/mach-stm32mp1/Makefile               |  1 +
 .../arm/mach-stm32mp1/include/mach/debug_ll.h | 28 ++++++
 arch/arm/mach-stm32mp1/include/mach/stm32.h   | 35 +++++++
 images/Makefile                               |  1 +
 images/Makefile.stm32mp1                      |  8 ++
 17 files changed, 314 insertions(+)
 create mode 100644 arch/arm/boards/stm32mp157c-dk2/Makefile
 create mode 100644 arch/arm/boards/stm32mp157c-dk2/board.c
 create mode 100644 arch/arm/boards/stm32mp157c-dk2/lowlevel.c
 create mode 100644 arch/arm/configs/stm32mp1_defconfig
 create mode 100644 arch/arm/dts/stm32mp157a-dk1.dts
 create mode 100644 arch/arm/dts/stm32mp157c-dk2.dts
 create mode 100644 arch/arm/dts/stm32mp157c.dtsi
 create mode 100644 arch/arm/mach-stm32mp1/Kconfig
 create mode 100644 arch/arm/mach-stm32mp1/Makefile
 create mode 100644 arch/arm/mach-stm32mp1/include/mach/debug_ll.h
 create mode 100644 arch/arm/mach-stm32mp1/include/mach/stm32.h
 create mode 100644 images/Makefile.stm32mp1

diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 9d3f5b2ca7..6e5f431e29 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -198,6 +198,16 @@ config ARCH_S3C64xx
 	select CPU_V6
 	select GENERIC_GPIO
 
+config ARCH_STM32MP1
+	bool "ST stm32mp1xx"
+	select CPU_V7
+	select HAVE_PBL_MULTI_IMAGES
+	select CLKDEV_LOOKUP
+	select COMMON_CLK
+	select COMMON_CLK_OF_PROVIDER
+	select HAS_DEBUG_LL
+	select HAVE_CLK
+
 config ARCH_VERSATILE
 	bool "ARM Versatile boards (ARM926EJ-S)"
 	select GPIOLIB
@@ -284,6 +294,7 @@ source arch/arm/mach-pxa/Kconfig
 source arch/arm/mach-rockchip/Kconfig
 source arch/arm/mach-samsung/Kconfig
 source arch/arm/mach-socfpga/Kconfig
+source arch/arm/mach-stm32mp1/Kconfig
 source arch/arm/mach-versatile/Kconfig
 source arch/arm/mach-vexpress/Kconfig
 source arch/arm/mach-tegra/Kconfig
diff --git a/arch/arm/Makefile b/arch/arm/Makefile
index 6b5f21a7a9..9b0e34f50b 100644
--- a/arch/arm/Makefile
+++ b/arch/arm/Makefile
@@ -96,6 +96,7 @@ machine-$(CONFIG_ARCH_PXA)		:= pxa
 machine-$(CONFIG_ARCH_ROCKCHIP)		:= rockchip
 machine-$(CONFIG_ARCH_SAMSUNG)		:= samsung
 machine-$(CONFIG_ARCH_SOCFPGA)		:= socfpga
+machine-$(CONFIG_ARCH_STM32MP1)		:= stm32mp1
 machine-$(CONFIG_ARCH_VERSATILE)	:= versatile
 machine-$(CONFIG_ARCH_VEXPRESS)		:= vexpress
 machine-$(CONFIG_ARCH_TEGRA)		:= tegra
diff --git a/arch/arm/boards/Makefile b/arch/arm/boards/Makefile
index c5dc41526b..5193edff9f 100644
--- a/arch/arm/boards/Makefile
+++ b/arch/arm/boards/Makefile
@@ -123,6 +123,7 @@ obj-$(CONFIG_MACH_SOCFPGA_TERASIC_DE0_NANO_SOC)	+= terasic-de0-nano-soc/
 obj-$(CONFIG_MACH_SOCFPGA_TERASIC_SOCKIT)	+= terasic-sockit/
 obj-$(CONFIG_MACH_SOLIDRUN_CUBOX)		+= solidrun-cubox/
 obj-$(CONFIG_MACH_SOLIDRUN_MICROSOM)		+= solidrun-microsom/
+obj-$(CONFIG_MACH_STM32MP157C_DK2)		+= stm32mp157c-dk2/
 obj-$(CONFIG_MACH_TECHNEXION_PICO_HOBBIT)	+= technexion-pico-hobbit/
 obj-$(CONFIG_MACH_TECHNEXION_WANDBOARD)		+= technexion-wandboard/
 obj-$(CONFIG_MACH_TNY_A9260)			+= tny-a926x/
diff --git a/arch/arm/boards/stm32mp157c-dk2/Makefile b/arch/arm/boards/stm32mp157c-dk2/Makefile
new file mode 100644
index 0000000000..092c31d6b2
--- /dev/null
+++ b/arch/arm/boards/stm32mp157c-dk2/Makefile
@@ -0,0 +1,2 @@
+lwl-y += lowlevel.o
+obj-y += board.o
diff --git a/arch/arm/boards/stm32mp157c-dk2/board.c b/arch/arm/boards/stm32mp157c-dk2/board.c
new file mode 100644
index 0000000000..278a0c0126
--- /dev/null
+++ b/arch/arm/boards/stm32mp157c-dk2/board.c
@@ -0,0 +1,16 @@
+// SPDX-License-Identifier: GPL-2.0+
+#include <common.h>
+#include <linux/sizes.h>
+#include <init.h>
+#include <asm/memory.h>
+
+static int dk2_postcore_init(void)
+{
+	if (!of_machine_is_compatible("st,stm32mp157c-dk2"))
+		return 0;
+
+	arm_add_mem_device("ram0", 0xc0000000, SZ_512M);
+
+	return 0;
+}
+mem_initcall(dk2_postcore_init);
diff --git a/arch/arm/boards/stm32mp157c-dk2/lowlevel.c b/arch/arm/boards/stm32mp157c-dk2/lowlevel.c
new file mode 100644
index 0000000000..be12160a0b
--- /dev/null
+++ b/arch/arm/boards/stm32mp157c-dk2/lowlevel.c
@@ -0,0 +1,18 @@
+// SPDX-License-Identifier: GPL-2.0+
+#include <common.h>
+#include <asm/barebox-arm-head.h>
+#include <asm/barebox-arm.h>
+#include <debug_ll.h>
+
+extern char __dtb_stm32mp157c_dk2_start[];
+
+ENTRY_FUNCTION(start_stm32mp157c_dk2, r0, r1, r2)
+{
+	void *fdt;
+
+	arm_cpu_lowlevel_init();
+
+	fdt = __dtb_stm32mp157c_dk2_start + get_runtime_offset();
+
+	barebox_arm_entry(0xc0000000, SZ_512M, fdt);
+}
diff --git a/arch/arm/configs/stm32mp1_defconfig b/arch/arm/configs/stm32mp1_defconfig
new file mode 100644
index 0000000000..2922ce3632
--- /dev/null
+++ b/arch/arm/configs/stm32mp1_defconfig
@@ -0,0 +1,98 @@
+CONFIG_ARCH_STM32MP1=y
+CONFIG_MACH_STM32MP157C_DK2=y
+CONFIG_THUMB2_BAREBOX=y
+CONFIG_ARM_BOARD_APPEND_ATAG=y
+CONFIG_ARM_OPTIMZED_STRING_FUNCTIONS=y
+CONFIG_ARM_UNWIND=y
+CONFIG_ARM_PSCI=y
+CONFIG_MMU=y
+CONFIG_MALLOC_SIZE=0x0
+CONFIG_MALLOC_TLSF=y
+CONFIG_KALLSYMS=y
+CONFIG_RELOCATABLE=y
+CONFIG_HUSH_FANCY_PROMPT=y
+CONFIG_CMDLINE_EDITING=y
+CONFIG_AUTO_COMPLETE=y
+CONFIG_MENU=y
+CONFIG_BOOTM_SHOW_TYPE=y
+CONFIG_BOOTM_VERBOSE=y
+CONFIG_BOOTM_INITRD=y
+CONFIG_BOOTM_OFTREE=y
+CONFIG_BOOTM_OFTREE_UIMAGE=y
+CONFIG_BLSPEC=y
+CONFIG_CONSOLE_ACTIVATE_NONE=y
+CONFIG_CONSOLE_ALLOW_COLOR=y
+CONFIG_PBL_CONSOLE=y
+CONFIG_PARTITION=y
+CONFIG_DEFAULT_ENVIRONMENT_GENERIC_NEW=y
+CONFIG_POLLER=y
+CONFIG_RESET_SOURCE=y
+CONFIG_DEBUG_INITCALLS=y
+CONFIG_CMD_DMESG=y
+CONFIG_LONGHELP=y
+CONFIG_CMD_IOMEM=y
+CONFIG_CMD_IMD=y
+CONFIG_CMD_MEMINFO=y
+CONFIG_CMD_ARM_MMUINFO=y
+# CONFIG_CMD_BOOTU is not set
+CONFIG_CMD_GO=y
+CONFIG_CMD_RESET=y
+CONFIG_CMD_UIMAGE=y
+CONFIG_CMD_PARTITION=y
+CONFIG_CMD_EXPORT=y
+CONFIG_CMD_LOADENV=y
+CONFIG_CMD_PRINTENV=y
+CONFIG_CMD_MAGICVAR=y
+CONFIG_CMD_MAGICVAR_HELP=y
+CONFIG_CMD_SAVEENV=y
+CONFIG_CMD_FILETYPE=y
+CONFIG_CMD_LN=y
+CONFIG_CMD_MD5SUM=y
+CONFIG_CMD_UNCOMPRESS=y
+CONFIG_CMD_LET=y
+CONFIG_CMD_MSLEEP=y
+CONFIG_CMD_READF=y
+CONFIG_CMD_SLEEP=y
+CONFIG_CMD_DHCP=y
+CONFIG_CMD_MIITOOL=y
+CONFIG_CMD_PING=y
+CONFIG_CMD_TFTP=y
+CONFIG_CMD_ECHO_E=y
+CONFIG_CMD_EDIT=y
+CONFIG_CMD_MENU=y
+CONFIG_CMD_MENU_MANAGEMENT=y
+CONFIG_CMD_MENUTREE=y
+CONFIG_CMD_READLINE=y
+CONFIG_CMD_TIMEOUT=y
+CONFIG_CMD_CRC=y
+CONFIG_CMD_CRC_CMP=y
+CONFIG_CMD_MEMTEST=y
+CONFIG_CMD_MM=y
+CONFIG_CMD_CLK=y
+CONFIG_CMD_DETECT=y
+CONFIG_CMD_FLASH=y
+CONFIG_CMD_BAREBOX_UPDATE=y
+CONFIG_CMD_OF_NODE=y
+CONFIG_CMD_OF_PROPERTY=y
+CONFIG_CMD_OFTREE=y
+CONFIG_CMD_TIME=y
+CONFIG_NET=y
+CONFIG_NET_NETCONSOLE=y
+CONFIG_OFDEVICE=y
+CONFIG_OF_BAREBOX_DRIVERS=y
+CONFIG_DRIVER_SERIAL_STM32=y
+CONFIG_DRIVER_NET_DESIGNWARE=y
+CONFIG_DRIVER_NET_DESIGNWARE_GENERIC=y
+CONFIG_AT803X_PHY=y
+CONFIG_MICREL_PHY=y
+# CONFIG_SPI is not set
+# CONFIG_PINCTRL is not set
+CONFIG_FS_EXT4=y
+CONFIG_FS_TFTP=y
+CONFIG_FS_NFS=y
+CONFIG_FS_FAT=y
+CONFIG_FS_FAT_WRITE=y
+CONFIG_FS_FAT_LFN=y
+CONFIG_ZLIB=y
+CONFIG_LZO_DECOMPRESS=y
+CONFIG_CRC8=y
diff --git a/arch/arm/dts/Makefile b/arch/arm/dts/Makefile
index f989df6b0c..c89efeaf85 100644
--- a/arch/arm/dts/Makefile
+++ b/arch/arm/dts/Makefile
@@ -89,6 +89,7 @@ pbl-dtb-$(CONFIG_MACH_SOLIDRUN_CUBOX) += dove-cubox-bb.dtb.o
 pbl-dtb-$(CONFIG_MACH_SOLIDRUN_MICROSOM) += imx6dl-hummingboard.dtb.o imx6q-hummingboard.dtb.o \
 				imx6dl-hummingboard2.dtb.o imx6q-hummingboard2.dtb.o \
 				imx6q-h100.dtb.o
+pbl-dtb-$(CONFIG_MACH_STM32MP157C_DK2) += stm32mp157c-dk2.dtb.o
 pbl-dtb-$(CONFIG_MACH_TECHNEXION_WANDBOARD) += imx6q-wandboard.dtb.o imx6dl-wandboard.dtb.o
 pbl-dtb-$(CONFIG_MACH_TECHNEXION_PICO_HOBBIT) += imx6ul-pico-hobbit.dtb.o
 pbl-dtb-$(CONFIG_MACH_NXP_IMX6ULL_EVK) += imx6ull-14x14-evk.dtb.o
diff --git a/arch/arm/dts/stm32mp157a-dk1.dts b/arch/arm/dts/stm32mp157a-dk1.dts
new file mode 100644
index 0000000000..741284a444
--- /dev/null
+++ b/arch/arm/dts/stm32mp157a-dk1.dts
@@ -0,0 +1,62 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause)
+/*
+ * Copyright (C) STMicroelectronics 2018 - All Rights Reserved
+ * Author: Alexandre Torgue <alexandre.torgue@st.com>.
+ */
+
+/dts-v1/;
+
+#include "stm32mp157c.dtsi"
+#include <arm/stm32mp157c.dtsi>
+#include <arm/stm32mp157-pinctrl.dtsi>
+
+/ {
+	model = "STMicroelectronics STM32MP157A-DK1 Discovery Board";
+	compatible = "st,stm32mp157a-dk1", "st,stm32mp157";
+
+	aliases {
+		ethernet0 = &ethernet0;
+		serial0 = &uart4;
+	};
+
+	chosen {
+		stdout-path = "serial0:115200n8";
+	};
+
+	sram: sram@10050000 {
+		compatible = "mmio-sram";
+		reg = <0x10050000 0x10000>;
+		#address-cells = <1>;
+		#size-cells = <1>;
+		ranges = <0 0x10050000 0x10000>;
+
+		dma_pool: dma_pool@0 {
+			reg = <0x0 0x10000>;
+			pool;
+		};
+	};
+};
+
+&ethernet0 {
+	status = "okay";
+	pinctrl-0 = <&ethernet0_rgmii_pins_a>;
+	pinctrl-names = "default", "sleep";
+	phy-mode = "rgmii";
+	max-speed = <1000>;
+	phy-handle = <&phy0>;
+
+	mdio0 {
+		#address-cells = <1>;
+		#size-cells = <0>;
+		compatible = "snps,dwmac-mdio";
+		phy0: ethernet-phy@0 {
+			reg = <0>;
+		};
+	};
+};
+
+&uart4 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&uart4_pins_a>;
+	status = "okay";
+};
diff --git a/arch/arm/dts/stm32mp157c-dk2.dts b/arch/arm/dts/stm32mp157c-dk2.dts
new file mode 100644
index 0000000000..7565cabc3d
--- /dev/null
+++ b/arch/arm/dts/stm32mp157c-dk2.dts
@@ -0,0 +1,14 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause)
+/*
+ * Copyright (C) STMicroelectronics 2018 - All Rights Reserved
+ * Author: Alexandre Torgue <alexandre.torgue@st.com>.
+ */
+
+/dts-v1/;
+
+#include "stm32mp157a-dk1.dts"
+
+/ {
+	model = "STMicroelectronics STM32MP157C-DK2 Discovery Board";
+	compatible = "st,stm32mp157c-dk2", "st,stm32mp157";
+};
diff --git a/arch/arm/dts/stm32mp157c.dtsi b/arch/arm/dts/stm32mp157c.dtsi
new file mode 100644
index 0000000000..fa0d00ff02
--- /dev/null
+++ b/arch/arm/dts/stm32mp157c.dtsi
@@ -0,0 +1,7 @@
+
+/ {
+	clocks {
+		/* Needed to let barebox find the clock nodes */
+		compatible = "simple-bus";
+	};
+};
diff --git a/arch/arm/mach-stm32mp1/Kconfig b/arch/arm/mach-stm32mp1/Kconfig
new file mode 100644
index 0000000000..cc7cf23cfb
--- /dev/null
+++ b/arch/arm/mach-stm32mp1/Kconfig
@@ -0,0 +1,10 @@
+if ARCH_STM32MP1
+
+config ARCH_STM32MP1157
+	bool
+
+config MACH_STM32MP157C_DK2
+	select ARCH_STM32MP1157
+	bool "STM32MP157C-DK2 board"
+
+endif
diff --git a/arch/arm/mach-stm32mp1/Makefile b/arch/arm/mach-stm32mp1/Makefile
new file mode 100644
index 0000000000..16a218658a
--- /dev/null
+++ b/arch/arm/mach-stm32mp1/Makefile
@@ -0,0 +1 @@
+obj- := __dummy__.o
diff --git a/arch/arm/mach-stm32mp1/include/mach/debug_ll.h b/arch/arm/mach-stm32mp1/include/mach/debug_ll.h
new file mode 100644
index 0000000000..99fedb91fe
--- /dev/null
+++ b/arch/arm/mach-stm32mp1/include/mach/debug_ll.h
@@ -0,0 +1,28 @@
+#ifndef __MACH_STM32MP1_DEBUG_LL_H
+#define __MACH_STM32MP1_DEBUG_LL_H
+
+#include <io.h>
+#include <mach/stm32.h>
+
+#define DEBUG_LL_UART_ADDR	STM32_UART4_BASE
+
+#define CR1_OFFSET	0x00
+#define CR3_OFFSET	0x08
+#define BRR_OFFSET	0x0c
+#define ISR_OFFSET	0x1c
+#define ICR_OFFSET	0x20
+#define RDR_OFFSET	0x24
+#define TDR_OFFSET	0x28
+
+#define USART_ISR_TXE	BIT(7)
+
+static inline void PUTC_LL(int c)
+{
+	void __iomem *base = IOMEM(DEBUG_LL_UART_ADDR);
+
+	writel(c, base + TDR_OFFSET);
+
+	while ((readl(base + ISR_OFFSET) & USART_ISR_TXE) == 0);
+}
+
+#endif /* __MACH_STM32MP1_DEBUG_LL_H */
diff --git a/arch/arm/mach-stm32mp1/include/mach/stm32.h b/arch/arm/mach-stm32mp1/include/mach/stm32.h
new file mode 100644
index 0000000000..f9bdb788b9
--- /dev/null
+++ b/arch/arm/mach-stm32mp1/include/mach/stm32.h
@@ -0,0 +1,35 @@
+/* SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause */
+/*
+ * Copyright (C) 2018, STMicroelectronics - All Rights Reserved
+ */
+
+#ifndef _MACH_STM32_H_
+#define _MACH_STM32_H_
+
+/*
+ * Peripheral memory map
+ */
+#define STM32_RCC_BASE			0x50000000
+#define STM32_PWR_BASE			0x50001000
+#define STM32_DBGMCU_BASE		0x50081000
+#define STM32_BSEC_BASE			0x5C005000
+#define STM32_TZC_BASE			0x5C006000
+#define STM32_ETZPC_BASE		0x5C007000
+#define STM32_TAMP_BASE			0x5C00A000
+
+#define STM32_USART1_BASE		0x5C000000
+#define STM32_USART2_BASE		0x4000E000
+#define STM32_USART3_BASE		0x4000F000
+#define STM32_UART4_BASE		0x40010000
+#define STM32_UART5_BASE		0x40011000
+#define STM32_USART6_BASE		0x44003000
+#define STM32_UART7_BASE		0x40018000
+#define STM32_UART8_BASE		0x40019000
+
+#define STM32_SYSRAM_BASE		0x2FFC0000
+#define STM32_SYSRAM_SIZE		SZ_256K
+
+#define STM32_DDR_BASE			0xC0000000
+#define STM32_DDR_SIZE			SZ_1G
+
+#endif /* _MACH_STM32_H_ */
diff --git a/images/Makefile b/images/Makefile
index 59b81f9b6d..ea3f913c00 100644
--- a/images/Makefile
+++ b/images/Makefile
@@ -108,6 +108,7 @@ include $(srctree)/images/Makefile.mxs
 include $(srctree)/images/Makefile.omap3
 include $(srctree)/images/Makefile.rockchip
 include $(srctree)/images/Makefile.socfpga
+include $(srctree)/images/Makefile.stm32mp1
 include $(srctree)/images/Makefile.tegra
 include $(srctree)/images/Makefile.vexpress
 include $(srctree)/images/Makefile.xburst
diff --git a/images/Makefile.stm32mp1 b/images/Makefile.stm32mp1
new file mode 100644
index 0000000000..d26231cd92
--- /dev/null
+++ b/images/Makefile.stm32mp1
@@ -0,0 +1,8 @@
+# SPDX-License-Identifier: GPL-2.0-or-later
+#
+# barebox image generation Makefile for STMicroelectronics MP1
+#
+
+pblb-$(CONFIG_MACH_STM32MP157C_DK2) += start_stm32mp157c_dk2.pblb
+FILE_barebox-stm32mp157c-dk2.img = start_stm32mp157c_dk2.pblb
+image-$(CONFIG_MACH_STM32MP157C_DK2) += barebox-stm32mp157c-dk2.img
-- 
2.20.1


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [PATCH 14/14] ARM: Add initial STM32MP1 support
  2019-03-11  9:31 ` [PATCH 14/14] ARM: Add initial STM32MP1 support Sascha Hauer
@ 2019-03-12  1:41   ` Andrey Smirnov
  2019-03-13  8:35     ` Sascha Hauer
  0 siblings, 1 reply; 17+ messages in thread
From: Andrey Smirnov @ 2019-03-12  1:41 UTC (permalink / raw)
  To: Sascha Hauer; +Cc: Barebox List

On Mon, Mar 11, 2019 at 2:48 AM Sascha Hauer <s.hauer@pengutronix.de> wrote:
>
> This adds initial STMicroelectronics MP1 support along with support
> for the DK2 devel board. Only very basic support:
>
> - UART
> - SDRAM memory base/size
> - No 1st stage support
>
> Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
> ---
>  arch/arm/Kconfig                              | 11 +++
>  arch/arm/Makefile                             |  1 +
>  arch/arm/boards/Makefile                      |  1 +
>  arch/arm/boards/stm32mp157c-dk2/Makefile      |  2 +
>  arch/arm/boards/stm32mp157c-dk2/board.c       | 16 +++
>  arch/arm/boards/stm32mp157c-dk2/lowlevel.c    | 18 ++++
>  arch/arm/configs/stm32mp1_defconfig           | 98 +++++++++++++++++++
>  arch/arm/dts/Makefile                         |  1 +
>  arch/arm/dts/stm32mp157a-dk1.dts              | 62 ++++++++++++
>  arch/arm/dts/stm32mp157c-dk2.dts              | 14 +++
>  arch/arm/dts/stm32mp157c.dtsi                 |  7 ++
>  arch/arm/mach-stm32mp1/Kconfig                | 10 ++
>  arch/arm/mach-stm32mp1/Makefile               |  1 +
>  .../arm/mach-stm32mp1/include/mach/debug_ll.h | 28 ++++++
>  arch/arm/mach-stm32mp1/include/mach/stm32.h   | 35 +++++++
>  images/Makefile                               |  1 +
>  images/Makefile.stm32mp1                      |  8 ++
>  17 files changed, 314 insertions(+)
>  create mode 100644 arch/arm/boards/stm32mp157c-dk2/Makefile
>  create mode 100644 arch/arm/boards/stm32mp157c-dk2/board.c
>  create mode 100644 arch/arm/boards/stm32mp157c-dk2/lowlevel.c
>  create mode 100644 arch/arm/configs/stm32mp1_defconfig
>  create mode 100644 arch/arm/dts/stm32mp157a-dk1.dts
>  create mode 100644 arch/arm/dts/stm32mp157c-dk2.dts
>  create mode 100644 arch/arm/dts/stm32mp157c.dtsi
>  create mode 100644 arch/arm/mach-stm32mp1/Kconfig
>  create mode 100644 arch/arm/mach-stm32mp1/Makefile
>  create mode 100644 arch/arm/mach-stm32mp1/include/mach/debug_ll.h
>  create mode 100644 arch/arm/mach-stm32mp1/include/mach/stm32.h
>  create mode 100644 images/Makefile.stm32mp1
>
> diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
> index 9d3f5b2ca7..6e5f431e29 100644
> --- a/arch/arm/Kconfig
> +++ b/arch/arm/Kconfig
> @@ -198,6 +198,16 @@ config ARCH_S3C64xx
>         select CPU_V6
>         select GENERIC_GPIO
>
> +config ARCH_STM32MP1
> +       bool "ST stm32mp1xx"
> +       select CPU_V7
> +       select HAVE_PBL_MULTI_IMAGES
> +       select CLKDEV_LOOKUP
> +       select COMMON_CLK
> +       select COMMON_CLK_OF_PROVIDER
> +       select HAS_DEBUG_LL
> +       select HAVE_CLK
> +
>  config ARCH_VERSATILE
>         bool "ARM Versatile boards (ARM926EJ-S)"
>         select GPIOLIB
> @@ -284,6 +294,7 @@ source arch/arm/mach-pxa/Kconfig
>  source arch/arm/mach-rockchip/Kconfig
>  source arch/arm/mach-samsung/Kconfig
>  source arch/arm/mach-socfpga/Kconfig
> +source arch/arm/mach-stm32mp1/Kconfig
>  source arch/arm/mach-versatile/Kconfig
>  source arch/arm/mach-vexpress/Kconfig
>  source arch/arm/mach-tegra/Kconfig
> diff --git a/arch/arm/Makefile b/arch/arm/Makefile
> index 6b5f21a7a9..9b0e34f50b 100644
> --- a/arch/arm/Makefile
> +++ b/arch/arm/Makefile
> @@ -96,6 +96,7 @@ machine-$(CONFIG_ARCH_PXA)            := pxa
>  machine-$(CONFIG_ARCH_ROCKCHIP)                := rockchip
>  machine-$(CONFIG_ARCH_SAMSUNG)         := samsung
>  machine-$(CONFIG_ARCH_SOCFPGA)         := socfpga
> +machine-$(CONFIG_ARCH_STM32MP1)                := stm32mp1
>  machine-$(CONFIG_ARCH_VERSATILE)       := versatile
>  machine-$(CONFIG_ARCH_VEXPRESS)                := vexpress
>  machine-$(CONFIG_ARCH_TEGRA)           := tegra
> diff --git a/arch/arm/boards/Makefile b/arch/arm/boards/Makefile
> index c5dc41526b..5193edff9f 100644
> --- a/arch/arm/boards/Makefile
> +++ b/arch/arm/boards/Makefile
> @@ -123,6 +123,7 @@ obj-$(CONFIG_MACH_SOCFPGA_TERASIC_DE0_NANO_SOC)     += terasic-de0-nano-soc/
>  obj-$(CONFIG_MACH_SOCFPGA_TERASIC_SOCKIT)      += terasic-sockit/
>  obj-$(CONFIG_MACH_SOLIDRUN_CUBOX)              += solidrun-cubox/
>  obj-$(CONFIG_MACH_SOLIDRUN_MICROSOM)           += solidrun-microsom/
> +obj-$(CONFIG_MACH_STM32MP157C_DK2)             += stm32mp157c-dk2/
>  obj-$(CONFIG_MACH_TECHNEXION_PICO_HOBBIT)      += technexion-pico-hobbit/
>  obj-$(CONFIG_MACH_TECHNEXION_WANDBOARD)                += technexion-wandboard/
>  obj-$(CONFIG_MACH_TNY_A9260)                   += tny-a926x/
> diff --git a/arch/arm/boards/stm32mp157c-dk2/Makefile b/arch/arm/boards/stm32mp157c-dk2/Makefile
> new file mode 100644
> index 0000000000..092c31d6b2
> --- /dev/null
> +++ b/arch/arm/boards/stm32mp157c-dk2/Makefile
> @@ -0,0 +1,2 @@
> +lwl-y += lowlevel.o
> +obj-y += board.o
> diff --git a/arch/arm/boards/stm32mp157c-dk2/board.c b/arch/arm/boards/stm32mp157c-dk2/board.c
> new file mode 100644
> index 0000000000..278a0c0126
> --- /dev/null
> +++ b/arch/arm/boards/stm32mp157c-dk2/board.c
> @@ -0,0 +1,16 @@
> +// SPDX-License-Identifier: GPL-2.0+
> +#include <common.h>
> +#include <linux/sizes.h>
> +#include <init.h>
> +#include <asm/memory.h>
> +
> +static int dk2_postcore_init(void)
> +{
> +       if (!of_machine_is_compatible("st,stm32mp157c-dk2"))
> +               return 0;
> +
> +       arm_add_mem_device("ram0", 0xc0000000, SZ_512M);
> +

Minor nit: I think you can replace 0xc0000000 with STM32_DDR_BASE.

> +       return 0;
> +}
> +mem_initcall(dk2_postcore_init);
> diff --git a/arch/arm/boards/stm32mp157c-dk2/lowlevel.c b/arch/arm/boards/stm32mp157c-dk2/lowlevel.c
> new file mode 100644
> index 0000000000..be12160a0b
> --- /dev/null
> +++ b/arch/arm/boards/stm32mp157c-dk2/lowlevel.c
> @@ -0,0 +1,18 @@
> +// SPDX-License-Identifier: GPL-2.0+
> +#include <common.h>
> +#include <asm/barebox-arm-head.h>
> +#include <asm/barebox-arm.h>
> +#include <debug_ll.h>
> +
> +extern char __dtb_stm32mp157c_dk2_start[];
> +
> +ENTRY_FUNCTION(start_stm32mp157c_dk2, r0, r1, r2)
> +{
> +       void *fdt;
> +
> +       arm_cpu_lowlevel_init();
> +
> +       fdt = __dtb_stm32mp157c_dk2_start + get_runtime_offset();
> +
> +       barebox_arm_entry(0xc0000000, SZ_512M, fdt);

Ditto.

Thanks,
Andrey Smirnov

_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [PATCH 14/14] ARM: Add initial STM32MP1 support
  2019-03-12  1:41   ` Andrey Smirnov
@ 2019-03-13  8:35     ` Sascha Hauer
  0 siblings, 0 replies; 17+ messages in thread
From: Sascha Hauer @ 2019-03-13  8:35 UTC (permalink / raw)
  To: Andrey Smirnov; +Cc: Barebox List

On Mon, Mar 11, 2019 at 06:41:59PM -0700, Andrey Smirnov wrote:
> > +static int dk2_postcore_init(void)
> > +{
> > +       if (!of_machine_is_compatible("st,stm32mp157c-dk2"))
> > +               return 0;
> > +
> > +       arm_add_mem_device("ram0", 0xc0000000, SZ_512M);
> > +
> 
> Minor nit: I think you can replace 0xc0000000 with STM32_DDR_BASE.

Indeed. Fixed, thanks

Sascha

-- 
Pengutronix e.K.                           |                             |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |

_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 17+ messages in thread

end of thread, other threads:[~2019-03-13  8:38 UTC | newest]

Thread overview: 17+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-03-11  9:31 [PATCH 00/14] Add initial STMicroelectronics MP1 support Sascha Hauer
2019-03-11  9:31 ` [PATCH 01/14] clk: clk-composite: return parent_rate if no rate clk Sascha Hauer
2019-03-11  9:31 ` [PATCH 02/14] clk: parent_names should be const Sascha Hauer
2019-03-11  9:31 ` [PATCH 03/14] clk: export clk_gate_is_enabled() Sascha Hauer
2019-03-11  9:31 ` [PATCH 04/14] clk: Make CLK_IGNORE_UNUSED generic Sascha Hauer
2019-03-11  9:31 ` [PATCH 05/14] clk: Support CLK_IS_CRITICAL flag Sascha Hauer
2019-03-11  9:31 ` [PATCH 06/14] clk: divider: pass divider flags Sascha Hauer
2019-03-11  9:31 ` [PATCH 07/14] clk: divider: Support CLK_DIVIDER_READ_ONLY flag Sascha Hauer
2019-03-11  9:31 ` [PATCH 08/14] clk: mux: Support mux specific flags Sascha Hauer
2019-03-11  9:31 ` [PATCH 09/14] clk: mux: Support CLK_MUX_READ_ONLY flag Sascha Hauer
2019-03-11  9:31 ` [PATCH 10/14] clk: mux: Support CLK_SET_RATE_NO_REPARENT flag Sascha Hauer
2019-03-11  9:31 ` [PATCH 11/14] ARM: stm32mp1: Add clk driver Sascha Hauer
2019-03-11  9:31 ` [PATCH 12/14] ARM: stm32mp1: Add serial driver Sascha Hauer
2019-03-11  9:31 ` [PATCH 13/14] clocksource: Enable architected timer support for CPU_V7 Sascha Hauer
2019-03-11  9:31 ` [PATCH 14/14] ARM: Add initial STM32MP1 support Sascha Hauer
2019-03-12  1:41   ` Andrey Smirnov
2019-03-13  8:35     ` Sascha Hauer

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox