linux-riscv.lists.infradead.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v3 0/2] Use GCR.U timer device as clocksource
@ 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:17 ` [PATCH v3 2/2] Allow for riscv-clock to pick up mmio address Aleksa Paunovic
  0 siblings, 2 replies; 8+ messages in thread
From: Aleksa Paunovic @ 2025-04-23 12:12 UTC (permalink / raw)
  To: linux-riscv@lists.infradead.org
  Cc: Djordje Todorovic, Palmer Dabbelt, Conor Dooley,
	Aleksandar Rikalo, linux-riscv@lists.infradead.org, Paul Walmsley,
	Albert Ou, Daniel Lezcano, Thomas Gleixner,
	linux-kernel@vger.kernel.org, devicetree@vger.kernel.org

HTEC Public

This series adds bindings for the GCR.U timer device and corresponding
driver support. Accessing the memory mapped mtime register in the GCR.U
region should be faster than trapping to M mode each time the timer
needs to be read.


Aleksa Paunovic (2):
  dt-bindings: timer: mti,gcru
  Allow for riscv-clock to pick up mmio address.

 .../devicetree/bindings/timer/mti,gcru.yaml   | 47 +++++++++++++++
 arch/riscv/include/asm/timex.h                | 59 ++++++++++++-------
 drivers/clocksource/Kconfig                   | 12 ++++
 drivers/clocksource/timer-riscv.c             | 32 ++++++++++
 4 files changed, 130 insertions(+), 20 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/timer/mti,gcru.yaml

--
2.34.1

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

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

* [PATCH v3 1/2] dt-bindings: timer: mti,gcru
  2025-04-23 12:12 [PATCH v3 0/2] Use GCR.U timer device as clocksource Aleksa Paunovic
@ 2025-04-23 12:14 ` Aleksa Paunovic
  2025-04-23 15:27   ` Conor Dooley
  2025-04-24  6:24   ` Krzysztof Kozlowski
  2025-04-23 12:17 ` [PATCH v3 2/2] Allow for riscv-clock to pick up mmio address Aleksa Paunovic
  1 sibling, 2 replies; 8+ messages in thread
From: Aleksa Paunovic @ 2025-04-23 12:14 UTC (permalink / raw)
  To: linux-riscv@lists.infradead.org
  Cc: Djordje Todorovic, Palmer Dabbelt, Conor Dooley,
	Aleksandar Rikalo, Paul Walmsley, Albert Ou, Daniel Lezcano,
	Thomas Gleixner, linux-kernel@vger.kernel.org,
	devicetree@vger.kernel.org

HTEC Public

Add dt-bindings for the GCR.U memory mapped timer device for RISC-V
platforms. The GCR.U memory region contains shadow copies of the RISC-V
mtime register and the hrtime Global Configuration Register.

Signed-off-by: Aleksa Paunovic <aleksa.paunovic@htecgroup.com>
---
 .../devicetree/bindings/timer/mti,gcru.yaml   | 47 +++++++++++++++++++
 1 file changed, 47 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/timer/mti,gcru.yaml

diff --git a/Documentation/devicetree/bindings/timer/mti,gcru.yaml b/Documentation/devicetree/bindings/timer/mti,gcru.yaml
new file mode 100644
index 000000000000..6555dbab402e
--- /dev/null
+++ b/Documentation/devicetree/bindings/timer/mti,gcru.yaml
@@ -0,0 +1,47 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/timer/mti,gcru.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: GCR.U timer device for RISC-V platforms
+
+maintainers:
+  - Aleksa Paunovic <aleksa.paunovic@htecgroup.com>
+
+description:
+  The GCR.U memory region contains memory mapped shadow copies of
+  mtime and hrtime Global Configuration Registers,
+  which software can choose to make accessible from user mode.
+
+select:
+  properties:
+    compatible:
+      contains:
+        const: mti,gcru
+
+  required:
+    - compatible
+
+properties:
+  compatible:
+    const: mti,gcru
+
+  reg:
+    items:
+      - description: Read-only shadow copy of the RISC-V mtime register.
+      - description: Read-only shadow copy of the high resolution timer register.
+
+required:
+  - compatible
+  - reg
+
+additionalProperties: false
+
+examples:
+  - |
+    gcru: timer@1617F000 {
+        compatible = "mti,gcru";
+        reg = <0x1617F050 0x8>,
+              <0x1617F090 0x8>;
+    };
--
2.34.1

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

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

* [PATCH v3 2/2] Allow for riscv-clock to pick up mmio address.
  2025-04-23 12:12 [PATCH v3 0/2] Use GCR.U timer device as clocksource Aleksa Paunovic
  2025-04-23 12:14 ` [PATCH v3 1/2] dt-bindings: timer: mti,gcru Aleksa Paunovic
@ 2025-04-23 12:17 ` Aleksa Paunovic
  2025-04-29  8:52   ` Daniel Lezcano
  1 sibling, 1 reply; 8+ messages in thread
From: Aleksa Paunovic @ 2025-04-23 12:17 UTC (permalink / raw)
  To: linux-riscv@lists.infradead.org
  Cc: Djordje Todorovic, Palmer Dabbelt, Conor Dooley,
	Aleksandar Rikalo, Paul Walmsley, Albert Ou, Daniel Lezcano,
	Thomas Gleixner, linux-kernel@vger.kernel.org,
	devicetree@vger.kernel.org

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);
+
+#define riscv_time_val riscv_time_val
+
 #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));
+}
+
+#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);
+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

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

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

* Re: [PATCH v3 1/2] dt-bindings: timer: mti,gcru
  2025-04-23 12:14 ` [PATCH v3 1/2] dt-bindings: timer: mti,gcru Aleksa Paunovic
@ 2025-04-23 15:27   ` Conor Dooley
  2025-04-24  6:24   ` Krzysztof Kozlowski
  1 sibling, 0 replies; 8+ messages in thread
From: Conor Dooley @ 2025-04-23 15:27 UTC (permalink / raw)
  To: Aleksa Paunovic
  Cc: linux-riscv@lists.infradead.org, Djordje Todorovic,
	Palmer Dabbelt, Aleksandar Rikalo, Paul Walmsley, Albert Ou,
	Daniel Lezcano, Thomas Gleixner, linux-kernel@vger.kernel.org,
	devicetree@vger.kernel.org


[-- Attachment #1.1: Type: text/plain, Size: 2278 bytes --]

On Wed, Apr 23, 2025 at 12:14:26PM +0000, Aleksa Paunovic wrote:
> HTEC Public
> 
> Add dt-bindings for the GCR.U memory mapped timer device for RISC-V
> platforms. The GCR.U memory region contains shadow copies of the RISC-V
> mtime register and the hrtime Global Configuration Register.
> 
> Signed-off-by: Aleksa Paunovic <aleksa.paunovic@htecgroup.com>
> ---
>  .../devicetree/bindings/timer/mti,gcru.yaml   | 47 +++++++++++++++++++
>  1 file changed, 47 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/timer/mti,gcru.yaml
> 
> diff --git a/Documentation/devicetree/bindings/timer/mti,gcru.yaml b/Documentation/devicetree/bindings/timer/mti,gcru.yaml
> new file mode 100644
> index 000000000000..6555dbab402e
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/timer/mti,gcru.yaml
> @@ -0,0 +1,47 @@
> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/timer/mti,gcru.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: GCR.U timer device for RISC-V platforms
> +
> +maintainers:
> +  - Aleksa Paunovic <aleksa.paunovic@htecgroup.com>
> +
> +description:
> +  The GCR.U memory region contains memory mapped shadow copies of
> +  mtime and hrtime Global Configuration Registers,
> +  which software can choose to make accessible from user mode.
> +
> +select:
> +  properties:
> +    compatible:
> +      contains:
> +        const: mti,gcru
> +
> +  required:
> +    - compatible

Why is this select required?
I don't see why it would be since there's not a fallback to a compatble
from some toher binding.

> +
> +properties:
> +  compatible:
> +    const: mti,gcru
> +
> +  reg:
> +    items:
> +      - description: Read-only shadow copy of the RISC-V mtime register.
> +      - description: Read-only shadow copy of the high resolution timer register.
> +
> +required:
> +  - compatible
> +  - reg
> +
> +additionalProperties: false
> +
> +examples:
> +  - |
> +    gcru: timer@1617F000 {

Drop the "gcru" label from here, there are no users.

> +        compatible = "mti,gcru";
> +        reg = <0x1617F050 0x8>,
> +              <0x1617F090 0x8>;
> +    };
> --
> 2.34.1

[-- Attachment #1.2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]

[-- Attachment #2: Type: text/plain, Size: 161 bytes --]

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

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

* Re: [PATCH v3 1/2] dt-bindings: timer: mti,gcru
  2025-04-23 12:14 ` [PATCH v3 1/2] dt-bindings: timer: mti,gcru Aleksa Paunovic
  2025-04-23 15:27   ` Conor Dooley
@ 2025-04-24  6:24   ` Krzysztof Kozlowski
  2025-05-14 15:02     ` Aleksa Paunovic
  1 sibling, 1 reply; 8+ messages in thread
From: Krzysztof Kozlowski @ 2025-04-24  6:24 UTC (permalink / raw)
  To: Aleksa Paunovic, linux-riscv@lists.infradead.org
  Cc: Djordje Todorovic, Palmer Dabbelt, Conor Dooley,
	Aleksandar Rikalo, Paul Walmsley, Albert Ou, Daniel Lezcano,
	Thomas Gleixner, linux-kernel@vger.kernel.org,
	devicetree@vger.kernel.org

On 23/04/2025 14:14, Aleksa Paunovic wrote:
> HTEC Public

Fix your email systems or use b4 relay.


<form letter>
Please use scripts/get_maintainers.pl to get a list of necessary people
and lists to CC (and consider --no-git-fallback argument, so you will
not CC people just because they made one commit years ago). It might
happen, that command when run on an older kernel, gives you outdated
entries. Therefore please be sure you base your patches on recent Linux
kernel.

Tools like b4 or scripts/get_maintainer.pl provide you proper list of
people, so fix your workflow. Tools might also fail if you work on some
ancient tree (don't, instead use mainline) or work on fork of kernel
(don't, instead use mainline). Just use b4 and everything should be
fine, although remember about `b4 prep --auto-to-cc` if you added new
patches to the patchset.
</form letter>

> 
> Add dt-bindings for the GCR.U memory mapped timer device for RISC-V
> platforms. The GCR.U memory region contains shadow copies of the RISC-V
> mtime register and the hrtime Global Configuration Register.
> 
> Signed-off-by: Aleksa Paunovic <aleksa.paunovic@htecgroup.com>
> ---
>  .../devicetree/bindings/timer/mti,gcru.yaml   | 47 +++++++++++++++++++
>  1 file changed, 47 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/timer/mti,gcru.yaml
> 
> diff --git a/Documentation/devicetree/bindings/timer/mti,gcru.yaml b/Documentation/devicetree/bindings/timer/mti,gcru.yaml
> new file mode 100644
> index 000000000000..6555dbab402e
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/timer/mti,gcru.yaml
> @@ -0,0 +1,47 @@
> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/timer/mti,gcru.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: GCR.U timer device for RISC-V platforms
> +
> +maintainers:
> +  - Aleksa Paunovic <aleksa.paunovic@htecgroup.com>
> +
> +description:
> +  The GCR.U memory region contains memory mapped shadow copies of
> +  mtime and hrtime Global Configuration Registers,
> +  which software can choose to make accessible from user mode.
> +
> +select:
> +  properties:
> +    compatible:
> +      contains:
> +        const: mti,gcru
> +
> +  required:
> +    - compatible

Drop select, why do you need it?

> +
> +properties:
> +  compatible:
> +    const: mti,gcru
> +
> +  reg:
> +    items:
> +      - description: Read-only shadow copy of the RISC-V mtime register.
> +      - description: Read-only shadow copy of the high resolution timer register.
> +
> +required:
> +  - compatible
> +  - reg
> +
> +additionalProperties: false
> +
> +examples:
> +  - |
> +    gcru: timer@1617F000 {

Lower-case hex in DTS, always. See DTS coding style.

Best regards,
Krzysztof

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

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

* Re: [PATCH v3 2/2] Allow for riscv-clock to pick up mmio address.
  2025-04-23 12:17 ` [PATCH v3 2/2] Allow for riscv-clock to pick up mmio address Aleksa Paunovic
@ 2025-04-29  8:52   ` Daniel Lezcano
  2025-05-14 15:13     ` Aleksa Paunovic
  0 siblings, 1 reply; 8+ messages in thread
From: Daniel Lezcano @ 2025-04-29  8:52 UTC (permalink / raw)
  To: Aleksa Paunovic
  Cc: linux-riscv@lists.infradead.org, Djordje Todorovic,
	Palmer Dabbelt, Conor Dooley, Aleksandar Rikalo, Paul Walmsley,
	Albert Ou, Thomas Gleixner, linux-kernel@vger.kernel.org,
	devicetree@vger.kernel.org

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

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

* Re: [PATCH v3 1/2] dt-bindings: timer: mti,gcru
  2025-04-24  6:24   ` Krzysztof Kozlowski
@ 2025-05-14 15:02     ` Aleksa Paunovic
  0 siblings, 0 replies; 8+ messages in thread
From: Aleksa Paunovic @ 2025-05-14 15:02 UTC (permalink / raw)
  To: krzk@kernel.org
  Cc: Aleksa Paunovic, aou@eecs.berkeley.edu, arikalo@gmail.com,
	conor@kernel.org, daniel.lezcano@linaro.org,
	devicetree@vger.kernel.org, Djordje Todorovic,
	linux-kernel@vger.kernel.org, linux-riscv@lists.infradead.org,
	palmer@dabbelt.com, paul.walmsley@sifive.com, tglx@linutronix.de

On 24. 4. 25. 08:24, Krzysztof Kozlowski wrote:
> [You don't often get email from krzk@kernel.org. Learn why this is important at https://aka.ms/LearnAboutSenderIdentification ]
> 
> CAUTION: This email originated from outside of the organization. Do not click links or open attachments unless you recognize the sender and know the content is safe.
> 
> 
> On 23/04/2025 14:14, Aleksa Paunovic wrote:
>> HTEC Public
> 
> Fix your email systems or use b4 relay.
> 
> 
> <form letter>
> Please use scripts/get_maintainers.pl to get a list of necessary people
> and lists to CC (and consider --no-git-fallback argument, so you will
> not CC people just because they made one commit years ago). It might
> happen, that command when run on an older kernel, gives you outdated
> entries. Therefore please be sure you base your patches on recent Linux
> kernel.
> 
> Tools like b4 or scripts/get_maintainer.pl provide you proper list of
> people, so fix your workflow. Tools might also fail if you work on some
> ancient tree (don't, instead use mainline) or work on fork of kernel
> (don't, instead use mainline). Just use b4 and everything should be
> fine, although remember about `b4 prep --auto-to-cc` if you added new
> patches to the patchset.
> </form letter>
>  
Thank you for the tips. Will be using b4 relay in the future, starting with v4 linked at [1].

[1]
https://lore.kernel.org/linux-riscv/20250514-riscv-time-mmio-v4-0-cb0cf2922d66@htecgroup.com/

Best regards,
Aleksa Paunovic
>>
>> Add dt-bindings for the GCR.U memory mapped timer device for RISC-V
>> platforms. The GCR.U memory region contains shadow copies of the RISC-V
>> mtime register and the hrtime Global Configuration Register.
>>
>> Signed-off-by: Aleksa Paunovic <aleksa.paunovic@htecgroup.com>
>> ---
>>  .../devicetree/bindings/timer/mti,gcru.yaml   | 47 +++++++++++++++++++
>>  1 file changed, 47 insertions(+)
>>  create mode 100644 Documentation/devicetree/bindings/timer/mti,gcru.yaml
>>
>> diff --git a/Documentation/devicetree/bindings/timer/mti,gcru.yaml b/Documentation/devicetree/bindings/timer/mti,gcru.yaml
>> new file mode 100644
>> index 000000000000..6555dbab402e
>> --- /dev/null
>> +++ b/Documentation/devicetree/bindings/timer/mti,gcru.yaml
>> @@ -0,0 +1,47 @@
>> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
>> +%YAML 1.2
>> +---
>> +$id: http://devicetree.org/schemas/timer/mti,gcru.yaml#
>> +$schema: http://devicetree.org/meta-schemas/core.yaml#
>> +
>> +title: GCR.U timer device for RISC-V platforms
>> +
>> +maintainers:
>> +  - Aleksa Paunovic <aleksa.paunovic@htecgroup.com>
>> +
>> +description:
>> +  The GCR.U memory region contains memory mapped shadow copies of
>> +  mtime and hrtime Global Configuration Registers,
>> +  which software can choose to make accessible from user mode.
>> +
>> +select:
>> +  properties:
>> +    compatible:
>> +      contains:
>> +        const: mti,gcru
>> +
>> +  required:
>> +    - compatible
> 
> Drop select, why do you need it?
> 
>> +
>> +properties:
>> +  compatible:
>> +    const: mti,gcru
>> +
>> +  reg:
>> +    items:
>> +      - description: Read-only shadow copy of the RISC-V mtime register.
>> +      - description: Read-only shadow copy of the high resolution timer register.
>> +
>> +required:
>> +  - compatible
>> +  - reg
>> +
>> +additionalProperties: false
>> +
>> +examples:
>> +  - |
>> +    gcru: timer@1617F000 {
> 
> Lower-case hex in DTS, always. See DTS coding style.
> 
> Best regards,
> Krzysztof
_______________________________________________
linux-riscv mailing list
linux-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-riscv

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

* Re: [PATCH v3 2/2] Allow for riscv-clock to pick up mmio address.
  2025-04-29  8:52   ` Daniel Lezcano
@ 2025-05-14 15:13     ` Aleksa Paunovic
  0 siblings, 0 replies; 8+ messages in thread
From: Aleksa Paunovic @ 2025-05-14 15:13 UTC (permalink / raw)
  To: daniel.lezcano@linaro.org
  Cc: Aleksa Paunovic, aou@eecs.berkeley.edu, arikalo@gmail.com,
	conor@kernel.org, devicetree@vger.kernel.org, Djordje Todorovic,
	linux-kernel@vger.kernel.org, linux-riscv@lists.infradead.org,
	palmer@dabbelt.com, paul.walmsley@sifive.com, tglx@linutronix.de

On 29. 4. 25. 10:52, Daniel Lezcano wrote:
> 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 ?
>    
We decided to leave this in v4[1] for consistency with the #define riscv_time_val clint_time_val macro. Similar to the #define get_cycles get_cycles macro. Will remove in v5 if unnecessary.  

[1]
https://lore.kernel.org/linux-riscv/20250514-riscv-time-mmio-v4-0-cb0cf2922d66@htecgroup.com/

Best regards,
Aleksa Paunovic

>>  #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

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

end of thread, other threads:[~2025-05-14 17:46 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-04-23 12:12 [PATCH v3 0/2] Use GCR.U timer device as clocksource Aleksa Paunovic
2025-04-23 12:14 ` [PATCH v3 1/2] dt-bindings: timer: mti,gcru Aleksa Paunovic
2025-04-23 15:27   ` Conor Dooley
2025-04-24  6:24   ` Krzysztof Kozlowski
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-29  8:52   ` Daniel Lezcano
2025-05-14 15:13     ` Aleksa Paunovic

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).