On 7/24/26 9:36 AM, Emanuele Ghidoli wrote:

Hello everyone,

Regarding the timer, how come the timer is initialized so late on MX7 ?
timer_init() called in initcall_run_f().>
The Cortex-A7 should have its own ARM timer, that should be available right
from the beginning. Is that ARM timer in use on your system, or does your
system use GPT timer ?
iMX7 uses arch/arm/mach-imx/syscounter.c.

udelay() is called in initcall_run_f(), before timer_init().
arch_cpu_init() (arch/arm/mach-imx/mx7/soc.c) -> imx_gpcv2_init -> udelay
(which runs schedule/cyclic).

Yikes.

And this is interesting, udelay() before timer_init() leads to a 0 us delay,
so there is another bug.

I have verified that removing this udelay(65) the board boots.
Can we start the syscounter sooner ? Something like this:

diff --git a/arch/arm/include/asm/arch-mx6/sys_proto.h b/arch/arm/include/asm/arch-mx6/sys_proto.h
index 7845fa8e569..5f6759a3306 100644
--- a/arch/arm/include/asm/arch-mx6/sys_proto.h
+++ b/arch/arm/include/asm/arch-mx6/sys_proto.h
@@ -36,4 +36,6 @@ static inline void iomuxc_set_rgmii_io_voltage(int io_vol)
        __raw_writel(io_vol, IOMUXC_SW_PAD_CTL_GRP_DDR_TYPE_RGMII);
 }

+void syscounter_init(void);
+
 #endif /* __SYS_PROTO_IMX6_ */
diff --git a/arch/arm/include/asm/arch-mx7/sys_proto.h b/arch/arm/include/asm/arch-mx7/sys_proto.h
index 5da0037b2c6..765764cf1bc 100644
--- a/arch/arm/include/asm/arch-mx7/sys_proto.h
+++ b/arch/arm/include/asm/arch-mx7/sys_proto.h
@@ -11,4 +11,6 @@ struct wdog_regs;

 void set_wdog_reset(struct wdog_regs *wdog);

+void syscounter_init(void);
+
 #endif /* __SYS_PROTO_IMX7_ */
diff --git a/arch/arm/mach-imx/mx6/soc.c b/arch/arm/mach-imx/mx6/soc.c
index 02df86156d4..641b5d813ea 100644
--- a/arch/arm/mach-imx/mx6/soc.c
+++ b/arch/arm/mach-imx/mx6/soc.c
@@ -437,6 +437,8 @@ int arch_cpu_init(void)
                 */
                if (mxc_get_clock(MXC_ARM_CLK) == 396000000)
                        set_ahb_rate(132000000);
+       } else {
+               syscounter_init();
        }

        if (is_mx6ul()) {
diff --git a/arch/arm/mach-imx/mx7/soc.c b/arch/arm/mach-imx/mx7/soc.c
index e504c1fd52a..82d851b7817 100644
--- a/arch/arm/mach-imx/mx7/soc.c
+++ b/arch/arm/mach-imx/mx7/soc.c
@@ -331,6 +331,8 @@ int arch_cpu_init(void)

        init_snvs();

+       syscounter_init();
+
        imx_gpcv2_init();

        enable_ca7_smp();
diff --git a/arch/arm/mach-imx/syscounter.c b/arch/arm/mach-imx/syscounter.c
index 96fe2c7c17b..7b902540737 100644
--- a/arch/arm/mach-imx/syscounter.c
+++ b/arch/arm/mach-imx/syscounter.c
@@ -60,7 +60,7 @@ static inline unsigned long long us_to_tick(unsigned long long usec)
 }

 #if !CONFIG_IS_ENABLED(SKIP_LOWLEVEL_INIT) || IS_ENABLED(CONFIG_XPL_BUILD)
-int timer_init(void)
+void syscounter_init(void)
 {
        struct sctr_regs *sctr = (struct sctr_regs *)SCTR_BASE_ADDR;
        unsigned long val, freq;
@@ -80,6 +80,12 @@ int timer_init(void)
        gd->arch.tbu = 0;

        gd->arch.timer_rate_hz = freq;
+
+       return 0;
+}
+
+int timer_init(void)
+{
        return 0;
 }
 #endif

Reply via email to