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@xxxxxxxxx> --- 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@xxxxxxxxxxxxxxxxxxx http://lists.infradead.org/mailman/listinfo/barebox