Thread (13 messages) 13 messages, 1 author, 4d ago
COOLING4d

[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
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help