* [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
* 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 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
* [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 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 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).