On Fri, Sep 04, 2026 at 09:12:55AM +0300, Nikita Shubin wrote:
> RISC-V timer is missing timer_early_get_rate() for M-Mode.
> 
> Also timer_early_get_count() is guarded by RISCV_SMODE for no
> clear reason.

This driver is described as "support for a generic RISC-V S-Mode timer
driver", which should be the original reason to mark it as S-Mode only.
It should be intentionally to split M-mode (riscv_aclint_timer.c,
guarded by CONFIG_RISCV_ACLINT) and S-mode timers, since riscv_timer.c
reads ticks from TIME CSR, while at least SiFive cores miss it in
M-mode, and rely on OpenSBI to emulate them.

But this separation is indeed unnecessary, there are as well cores
implementing TIME CSR, so riscv_timer.c works on them even in M-mode,
too, e.g., T-Head ones.

I've summarized the situation here[1], but didn't find enough time and
energy to send out a series to fix issues up...

Anyway, please fix the Kconfig help text, too.

> Make timer_early_get_rate() use RISCV_MMODE_TIMER_FREQ in M-Mode and
> move timer_early_get_count() out of define.
> 
> Signed-off-by: Nikita Shubin <[email protected]>
> ---
>  drivers/timer/riscv_timer.c | 11 +++++++++--
>  1 file changed, 9 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/timer/riscv_timer.c b/drivers/timer/riscv_timer.c
> index 1f4980ceb38..65f174fb879 100644
> --- a/drivers/timer/riscv_timer.c
> +++ b/drivers/timer/riscv_timer.c

At start of the file, a comment mentions "This driver provides generic
timer support for S-mode U-Boot". Please update it along the way.

> @@ -33,14 +33,22 @@ static u64 notrace riscv_timer_get_count(struct udevice 
> *dev)
>       return ((u64)hi << 32) | lo;
>  }
>  
> -#if CONFIG_IS_ENABLED(RISCV_SMODE) && IS_ENABLED(CONFIG_TIMER_EARLY)
>  /**
>   * timer_early_get_rate() - Get the timer rate before driver model
>   */
> +#if IS_ENABLED(CONFIG_TIMER_EARLY)
> +#if CONFIG_IS_ENABLED(RISCV_SMODE)
>  unsigned long notrace timer_early_get_rate(void)
>  {
>       return RISCV_SMODE_TIMER_FREQ;
>  }
> +#elif CONFIG_IS_ENABLED(RISCV_MMODE)
> +unsigned long notrace timer_early_get_rate(void)
> +{
> +     return RISCV_MMODE_TIMER_FREQ;
> +}
> +#endif
> +#endif

For platforms like starfive_visionfive2_defconfig where both
CONFIG_RISCV_TIMER and CONFIG_RISCV_ACLINT are enabled, riscv_timer.c
and riscv_aclint_timer.c would each provide their own early timer
symbols and causing linking errors when building with defconfig.

These platforms might depend on the IPI functionality provided by
aclint_ipi.c, which is also guarded by CONFIG_RISCV_ACLINT; and
riscv_timer.c might not work on them, either, thus simply disabling
CONFIG_RISCV_ACLINT isn't an option.

Regards,
Yao Zi

[1]: https://lore.kernel.org/all/[email protected]/

Reply via email to