All of lore.kernel.org
 help / color / mirror / Atom feed
From: Daniel Lezcano <daniel.lezcano@linaro.org>
To: Aleksa Paunovic <aleksa.paunovic@htecgroup.com>
Cc: "linux-riscv@lists.infradead.org"
	<linux-riscv@lists.infradead.org>,
	Djordje Todorovic <djordje.todorovic@htecgroup.com>,
	Palmer Dabbelt <palmer@dabbelt.com>,
	Conor Dooley <conor@kernel.org>,
	Aleksandar Rikalo <arikalo@gmail.com>,
	Paul Walmsley <paul.walmsley@sifive.com>,
	Albert Ou <aou@eecs.berkeley.edu>,
	Thomas Gleixner <tglx@linutronix.de>,
	"linux-kernel@vger.kernel.org" <linux-kernel@vger.kernel.org>,
	"devicetree@vger.kernel.org" <devicetree@vger.kernel.org>
Subject: Re: [PATCH v3 2/2] Allow for riscv-clock to pick up mmio address.
Date: Tue, 29 Apr 2025 10:52:58 +0200	[thread overview]
Message-ID: <aBCTagteN-pnSqKu@mai.linaro.org> (raw)
In-Reply-To: <DU0PR09MB619673345C9082CB442A8DEFF6BA2@DU0PR09MB6196.eurprd09.prod.outlook.com>

On Wed, Apr 23, 2025 at 12:17:37PM +0000, Aleksa Paunovic wrote:
> HTEC Public
> 
> Allow faster rdtime access via GCR.U mtime shadow register on RISC-V
> devices. This feature can be enabled by setting GCRU_TIME_MMIO during configuration.
> 
> Signed-off-by: Aleksa Paunovic <aleksa.paunovic@htecgroup.com>
> ---
>  arch/riscv/include/asm/timex.h    | 59 ++++++++++++++++++++-----------
>  drivers/clocksource/Kconfig       | 12 +++++++
>  drivers/clocksource/timer-riscv.c | 32 +++++++++++++++++
>  3 files changed, 83 insertions(+), 20 deletions(-)
> 
> diff --git a/arch/riscv/include/asm/timex.h b/arch/riscv/include/asm/timex.h
> index a06697846e69..47ad6285b83a 100644
> --- a/arch/riscv/include/asm/timex.h
> +++ b/arch/riscv/include/asm/timex.h
> @@ -7,31 +7,24 @@
>  #define _ASM_RISCV_TIMEX_H
> 
>  #include <asm/csr.h>
> +#include <asm/mmio.h>
> +
> +#include <linux/jump_label.h>
> 
>  typedef unsigned long cycles_t;
> 
> +extern u64 __iomem *riscv_time_val;
> +DECLARE_STATIC_KEY_FALSE(riscv_time_mmio_available);

Please keep it self-encapsulate in the timer-riscv.c

> +#define riscv_time_val riscv_time_val

why ?

>  #ifdef CONFIG_RISCV_M_MODE
> 
>  #include <asm/clint.h>
> 
> -#ifdef CONFIG_64BIT
> -static inline cycles_t get_cycles(void)
> -{
> -       return readq_relaxed(clint_time_val);
> -}
> -#else /* !CONFIG_64BIT */
> -static inline u32 get_cycles(void)
> -{
> -       return readl_relaxed(((u32 *)clint_time_val));
> -}
> -#define get_cycles get_cycles
> +#undef riscv_time_val
> 
> -static inline u32 get_cycles_hi(void)
> -{
> -       return readl_relaxed(((u32 *)clint_time_val) + 1);
> -}
> -#define get_cycles_hi get_cycles_hi
> -#endif /* CONFIG_64BIT */
> +#define riscv_time_val clint_time_val
> 
>  /*
>   * Much like MIPS, we may not have a viable counter to use at an early point
> @@ -46,22 +39,48 @@ static inline unsigned long random_get_entropy(void)
>  }
>  #define random_get_entropy()   random_get_entropy()
> 
> -#else /* CONFIG_RISCV_M_MODE */
> +#endif
> +
> +static inline long use_riscv_time_mmio(void)
> +{
> +       return IS_ENABLED(CONFIG_RISCV_M_MODE) ||
> +               (IS_ENABLED(CONFIG_GCRU_TIME_MMIO) &&
> +                static_branch_unlikely(&riscv_time_mmio_available));
> +}
> +

Don't use this function to branch when calling get_cycles(). Provide two
versions of the *get_cycles* and initialize with the right one at init time.

> +#ifdef CONFIG_64BIT
> +static inline cycles_t mmio_get_cycles(void)
> +{
> +       return readq_relaxed(riscv_time_val);
> +}
> +#else /* !CONFIG_64BIT */
> +static inline cycles_t mmio_get_cycles(void)
> +{
> +       return readl_relaxed(((u32 *)riscv_time_val));
> +}
> +#endif /* CONFIG_64BIT */
> +
> +static inline u32 mmio_get_cycles_hi(void)
> +{
> +       return readl_relaxed(((u32 *)riscv_time_val) + 1);
> +}
> 
>  static inline cycles_t get_cycles(void)
>  {
> +       if (use_riscv_time_mmio())
> +               return mmio_get_cycles();
>         return csr_read(CSR_TIME);
>  }
>  #define get_cycles get_cycles
> 
>  static inline u32 get_cycles_hi(void)
>  {
> +       if (use_riscv_time_mmio())
> +               return mmio_get_cycles_hi();
>         return csr_read(CSR_TIMEH);
>  }
>  #define get_cycles_hi get_cycles_hi
> 
> -#endif /* !CONFIG_RISCV_M_MODE */
> -
>  #ifdef CONFIG_64BIT
>  static inline u64 get_cycles64(void)
>  {
> diff --git a/drivers/clocksource/Kconfig b/drivers/clocksource/Kconfig
> index 487c85259967..0f2bb75564c7 100644
> --- a/drivers/clocksource/Kconfig
> +++ b/drivers/clocksource/Kconfig
> @@ -661,6 +661,18 @@ config CLINT_TIMER
>           This option enables the CLINT timer for RISC-V systems.  The CLINT
>           driver is usually used for NoMMU RISC-V systems.
> 
> +config GCRU_TIME_MMIO
> +       bool "GCR.U timer support for RISC-V platforms"
> +       depends on !RISCV_M_MODE && RISCV
> +       default n
> +       help
> +        Access GCR.U shadow copy of the RISC-V mtime register
> +        on platforms that provide a compatible device, instead of
> +        reading the time CSR. Since reading the time CSR
> +        traps to M mode on certain platforms, this may be more efficient.
> +
> +        If you don't know what to do here, say n.
> +
>  config CSKY_MP_TIMER
>         bool "SMP Timer for the C-SKY platform" if COMPILE_TEST
>         depends on CSKY
> diff --git a/drivers/clocksource/timer-riscv.c b/drivers/clocksource/timer-riscv.c
> index 48ce50c5f5e6..4290e4b840f7 100644
> --- a/drivers/clocksource/timer-riscv.c
> +++ b/drivers/clocksource/timer-riscv.c
> @@ -22,6 +22,7 @@
>  #include <linux/io-64-nonatomic-lo-hi.h>
>  #include <linux/interrupt.h>
>  #include <linux/of_irq.h>
> +#include <linux/of_address.h>
>  #include <linux/limits.h>
>  #include <clocksource/timer-riscv.h>
>  #include <asm/smp.h>
> @@ -32,6 +33,13 @@
>  static DEFINE_STATIC_KEY_FALSE(riscv_sstc_available);
>  static bool riscv_timer_cannot_wake_cpu;
> 
> +#if defined(CONFIG_GCRU_TIME_MMIO)
> +DEFINE_STATIC_KEY_FALSE_RO(riscv_time_mmio_available);

static DEFINE_STATIC_KEY_FALSE_RO( ... )

> +EXPORT_SYMBOL(riscv_time_mmio_available);
> +u64 __iomem *riscv_time_val __ro_after_init;
> +EXPORT_SYMBOL(riscv_time_val);
> +#endif
> +
>  static void riscv_clock_event_stop(void)
>  {
>         if (static_branch_likely(&riscv_sstc_available)) {
> @@ -203,6 +211,11 @@ static int __init riscv_timer_init_dt(struct device_node *n)
>         int cpuid, error;
>         unsigned long hartid;
>         struct device_node *child;
> +#if defined(CONFIG_GCRU_TIME_MMIO)
> +       u64 mmio_addr;
> +       u64 mmio_size;
> +       struct device_node *gcru;
> +#endif
> 
>         error = riscv_of_processor_hartid(n, &hartid);
>         if (error < 0) {
> @@ -220,6 +233,25 @@ static int __init riscv_timer_init_dt(struct device_node *n)
>         if (cpuid != smp_processor_id())
>                 return 0;
> 
> +#if defined(CONFIG_GCRU_TIME_MMIO)
> +       gcru = of_find_compatible_node(NULL, NULL, "mti,gcru");
> +       if (gcru) {
> +               if (!of_property_read_reg(gcru, 0, &mmio_addr, &mmio_size)) {
> +                       riscv_time_val = ioremap((long)mmio_addr, mmio_size);
> +                       if (riscv_time_val) {
> +                               pr_info("Using mmio time register at 0x%llx\n",
> +                                       mmio_addr);
> +                               static_branch_enable(
> +                                       &riscv_time_mmio_available);
> +                       } else {
> +                               pr_warn("Unable to use mmio time at 0x%llx\n",
> +                                       mmio_addr);
> +                       }
> +                       of_node_put(gcru);
> +               }
> +       }
> +#endif
> +
>         child = of_find_compatible_node(NULL, NULL, "riscv,timer");
>         if (child) {
>                 riscv_timer_cannot_wake_cpu = of_property_read_bool(child,
> --
> 2.34.1

-- 

 <http://www.linaro.org/> Linaro.org │ Open source software for ARM SoCs

Follow Linaro:  <http://www.facebook.com/pages/Linaro> Facebook |
<http://twitter.com/#!/linaroorg> Twitter |
<http://www.linaro.org/linaro-blog/> Blog

_______________________________________________
linux-riscv mailing list
linux-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-riscv

WARNING: multiple messages have this Message-ID (diff)
From: Daniel Lezcano <daniel.lezcano@linaro.org>
To: Aleksa Paunovic <aleksa.paunovic@htecgroup.com>
Cc: "linux-riscv@lists.infradead.org"
	<linux-riscv@lists.infradead.org>,
	Djordje Todorovic <djordje.todorovic@htecgroup.com>,
	Palmer Dabbelt <palmer@dabbelt.com>,
	Conor Dooley <conor@kernel.org>,
	Aleksandar Rikalo <arikalo@gmail.com>,
	Paul Walmsley <paul.walmsley@sifive.com>,
	Albert Ou <aou@eecs.berkeley.edu>,
	Thomas Gleixner <tglx@linutronix.de>,
	"linux-kernel@vger.kernel.org" <linux-kernel@vger.kernel.org>,
	"devicetree@vger.kernel.org" <devicetree@vger.kernel.org>
Subject: Re: [PATCH v3 2/2] Allow for riscv-clock to pick up mmio address.
Date: Tue, 29 Apr 2025 10:52:58 +0200	[thread overview]
Message-ID: <aBCTagteN-pnSqKu@mai.linaro.org> (raw)
In-Reply-To: <DU0PR09MB619673345C9082CB442A8DEFF6BA2@DU0PR09MB6196.eurprd09.prod.outlook.com>

On Wed, Apr 23, 2025 at 12:17:37PM +0000, Aleksa Paunovic wrote:
> HTEC Public
> 
> Allow faster rdtime access via GCR.U mtime shadow register on RISC-V
> devices. This feature can be enabled by setting GCRU_TIME_MMIO during configuration.
> 
> Signed-off-by: Aleksa Paunovic <aleksa.paunovic@htecgroup.com>
> ---
>  arch/riscv/include/asm/timex.h    | 59 ++++++++++++++++++++-----------
>  drivers/clocksource/Kconfig       | 12 +++++++
>  drivers/clocksource/timer-riscv.c | 32 +++++++++++++++++
>  3 files changed, 83 insertions(+), 20 deletions(-)
> 
> diff --git a/arch/riscv/include/asm/timex.h b/arch/riscv/include/asm/timex.h
> index a06697846e69..47ad6285b83a 100644
> --- a/arch/riscv/include/asm/timex.h
> +++ b/arch/riscv/include/asm/timex.h
> @@ -7,31 +7,24 @@
>  #define _ASM_RISCV_TIMEX_H
> 
>  #include <asm/csr.h>
> +#include <asm/mmio.h>
> +
> +#include <linux/jump_label.h>
> 
>  typedef unsigned long cycles_t;
> 
> +extern u64 __iomem *riscv_time_val;
> +DECLARE_STATIC_KEY_FALSE(riscv_time_mmio_available);

Please keep it self-encapsulate in the timer-riscv.c

> +#define riscv_time_val riscv_time_val

why ?

>  #ifdef CONFIG_RISCV_M_MODE
> 
>  #include <asm/clint.h>
> 
> -#ifdef CONFIG_64BIT
> -static inline cycles_t get_cycles(void)
> -{
> -       return readq_relaxed(clint_time_val);
> -}
> -#else /* !CONFIG_64BIT */
> -static inline u32 get_cycles(void)
> -{
> -       return readl_relaxed(((u32 *)clint_time_val));
> -}
> -#define get_cycles get_cycles
> +#undef riscv_time_val
> 
> -static inline u32 get_cycles_hi(void)
> -{
> -       return readl_relaxed(((u32 *)clint_time_val) + 1);
> -}
> -#define get_cycles_hi get_cycles_hi
> -#endif /* CONFIG_64BIT */
> +#define riscv_time_val clint_time_val
> 
>  /*
>   * Much like MIPS, we may not have a viable counter to use at an early point
> @@ -46,22 +39,48 @@ static inline unsigned long random_get_entropy(void)
>  }
>  #define random_get_entropy()   random_get_entropy()
> 
> -#else /* CONFIG_RISCV_M_MODE */
> +#endif
> +
> +static inline long use_riscv_time_mmio(void)
> +{
> +       return IS_ENABLED(CONFIG_RISCV_M_MODE) ||
> +               (IS_ENABLED(CONFIG_GCRU_TIME_MMIO) &&
> +                static_branch_unlikely(&riscv_time_mmio_available));
> +}
> +

Don't use this function to branch when calling get_cycles(). Provide two
versions of the *get_cycles* and initialize with the right one at init time.

> +#ifdef CONFIG_64BIT
> +static inline cycles_t mmio_get_cycles(void)
> +{
> +       return readq_relaxed(riscv_time_val);
> +}
> +#else /* !CONFIG_64BIT */
> +static inline cycles_t mmio_get_cycles(void)
> +{
> +       return readl_relaxed(((u32 *)riscv_time_val));
> +}
> +#endif /* CONFIG_64BIT */
> +
> +static inline u32 mmio_get_cycles_hi(void)
> +{
> +       return readl_relaxed(((u32 *)riscv_time_val) + 1);
> +}
> 
>  static inline cycles_t get_cycles(void)
>  {
> +       if (use_riscv_time_mmio())
> +               return mmio_get_cycles();
>         return csr_read(CSR_TIME);
>  }
>  #define get_cycles get_cycles
> 
>  static inline u32 get_cycles_hi(void)
>  {
> +       if (use_riscv_time_mmio())
> +               return mmio_get_cycles_hi();
>         return csr_read(CSR_TIMEH);
>  }
>  #define get_cycles_hi get_cycles_hi
> 
> -#endif /* !CONFIG_RISCV_M_MODE */
> -
>  #ifdef CONFIG_64BIT
>  static inline u64 get_cycles64(void)
>  {
> diff --git a/drivers/clocksource/Kconfig b/drivers/clocksource/Kconfig
> index 487c85259967..0f2bb75564c7 100644
> --- a/drivers/clocksource/Kconfig
> +++ b/drivers/clocksource/Kconfig
> @@ -661,6 +661,18 @@ config CLINT_TIMER
>           This option enables the CLINT timer for RISC-V systems.  The CLINT
>           driver is usually used for NoMMU RISC-V systems.
> 
> +config GCRU_TIME_MMIO
> +       bool "GCR.U timer support for RISC-V platforms"
> +       depends on !RISCV_M_MODE && RISCV
> +       default n
> +       help
> +        Access GCR.U shadow copy of the RISC-V mtime register
> +        on platforms that provide a compatible device, instead of
> +        reading the time CSR. Since reading the time CSR
> +        traps to M mode on certain platforms, this may be more efficient.
> +
> +        If you don't know what to do here, say n.
> +
>  config CSKY_MP_TIMER
>         bool "SMP Timer for the C-SKY platform" if COMPILE_TEST
>         depends on CSKY
> diff --git a/drivers/clocksource/timer-riscv.c b/drivers/clocksource/timer-riscv.c
> index 48ce50c5f5e6..4290e4b840f7 100644
> --- a/drivers/clocksource/timer-riscv.c
> +++ b/drivers/clocksource/timer-riscv.c
> @@ -22,6 +22,7 @@
>  #include <linux/io-64-nonatomic-lo-hi.h>
>  #include <linux/interrupt.h>
>  #include <linux/of_irq.h>
> +#include <linux/of_address.h>
>  #include <linux/limits.h>
>  #include <clocksource/timer-riscv.h>
>  #include <asm/smp.h>
> @@ -32,6 +33,13 @@
>  static DEFINE_STATIC_KEY_FALSE(riscv_sstc_available);
>  static bool riscv_timer_cannot_wake_cpu;
> 
> +#if defined(CONFIG_GCRU_TIME_MMIO)
> +DEFINE_STATIC_KEY_FALSE_RO(riscv_time_mmio_available);

static DEFINE_STATIC_KEY_FALSE_RO( ... )

> +EXPORT_SYMBOL(riscv_time_mmio_available);
> +u64 __iomem *riscv_time_val __ro_after_init;
> +EXPORT_SYMBOL(riscv_time_val);
> +#endif
> +
>  static void riscv_clock_event_stop(void)
>  {
>         if (static_branch_likely(&riscv_sstc_available)) {
> @@ -203,6 +211,11 @@ static int __init riscv_timer_init_dt(struct device_node *n)
>         int cpuid, error;
>         unsigned long hartid;
>         struct device_node *child;
> +#if defined(CONFIG_GCRU_TIME_MMIO)
> +       u64 mmio_addr;
> +       u64 mmio_size;
> +       struct device_node *gcru;
> +#endif
> 
>         error = riscv_of_processor_hartid(n, &hartid);
>         if (error < 0) {
> @@ -220,6 +233,25 @@ static int __init riscv_timer_init_dt(struct device_node *n)
>         if (cpuid != smp_processor_id())
>                 return 0;
> 
> +#if defined(CONFIG_GCRU_TIME_MMIO)
> +       gcru = of_find_compatible_node(NULL, NULL, "mti,gcru");
> +       if (gcru) {
> +               if (!of_property_read_reg(gcru, 0, &mmio_addr, &mmio_size)) {
> +                       riscv_time_val = ioremap((long)mmio_addr, mmio_size);
> +                       if (riscv_time_val) {
> +                               pr_info("Using mmio time register at 0x%llx\n",
> +                                       mmio_addr);
> +                               static_branch_enable(
> +                                       &riscv_time_mmio_available);
> +                       } else {
> +                               pr_warn("Unable to use mmio time at 0x%llx\n",
> +                                       mmio_addr);
> +                       }
> +                       of_node_put(gcru);
> +               }
> +       }
> +#endif
> +
>         child = of_find_compatible_node(NULL, NULL, "riscv,timer");
>         if (child) {
>                 riscv_timer_cannot_wake_cpu = of_property_read_bool(child,
> --
> 2.34.1

-- 

 <http://www.linaro.org/> Linaro.org │ Open source software for ARM SoCs

Follow Linaro:  <http://www.facebook.com/pages/Linaro> Facebook |
<http://twitter.com/#!/linaroorg> Twitter |
<http://www.linaro.org/linaro-blog/> Blog

  reply	other threads:[~2025-04-29  8:57 UTC|newest]

Thread overview: 16+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2025-04-23 12:12 [PATCH v3 0/2] Use GCR.U timer device as clocksource Aleksa Paunovic
2025-04-23 12:12 ` Aleksa Paunovic
2025-04-23 12:14 ` [PATCH v3 1/2] dt-bindings: timer: mti,gcru Aleksa Paunovic
2025-04-23 12:14   ` Aleksa Paunovic
2025-04-23 15:27   ` Conor Dooley
2025-04-23 15:27     ` Conor Dooley
2025-04-24  6:24   ` Krzysztof Kozlowski
2025-04-24  6:24     ` Krzysztof Kozlowski
2025-05-14 15:02     ` Aleksa Paunovic
2025-05-14 15:02       ` Aleksa Paunovic
2025-04-23 12:17 ` [PATCH v3 2/2] Allow for riscv-clock to pick up mmio address Aleksa Paunovic
2025-04-23 12:17   ` Aleksa Paunovic
2025-04-29  8:52   ` Daniel Lezcano [this message]
2025-04-29  8:52     ` Daniel Lezcano
2025-05-14 15:13     ` Aleksa Paunovic
2025-05-14 15:13       ` Aleksa Paunovic

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=aBCTagteN-pnSqKu@mai.linaro.org \
    --to=daniel.lezcano@linaro.org \
    --cc=aleksa.paunovic@htecgroup.com \
    --cc=aou@eecs.berkeley.edu \
    --cc=arikalo@gmail.com \
    --cc=conor@kernel.org \
    --cc=devicetree@vger.kernel.org \
    --cc=djordje.todorovic@htecgroup.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-riscv@lists.infradead.org \
    --cc=palmer@dabbelt.com \
    --cc=paul.walmsley@sifive.com \
    --cc=tglx@linutronix.de \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.