mail archive of the barebox mailing list
 help / color / mirror / Atom feed
* [PATCH 1/2] ARM: i.MX7: Make sure CNTFRQ is initialized early enough
@ 2019-03-13  3:31 Andrey Smirnov
  2019-03-13  3:31 ` [PATCH 2/2] ARM: i.MX8MQ: Don't use cpu_is_mx8mq() at core_initcall level Andrey Smirnov
  2019-03-18  8:02 ` [PATCH 1/2] ARM: i.MX7: Make sure CNTFRQ is initialized early enough Sascha Hauer
  0 siblings, 2 replies; 3+ messages in thread
From: Andrey Smirnov @ 2019-03-13  3:31 UTC (permalink / raw)
  To: barebox; +Cc: Andrey Smirnov

We need to make sure that CNTFRQ is initialized before corresponding
clocksource driver tries to use it, otherwise we'll end up crashing
due to division by zero.

We can't convert imx7_timer_init() to be an initcall since it is an
i.MX7 specific task, but CPU type information won't be availible until
after imx_init() gets executed at postcore_initcall() level. To solve
this move all of the necessary code to be a part of
imx7_cpu_lowlevel_init().

Note, that original code both hardcoded frequency value to 8MHz as
well as tried to write it to the first element of the frequency mode
table which appears to be read-only on i.MX7. So while we are at it,
simplify the code by adding set_cntfrq() implementation for ARMv7 and
copy the code we already using for i.MX8MQ.

Fixes: dece70752 ("clocksource: Enable architected timer support for CPU_V7")
Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com>
---
 arch/arm/include/asm/system.h |  5 +++++
 arch/arm/mach-imx/cpu_init.c  | 13 +++++++++++++
 arch/arm/mach-imx/imx7.c      | 35 -----------------------------------
 3 files changed, 18 insertions(+), 35 deletions(-)

diff --git a/arch/arm/include/asm/system.h b/arch/arm/include/asm/system.h
index e55b19a13..ef9cb98bf 100644
--- a/arch/arm/include/asm/system.h
+++ b/arch/arm/include/asm/system.h
@@ -127,6 +127,11 @@ static inline unsigned long get_cntpct(void)
 	return cntpct;
 }
 #else
+static inline void set_cntfrq(unsigned long cntfrq)
+{
+	asm("mcr p15, 0, %0, c14, c0, 0" : : "r" (cntfrq));
+}
+
 static inline unsigned int get_cntfrq(void)
 {
 	unsigned int val;
diff --git a/arch/arm/mach-imx/cpu_init.c b/arch/arm/mach-imx/cpu_init.c
index f0d009dfd..ba45a1aef 100644
--- a/arch/arm/mach-imx/cpu_init.c
+++ b/arch/arm/mach-imx/cpu_init.c
@@ -15,7 +15,19 @@
 #include <asm/barebox-arm-head.h>
 #include <asm/errata.h>
 #include <linux/types.h>
+#include <linux/bitops.h>
 #include <mach/generic.h>
+#include <mach/imx7-regs.h>
+#include <common.h>
+#include <io.h>
+#include <asm/syscounter.h>
+#include <asm/system.h>
+
+static inline void imx_cpu_timer_init(void __iomem *syscnt)
+{
+	set_cntfrq(syscnt_get_cntfrq(syscnt));
+	syscnt_enable(syscnt);
+}
 
 #ifdef CONFIG_CPU_32
 void imx5_cpu_lowlevel_init(void)
@@ -47,6 +59,7 @@ void imx6ul_cpu_lowlevel_init(void)
 void imx7_cpu_lowlevel_init(void)
 {
 	arm_cpu_lowlevel_init();
+	imx_cpu_timer_init(IOMEM(MX7_SYSCNT_CTRL_BASE_ADDR));
 }
 
 void vf610_cpu_lowlevel_init(void)
diff --git a/arch/arm/mach-imx/imx7.c b/arch/arm/mach-imx/imx7.c
index ff2a828c7..d875bf44f 100644
--- a/arch/arm/mach-imx/imx7.c
+++ b/arch/arm/mach-imx/imx7.c
@@ -57,39 +57,6 @@ void imx7_init_lowlevel(void)
 	writel(0, aips3 + 0x50);
 }
 
-#define SC_CNTCR	0x0
-#define SC_CNTSR	0x4
-#define SC_CNTCV1	0x8
-#define SC_CNTCV2	0xc
-#define SC_CNTFID0	0x20
-#define SC_CNTFID1	0x24
-#define SC_CNTFID2	0x28
-#define SC_counterid	0xfcc
-
-#define SC_CNTCR_ENABLE         (1 << 0)
-#define SC_CNTCR_HDBG           (1 << 1)
-#define SC_CNTCR_FREQ0          (1 << 8)
-#define SC_CNTCR_FREQ1          (1 << 9)
-
-static int imx7_timer_init(void)
-{
-	void __iomem *sctr = IOMEM(MX7_SYSCNT_CTRL_BASE_ADDR);
-	unsigned long val, freq;
-
-	freq = 8000000;
-	asm("mcr p15, 0, %0, c14, c0, 0" : : "r" (freq));
-
-	writel(freq, sctr + SC_CNTFID0);
-
-	/* Enable system counter */
-	val = readl(sctr + SC_CNTCR);
-	val &= ~(SC_CNTCR_FREQ0 | SC_CNTCR_FREQ1);
-	val |= SC_CNTCR_FREQ0 | SC_CNTCR_ENABLE | SC_CNTCR_HDBG;
-	writel(val, sctr + SC_CNTCR);
-
-	return 0;
-}
-
 #define CSU_NUM_REGS               64
 #define CSU_INIT_SEC_LEVEL0        0x00FF00FF
 
@@ -186,8 +153,6 @@ int imx7_init(void)
 
 	imx7_init_csu();
 
-	imx7_timer_init();
-
 	imx7_boot_save_loc();
 
 	psci_set_ops(&imx7_psci_ops);
-- 
2.20.1


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

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

* [PATCH 2/2] ARM: i.MX8MQ: Don't use cpu_is_mx8mq() at core_initcall level
  2019-03-13  3:31 [PATCH 1/2] ARM: i.MX7: Make sure CNTFRQ is initialized early enough Andrey Smirnov
@ 2019-03-13  3:31 ` Andrey Smirnov
  2019-03-18  8:02 ` [PATCH 1/2] ARM: i.MX7: Make sure CNTFRQ is initialized early enough Sascha Hauer
  1 sibling, 0 replies; 3+ messages in thread
From: Andrey Smirnov @ 2019-03-13  3:31 UTC (permalink / raw)
  To: barebox; +Cc: Andrey Smirnov

Since __imx_cpu_type won't be initialized until
imx_init()@postcore_initcall is executed cpu_is_mx8mq() will only work
correctly at core_initcall level so long as imx_cpu_type does not
resolve into __imx_cpu_type. This is currently the case and
imx8mq_init_syscnt_frequency() works as expected, but it probably
won't be in the future.

To avoid this problem introduce imx8mq_cpu_lowlevel_init() and do
system counter frequency initialization there. Also convert all of the
i.MX8MQ boards to use this new function.

Fixes: 5691aed9a ("ARM: i.MX8MQ: Check CPU type in imx8mq_init_syscnt_frequency()")
Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com>
---
 arch/arm/boards/nxp-imx8mq-evk/lowlevel.c    |  2 +-
 arch/arm/boards/phytec-som-imx8mq/lowlevel.c |  2 +-
 arch/arm/boards/zii-imx8mq-dev/lowlevel.c    |  2 +-
 arch/arm/mach-imx/cpu_init.c                 |  9 ++++++++
 arch/arm/mach-imx/imx8mq.c                   | 22 --------------------
 arch/arm/mach-imx/include/mach/generic.h     |  1 +
 6 files changed, 13 insertions(+), 25 deletions(-)

diff --git a/arch/arm/boards/nxp-imx8mq-evk/lowlevel.c b/arch/arm/boards/nxp-imx8mq-evk/lowlevel.c
index ffbe14836..6451e5d41 100644
--- a/arch/arm/boards/nxp-imx8mq-evk/lowlevel.c
+++ b/arch/arm/boards/nxp-imx8mq-evk/lowlevel.c
@@ -89,7 +89,7 @@ static void nxp_imx8mq_evk_sram_setup(void)
  */
 ENTRY_FUNCTION(start_nxp_imx8mq_evk, r0, r1, r2)
 {
-	arm_cpu_lowlevel_init();
+	imx8mq_cpu_lowlevel_init();
 
 	if (IS_ENABLED(CONFIG_DEBUG_LL))
 		setup_uart();
diff --git a/arch/arm/boards/phytec-som-imx8mq/lowlevel.c b/arch/arm/boards/phytec-som-imx8mq/lowlevel.c
index cfee13f3e..e42e7a6fc 100644
--- a/arch/arm/boards/phytec-som-imx8mq/lowlevel.c
+++ b/arch/arm/boards/phytec-som-imx8mq/lowlevel.c
@@ -83,7 +83,7 @@ static void phytec_imx8mq_som_sram_setup(void)
  */
 ENTRY_FUNCTION(start_phytec_phycore_imx8mq, r0, r1, r2)
 {
-	arm_cpu_lowlevel_init();
+	imx8mq_cpu_lowlevel_init();
 
 	if (IS_ENABLED(CONFIG_DEBUG_LL))
 		setup_uart();
diff --git a/arch/arm/boards/zii-imx8mq-dev/lowlevel.c b/arch/arm/boards/zii-imx8mq-dev/lowlevel.c
index 059e4c9ef..0fd2ddfca 100644
--- a/arch/arm/boards/zii-imx8mq-dev/lowlevel.c
+++ b/arch/arm/boards/zii-imx8mq-dev/lowlevel.c
@@ -145,7 +145,7 @@ ENTRY_FUNCTION(start_zii_imx8mq_dev, r0, r1, r2)
 	unsigned int system_type;
 	void *fdt;
 
-	arm_cpu_lowlevel_init();
+	imx8mq_cpu_lowlevel_init();
 
 	if (IS_ENABLED(CONFIG_DEBUG_LL))
 		setup_uart();
diff --git a/arch/arm/mach-imx/cpu_init.c b/arch/arm/mach-imx/cpu_init.c
index ba45a1aef..7a980cf91 100644
--- a/arch/arm/mach-imx/cpu_init.c
+++ b/arch/arm/mach-imx/cpu_init.c
@@ -18,6 +18,7 @@
 #include <linux/bitops.h>
 #include <mach/generic.h>
 #include <mach/imx7-regs.h>
+#include <mach/imx8mq-regs.h>
 #include <common.h>
 #include <io.h>
 #include <asm/syscounter.h>
@@ -66,4 +67,12 @@ void vf610_cpu_lowlevel_init(void)
 {
 	arm_cpu_lowlevel_init();
 }
+#else
+void imx8mq_cpu_lowlevel_init(void)
+{
+	arm_cpu_lowlevel_init();
+
+	if (current_el() == 3)
+		imx_cpu_timer_init(IOMEM(MX8MQ_SYSCNT_CTRL_BASE_ADDR));
+}
 #endif
diff --git a/arch/arm/mach-imx/imx8mq.c b/arch/arm/mach-imx/imx8mq.c
index 3f6b433a5..089344528 100644
--- a/arch/arm/mach-imx/imx8mq.c
+++ b/arch/arm/mach-imx/imx8mq.c
@@ -27,28 +27,6 @@
 #define FSL_SIP_BUILDINFO			0xC2000003
 #define FSL_SIP_BUILDINFO_GET_COMMITHASH	0x00
 
-static int imx8mq_init_syscnt_frequency(void)
-{
-	if (!cpu_is_mx8mq())
-		return 0;
-
-	if (current_el() == 3) {
-		void __iomem *syscnt = IOMEM(MX8MQ_SYSCNT_CTRL_BASE_ADDR);
-		/*
-		 * Update with accurate clock frequency
-		 */
-		set_cntfrq(syscnt_get_cntfrq(syscnt));
-		syscnt_enable(syscnt);
-	}
-
-	return 0;
-}
-/*
- * This call needs to happen before timer driver gets probed and
- * requests its update frequency via cntfrq_el0
- */
-core_initcall(imx8mq_init_syscnt_frequency);
-
 int imx8mq_init(void)
 {
 	void __iomem *anatop = IOMEM(MX8MQ_ANATOP_BASE_ADDR);
diff --git a/arch/arm/mach-imx/include/mach/generic.h b/arch/arm/mach-imx/include/mach/generic.h
index be58da4da..ac066e3f1 100644
--- a/arch/arm/mach-imx/include/mach/generic.h
+++ b/arch/arm/mach-imx/include/mach/generic.h
@@ -58,6 +58,7 @@ void imx6_cpu_lowlevel_init(void);
 void imx6ul_cpu_lowlevel_init(void);
 void imx7_cpu_lowlevel_init(void);
 void vf610_cpu_lowlevel_init(void);
+void imx8mq_cpu_lowlevel_init(void);
 
 /* There's a off-by-one betweem the gpio bank number and the gpiochip */
 /* range e.g. GPIO_1_5 is gpio 5 under linux */
-- 
2.20.1


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

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

* Re: [PATCH 1/2] ARM: i.MX7: Make sure CNTFRQ is initialized early enough
  2019-03-13  3:31 [PATCH 1/2] ARM: i.MX7: Make sure CNTFRQ is initialized early enough Andrey Smirnov
  2019-03-13  3:31 ` [PATCH 2/2] ARM: i.MX8MQ: Don't use cpu_is_mx8mq() at core_initcall level Andrey Smirnov
@ 2019-03-18  8:02 ` Sascha Hauer
  1 sibling, 0 replies; 3+ messages in thread
From: Sascha Hauer @ 2019-03-18  8:02 UTC (permalink / raw)
  To: Andrey Smirnov; +Cc: barebox

On Tue, Mar 12, 2019 at 08:31:46PM -0700, Andrey Smirnov wrote:
> We need to make sure that CNTFRQ is initialized before corresponding
> clocksource driver tries to use it, otherwise we'll end up crashing
> due to division by zero.
> 
> We can't convert imx7_timer_init() to be an initcall since it is an
> i.MX7 specific task, but CPU type information won't be availible until
> after imx_init() gets executed at postcore_initcall() level. To solve
> this move all of the necessary code to be a part of
> imx7_cpu_lowlevel_init().
> 
> Note, that original code both hardcoded frequency value to 8MHz as
> well as tried to write it to the first element of the frequency mode
> table which appears to be read-only on i.MX7. So while we are at it,
> simplify the code by adding set_cntfrq() implementation for ARMv7 and
> copy the code we already using for i.MX8MQ.
> 
> Fixes: dece70752 ("clocksource: Enable architected timer support for CPU_V7")
> Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com>
> ---
>  arch/arm/include/asm/system.h |  5 +++++
>  arch/arm/mach-imx/cpu_init.c  | 13 +++++++++++++
>  arch/arm/mach-imx/imx7.c      | 35 -----------------------------------
>  3 files changed, 18 insertions(+), 35 deletions(-)

Applied, 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] 3+ messages in thread

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

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-03-13  3:31 [PATCH 1/2] ARM: i.MX7: Make sure CNTFRQ is initialized early enough Andrey Smirnov
2019-03-13  3:31 ` [PATCH 2/2] ARM: i.MX8MQ: Don't use cpu_is_mx8mq() at core_initcall level Andrey Smirnov
2019-03-18  8:02 ` [PATCH 1/2] ARM: i.MX7: Make sure CNTFRQ is initialized early enough Sascha Hauer

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