[PATCH RFC 02/12] rvtrace: Add pre-ratified implementation callback
From: Eric Lin <hidden>
Date: 2026-06-30 09:47:09
Also in:
linux-riscv, lkml
Subsystem:
hardware tracing facilities, the rest · Maintainers:
Alexander Shishkin, Linus Torvalds
For pre-ratified trace hardware, the implementation register bitfields differ from the ratified RISC-V trace specification, and the component type is not defined in the hardware implementation register. To address this, add a get_impl() callback function in the driver data to translate the pre-ratified trace hardware implementation register information and encode it into the standard RISC-V trace implementation register format. Co-developed-by: Nick Hu <redacted> Signed-off-by: Nick Hu <redacted> Co-developed-by: Vincent Chen <redacted> Signed-off-by: Vincent Chen <redacted> Signed-off-by: Eric Lin <redacted> --- drivers/hwtracing/rvtrace/Kconfig | 9 ++++++++ drivers/hwtracing/rvtrace/Makefile | 1 + drivers/hwtracing/rvtrace/rvtrace-platform.c | 21 +++++++++++++++++- drivers/hwtracing/rvtrace/rvtrace-v0.c | 32 ++++++++++++++++++++++++++++ drivers/hwtracing/rvtrace/rvtrace-v0.h | 16 ++++++++++++++ include/linux/rvtrace.h | 8 +++++++ 6 files changed, 86 insertions(+), 1 deletion(-)
diff --git a/drivers/hwtracing/rvtrace/Kconfig b/drivers/hwtracing/rvtrace/Kconfig
index ba11acf1117d..5e84a3d0b633 100644
--- a/drivers/hwtracing/rvtrace/Kconfig
+++ b/drivers/hwtracing/rvtrace/Kconfig@@ -31,3 +31,12 @@ config RVTRACE_RAMSINK help This driver provides support for Risc-V E-Trace Ramsink component. + +config RVTRACE_V0 + tristate "RISC-V Trace Pre-ratified driver" + depends on RVTRACE + select RVTRACE_ENCODER + select RVTRACE_RAMSINK + default y + help + This provides the RISC-V pre-ratified version trace hardware support.
diff --git a/drivers/hwtracing/rvtrace/Makefile b/drivers/hwtracing/rvtrace/Makefile
index 07403f4d94e3..51b292b1b4c4 100644
--- a/drivers/hwtracing/rvtrace/Makefile
+++ b/drivers/hwtracing/rvtrace/Makefile@@ -1,5 +1,6 @@ # SPDX-License-Identifier: GPL-2.0 +obj-$(CONFIG_RVTRACE_V0) += rvtrace-v0.o obj-$(CONFIG_RVTRACE) += rvtrace.o rvtrace-y := rvtrace-core.o rvtrace-platform.o rvtrace-perf.o obj-$(CONFIG_RVTRACE_ENCODER) += rvtrace-encoder.o
diff --git a/drivers/hwtracing/rvtrace/rvtrace-platform.c b/drivers/hwtracing/rvtrace/rvtrace-platform.c
index 83e5a577bc52..6cf8e7dae2ad 100644
--- a/drivers/hwtracing/rvtrace/rvtrace-platform.c
+++ b/drivers/hwtracing/rvtrace/rvtrace-platform.c@@ -11,6 +11,7 @@ #include <linux/property.h> #include <linux/rvtrace.h> #include <linux/types.h> +#include "rvtrace-v0.h" static int rvtrace_of_parse_outconns(struct rvtrace_platform_data *pdata) {
@@ -114,6 +115,7 @@ static int rvtrace_of_parse_inconns(struct rvtrace_platform_data *pdata) static int rvtrace_platform_probe(struct platform_device *pdev) { + const struct rvtrace_driver_data *driver_data; struct rvtrace_platform_data *pdata; struct device *dev = &pdev->dev; struct rvtrace_component *comp;
@@ -162,7 +164,14 @@ static int rvtrace_platform_probe(struct platform_device *pdev) if (ret) return dev_err_probe(dev, ret, "failed to reset component\n"); - impl = rvtrace_read32(pdata, RVTRACE_COMPONENT_IMPL_OFFSET); + driver_data = device_get_match_data(pdata->dev); + if (driver_data) { + if (driver_data->get_impl) + impl = driver_data->get_impl(pdata); + } else { + impl = rvtrace_read32(pdata, RVTRACE_COMPONENT_IMPL_OFFSET); + } + type = (impl >> RVTRACE_COMPONENT_IMPL_TYPE_SHIFT) & RVTRACE_COMPONENT_IMPL_TYPE_MASK; major = (impl >> RVTRACE_COMPONENT_IMPL_VERMAJOR_SHIFT) &
@@ -194,8 +203,18 @@ static void rvtrace_platform_remove(struct platform_device *pdev) rvtrace_unregister_component(comp); } +static const struct rvtrace_driver_data rvtrace_v0_encoder_data = { + .get_impl = rvtrace_v0_get_encoder_impl, +}; + +static const struct rvtrace_driver_data rvtrace_v0_funnel_data = { + .get_impl = rvtrace_v0_get_funnel_impl, +}; + static const struct of_device_id rvtrace_platform_match[] = { { .compatible = "riscv,trace-component" }, + { .compatible = "sifive,trace-encoder0", .data = &rvtrace_v0_encoder_data}, + { .compatible = "sifive,trace-funnel0", .data = &rvtrace_v0_funnel_data}, {} };
diff --git a/drivers/hwtracing/rvtrace/rvtrace-v0.c b/drivers/hwtracing/rvtrace/rvtrace-v0.c
new file mode 100644
index 000000000000..825de1120c8d
--- /dev/null
+++ b/drivers/hwtracing/rvtrace/rvtrace-v0.c@@ -0,0 +1,32 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2026 SiFive Inc. + */ + +#include <linux/rvtrace.h> +#include "rvtrace-v0.h" + +static u32 rvtrace_v0_get_impl(struct rvtrace_platform_data *pdata, u32 type) +{ + u32 impl, major, minor; + + impl = rvtrace_read32(pdata, RVTRACE_COMPONENT_IMPL_OFFSET); + major = 0; + minor = (impl >> RVTRACE_COMPONENT_IMPL_VERMAJOR_SHIFT) & + RVTRACE_COMPONENT_IMPL_VERMAJOR_MASK; + + /* Encode to standard rvtrace impl format */ + return (type << RVTRACE_COMPONENT_IMPL_TYPE_SHIFT) | + (minor << RVTRACE_COMPONENT_IMPL_VERMINOR_SHIFT) | + (major << RVTRACE_COMPONENT_IMPL_VERMAJOR_SHIFT); +} + +u32 rvtrace_v0_get_encoder_impl(struct rvtrace_platform_data *pdata) +{ + return rvtrace_v0_get_impl(pdata, RVTRACE_COMPONENT_TYPE_ENCODER); +} + +u32 rvtrace_v0_get_funnel_impl(struct rvtrace_platform_data *pdata) +{ + return rvtrace_v0_get_impl(pdata, RVTRACE_COMPONENT_TYPE_FUNNEL); +}
diff --git a/drivers/hwtracing/rvtrace/rvtrace-v0.h b/drivers/hwtracing/rvtrace/rvtrace-v0.h
new file mode 100644
index 000000000000..511aa6489caa
--- /dev/null
+++ b/drivers/hwtracing/rvtrace/rvtrace-v0.h@@ -0,0 +1,16 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (C) 2026 SiFive, Inc. + * + */ + +#ifndef __RVTRACE_V0_H__ +#define __RVTRACE_V0_H__ + +#include <linux/rvtrace.h> + +u32 rvtrace_v0_get_encoder_impl(struct rvtrace_platform_data *pdata); +u32 rvtrace_v0_get_funnel_impl(struct rvtrace_platform_data *pdata); + +#endif /* __RVTRACE_V0_H__ */ +
diff --git a/include/linux/rvtrace.h b/include/linux/rvtrace.h
index 0cb3bd474c2b..fdf6115d7f06 100644
--- a/include/linux/rvtrace.h
+++ b/include/linux/rvtrace.h@@ -154,6 +154,14 @@ struct rvtrace_platform_data { struct rvtrace_connection **outconns; }; +/** + * struct rvtrace_driver_data - Driver-specific data for RISC-V trace components + * @get_impl: Optional callback to retrieve pre-ratified implementation register information. + */ +struct rvtrace_driver_data { + u32 (*get_impl)(struct rvtrace_platform_data *pdata); +}; + static inline u32 rvtrace_read32(struct rvtrace_platform_data *pdata, u32 offset) { if (likely(pdata->io_mem))
--
2.34.1