From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from smtpbguseast1.qq.com (smtpbguseast1.qq.com [54.204.34.129]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 9F7412FE07D for ; Tue, 14 Apr 2026 03:43:39 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=54.204.34.129 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1776138222; cv=none; b=YNpFfKGioRWU7A1Te1yNUY2IxFqeffuLAosjmrf81qnUxeDNfqaEms96Ho46scQHRDErp5c1dSk8bYoya/Xh/vwOf+WdiL7VIvEoGN4444MjO7HJUr2PlycntXQpbe/El+Kc/COchBnVx7YNiOjp7oYlF/sHBqV/FiHMC822IqY= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1776138222; c=relaxed/simple; bh=DCXW0+IK3XUcRpizq+bCxJiOtTsfU7QsumESqCN7fqI=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=XhRgv2+xaUQCgJrNHDlZqFqxRvyc/B2+LwUUsl2UZBF61Y8vJCYdB5bz1ih6uuWWQxf0ifsO3nzw4ZsLZuE4YASlYLvXrvxN4jYcuhijVhdFyZOExBAv3ugdE5aTN2kwZqFRQwMF7au0shfvMphiL3kcXicdYBetRaCMDTaHcxk= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=linux.spacemit.com; spf=none smtp.mailfrom=linux.spacemit.com; dkim=pass (1024-bit key) header.d=linux.spacemit.com header.i=@linux.spacemit.com header.b=U6pv2oEb; arc=none smtp.client-ip=54.204.34.129 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=linux.spacemit.com Authentication-Results: smtp.subspace.kernel.org; spf=none smtp.mailfrom=linux.spacemit.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linux.spacemit.com header.i=@linux.spacemit.com header.b="U6pv2oEb" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.spacemit.com; s=mxsw2412; t=1776138142; bh=P3GVjBCXRU7adb+cVqE903QHuJnoDiq/UFyGJ9773gI=; h=From:To:Subject:Date:Message-Id:MIME-Version; b=U6pv2oEb/VH7XWiii/fIaFBYnaGVSkbMLtlNVFVF0CStVBfFsa4PU/fNnhPKL/a7f /NSzt5hamAYNSOJlD++iGE6sEMBr5NjR0hk3PqH0JDfH7cDZh1l0G6HBld+h/Ti6/J 26IVuMV6kXGAbkFrj4kpe8EMzwxBihQs/344ru6w= X-QQ-mid: zesmtpsz5t1776138135tb7d97203 X-QQ-Originating-IP: A4h7SvXs75OmbzLY+NVyMu9/GokZCmGtd1XspNpuU8g= Received: from snode5.. ( [61.145.255.150]) by bizesmtp.qq.com (ESMTP) with id ; Tue, 14 Apr 2026 11:42:13 +0800 (CST) X-QQ-SSF: 0000000000000000000000000000000 X-QQ-GoodBg: 0 X-BIZMAIL-ID: 1804587517364881883 EX-QQ-RecipientCnt: 26 From: Zane Leung To: robh@kernel.org, krzk+dt@kernel.org, conor+dt@kernel.org, palmer@dabbelt.com, pjw@kernel.org, gregkh@linuxfoundation.org, alexander.shishkin@linux.intel.com, irogers@google.com Cc: coresight@lists.linaro.org, peterz@infradead.org, mingo@redhat.com, namhyung@kernel.org, mark.rutland@arm.com, jolsa@kernel.org, adrian.hunter@intel.com, kan.liang@linux.intel.com, mchitale@gmail.com, anup@brainfault.org, atish.patra@linux.dev, andrew.jones@oss.qualcomm.com, sunilvl@oss.qualcomm.com, linux-riscv@lists.infradead.org, linux-kernel@vger.kernel.org, anup.patel@oss.qualcomm.com, mayuresh.chitale@oss.qualcomm.com, zhuangqiubin@linux.spacemit.com Subject: [RFC PATCH 05/12] coresight: Add RISC-V Trace ATB Bridge driver Date: Tue, 14 Apr 2026 11:41:46 +0800 Message-Id: <20260414034153.3272485-6-liangzhen@linux.spacemit.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20260414034153.3272485-1-liangzhen@linux.spacemit.com> References: <20260414034153.3272485-1-liangzhen@linux.spacemit.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-QQ-SENDSIZE: 520 Feedback-ID: zesmtpsz:linux.spacemit.com:qybglogicsvrgz:qybglogicsvrgz6b-0 X-QQ-XMAILINFO: MJsUkRPIFlJqGbRLbAHkPi0YYfAcjp5XDk/ZvfNah5muU0GU7AN8rtbL T5e5Ait4QyPzPuxJwxP/5XbUHdmmq03m+h9Ja5AJBbjnbY9qRoQQnYCBdYTCQlg4xP4P3e+ BwRw7+Dlp9ZOqGLt5uH71P9GGEe+LW5BF4ceyH0Zb3cumKzf+f9od/nszhm910eMVey+HVu gg/bb5jl1GM8MgOWesSAo9YPuWN47GaL8Srk9VBPtFoXg6AYUT+Kd8JzalwTfS5hi/ec1dN ey0TMLGKzNF0zreyW134W4fvEGAmkFtMh09Uu7jygMf+jag7D6Sq/cL423Yefw/cN0fcI1K NiRHnmJOJkTmX+rON4weN0ecx+QOSkRs+4TxQENs7Wn8Rs8a5ZcCA10v6SNzw8Y/KtYp0zC ao21VmrFw0OC7EQEkRv/Ys4l9Ez2hmz5dTV+D7JbfIzO/W5JJCLsVU2HLZYBd3qykrMgSqQ fOs5fZbzg1WZEYToAt9TCo7l1vuyfTecfK1hWAuk0VujFaAbnW895G1yfhWFRfNYELtsqE7 rfrfAh43m18xL08OK0iUHqvNSF8D0TuZxhjedsG3tTn722QXRJsKSY3iIFwaaGSjLVYL+WX sGb95TjCPK1gBYKjOD0KiPGauMlqtg6tTL7wNm5SB6gduArC64YVJjO/+IwOBACjYY1YFUf Gi/mVXTvfRcfuczQ1YX2jsRKbvO0SExp2zeyIQ5zEwdpETb4Cwlikf3/2URAd0JRey2FyhI hXDQdzLLpe9yK3zAG8wk9SToAI9V8Hell+hb2U7reWrtu1VPsRgz+rkUVoF7FvPp+D1Q8dT uaPXbz9WyH4kgIkRiOifYDlN/8hSftPxV+rS8gt7Sio3FU/Hy64of7UUM2iRnzRjfeuwUY0 Jkwz2mkztAx4Ce0RQWYlhMMf1LwdtKzOdKlxzNaEof9KOvsE0TiZ6H9cTYWEt9xr+q3nbLx rYtnV8srUJBSGMDO52I1HJqvRnDegJncyKJ5ptZj3kjg8MhoHWERoXfxbE2tMyeU61OGZ5R 6C+plzew1sQIjGTqeBp2pu7R+rzSO3Yi0mFGQP7KaL+PTy6lKs+1g+63qMDbtpynQWEYFqO fGJNF6emADeD9Uznbe2dn7DSN+GvQDCihrswVT6fCwq X-QQ-XMRINFO: Nq+8W0+stu50tPAe92KXseR0ZZmBTk3gLg== X-QQ-RECHKSPAM: 0 From: liangzhen Add initial implementation of RISC-V trace ATB Bridge driver. The ATB Bridge is defined in the RISC-V Trace Control Interface specification. Signed-off-by: liangzhen --- drivers/hwtracing/coresight/Kconfig | 12 + drivers/hwtracing/coresight/Makefile | 1 + .../hwtracing/coresight/rvtrace-atbbridge.c | 239 ++++++++++++++++++ 3 files changed, 252 insertions(+) create mode 100644 drivers/hwtracing/coresight/rvtrace-atbbridge.c diff --git a/drivers/hwtracing/coresight/Kconfig b/drivers/hwtracing/coresight/Kconfig index 8381a84e2699..1cd88a1a7d08 100644 --- a/drivers/hwtracing/coresight/Kconfig +++ b/drivers/hwtracing/coresight/Kconfig @@ -288,6 +288,17 @@ config RVTRACE dynamically aggregated with CoreSight trace infrastructure at run time to form a complete trace path. +config RVTRACE_ATBBRIDGE + tristate "RISCV Trace ATB Bridge driver" + depends on RVTRACE + help + This driver provides support for the ATB Bridge driver. The ATB + Bridge allows sending RISC-V trace to Arm CoreSight infrastructure + (instead of RISC-V compliant sink) as an ATB initiator. + + To compile this driver as a module, choose M here: the module + will be called rvtrace-atbbridge. + config RVTRACE_FUNNEL tristate "RISCV Trace Funnel driver" depends on RVTRACE @@ -303,6 +314,7 @@ config RVTRACE_ENCODER tristate "RISCV Trace Encoder driver" depends on RVTRACE select RVTRACE_FUNNEL + select RVTRACE_ATBBRIDGE help This driver provides support for the Trace Encoder module, tracing the instructions that a processor is executing. This is primarily diff --git a/drivers/hwtracing/coresight/Makefile b/drivers/hwtracing/coresight/Makefile index 409a0abf0642..2264a313a773 100644 --- a/drivers/hwtracing/coresight/Makefile +++ b/drivers/hwtracing/coresight/Makefile @@ -59,6 +59,7 @@ coresight-ctcu-y := coresight-ctcu-core.o obj-$(CONFIG_CORESIGHT_KUNIT_TESTS) += coresight-kunit-tests.o obj-$(CONFIG_RVTRACE) += rvtrace.o rvtrace-y := rvtrace-core.o +obj-$(CONFIG_RVTRACE_ATBBRIDGE) += rvtrace-atbbridge.o obj-$(CONFIG_RVTRACE_FUNNEL) += rvtrace-funnel.o obj-$(CONFIG_RVTRACE_ENCODER) += rvtrace-encoder.o rvtrace-encoder-y := rvtrace-encoder-core.o rvtrace-encoder-sysfs.o diff --git a/drivers/hwtracing/coresight/rvtrace-atbbridge.c b/drivers/hwtracing/coresight/rvtrace-atbbridge.c new file mode 100644 index 000000000000..a931be322a2f --- /dev/null +++ b/drivers/hwtracing/coresight/rvtrace-atbbridge.c @@ -0,0 +1,239 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright(C) 2026 Spacemit Limited. All rights reserved. + */ + +#include +#include +#include +#include +#include + +#include "coresight-priv.h" +#include "coresight-trace-id.h" + +#define RVTRACE_ATBBRIDGE_CONTROL_ID_MASK GENMASK(14, 8) +/** + * struct atbbridge_data - specifics associated to a ATB bridge component + * @csdev: Component vitals needed by the framework. + * @spinlock: Only one at a time pls. + * @traceid: Value of the current ID for this component. + */ +struct atbbridge_data { + struct coresight_device *csdev; + spinlock_t spinlock; + u8 traceid; +}; + +DEFINE_CORESIGHT_DEVLIST(atbbridge_devs, "atbbridge"); + +static int atbbridge_enable(struct coresight_device *csdev, + struct coresight_connection *in, + struct coresight_connection *out) +{ + u32 control; + int ret = 0; + struct rvtrace_component *comp = dev_get_drvdata(csdev->dev.parent); + struct atbbridge_data *atbbridge_data = rvtrace_component_data(comp); + unsigned long flags; + + spin_lock_irqsave(&atbbridge_data->spinlock, flags); + if (!comp->was_reset) { + ret = rvtrace_component_reset(comp); + if (ret) + goto done; + } + + control = readl_relaxed(comp->base + RVTRACE_COMPONENT_CTRL_OFFSET); + control |= FIELD_PREP(RVTRACE_ATBBRIDGE_CONTROL_ID_MASK, atbbridge_data->traceid); + writel_relaxed(control, comp->base + RVTRACE_COMPONENT_CTRL_OFFSET); + + ret = rvtrace_enable_component(comp); + if (ret) + goto done; + + spin_unlock_irqrestore(&atbbridge_data->spinlock, flags); + + dev_dbg(&csdev->dev, "Trace ATB bridge enabled\n"); +done: + return ret; +} + +static void atbbridge_disable(struct coresight_device *csdev, + struct coresight_connection *in, + struct coresight_connection *out) +{ + struct rvtrace_component *comp = dev_get_drvdata(csdev->dev.parent); + struct atbbridge_data *atbbridge_data = rvtrace_component_data(comp); + unsigned long flags; + + spin_lock_irqsave(&atbbridge_data->spinlock, flags); + + if (rvtrace_disable_component(comp)) + dev_err(&csdev->dev, + "timeout while waiting for Trace ATB Bridge to be disabled\n"); + + if (rvtrace_comp_is_empty(comp)) + dev_err(&csdev->dev, + "timeout while waiting for Trace ATB Bridge internal buffers become empty\n"); + + spin_unlock_irqrestore(&atbbridge_data->spinlock, flags); + + dev_dbg(&csdev->dev, "Trace ATB bridge disabled\n"); +} + +static int atbbridge_link_trace_id(struct coresight_device *csdev, __maybe_unused enum cs_mode mode, + __maybe_unused struct coresight_device *sink) +{ + struct rvtrace_component *comp = dev_get_drvdata(csdev->dev.parent); + struct atbbridge_data *atbbridge_data = rvtrace_component_data(comp); + + return atbbridge_data->traceid; +} + +static const struct coresight_ops_link atbbridge_link_ops = { + .enable = atbbridge_enable, + .disable = atbbridge_disable, +}; + +static const struct coresight_ops atbbridge_cs_ops = { + .trace_id = atbbridge_link_trace_id, + .link_ops = &atbbridge_link_ops, +}; + +static ssize_t reset_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t size) +{ + unsigned long val; + struct rvtrace_component *comp = dev_get_drvdata(dev->parent); + struct atbbridge_data *atbbridge_data = rvtrace_component_data(comp); + unsigned long flags; + + if (kstrtoul(buf, 16, &val)) + return -EINVAL; + + if (val) { + if (rvtrace_component_reset(comp)) { + comp->was_reset = false; + spin_unlock_irqrestore(&atbbridge_data->spinlock, flags); + return -EINVAL; + } + } + + spin_unlock_irqrestore(&atbbridge_data->spinlock, flags); + + return size; +} +static DEVICE_ATTR_WO(reset); + +static ssize_t cpu_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + unsigned long val; + struct rvtrace_component *comp = dev_get_drvdata(dev->parent); + + val = comp->cpu; + return scnprintf(buf, PAGE_SIZE, "%#lx\n", val); +} +static DEVICE_ATTR_RO(cpu); + +static ssize_t traceid_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + unsigned long val; + struct rvtrace_component *comp = dev_get_drvdata(dev->parent); + struct atbbridge_data *atbbridge_data = rvtrace_component_data(comp); + + val = atbbridge_data->traceid; + return scnprintf(buf, PAGE_SIZE, "%#lx\n", val); +} +static DEVICE_ATTR_RO(traceid); + +static struct attribute *trace_atbbridge_attrs[] = { + coresight_simple_reg32(control, RVTRACE_COMPONENT_CTRL_OFFSET), + coresight_simple_reg32(impl, RVTRACE_COMPONENT_IMPL_OFFSET), + &dev_attr_reset.attr, + &dev_attr_cpu.attr, + &dev_attr_traceid.attr, + NULL, +}; +ATTRIBUTE_GROUPS(trace_atbbridge); + +static int atbbridge_probe(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct coresight_platform_data *pdata; + struct atbbridge_data *atbbridge_data; + struct rvtrace_component *comp; + struct coresight_desc desc = { 0 }; + int trace_id = 0; + + comp = rvtrace_register_component(pdev); + if (IS_ERR(comp)) + return PTR_ERR(comp); + + atbbridge_data = devm_kzalloc(dev, sizeof(*atbbridge_data), GFP_KERNEL); + if (!atbbridge_data) + return -ENOMEM; + + spin_lock_init(&atbbridge_data->spinlock); + + pdata = coresight_get_platform_data(dev); + if (IS_ERR(pdata)) + return PTR_ERR(pdata); + pdev->dev.platform_data = pdata; + + platform_set_drvdata(pdev, comp); + + desc.name = coresight_alloc_device_name(&atbbridge_devs, dev); + desc.access = CSDEV_ACCESS_IOMEM(comp->base); + desc.type = CORESIGHT_DEV_TYPE_LINK; + desc.subtype.link_subtype = CORESIGHT_DEV_SUBTYPE_LINK_FIFO; + desc.ops = &atbbridge_cs_ops; + desc.pdata = pdata; + desc.dev = dev; + desc.groups = trace_atbbridge_groups; + atbbridge_data->csdev = coresight_register(&desc); + if (IS_ERR(atbbridge_data->csdev)) + return PTR_ERR(atbbridge_data->csdev); + + trace_id = coresight_trace_id_get_system_id(); + if (trace_id < 0) + return -EINVAL; + atbbridge_data->traceid = (u8)trace_id; + + comp->id.data = atbbridge_data; + + dev_dbg(dev, "Trace ATB Bridge initialized\n"); + + return 0; +} + +static void atbbridge_remove(struct platform_device *pdev) +{ + struct rvtrace_component *comp = platform_get_drvdata(pdev); + struct atbbridge_data *atbbridge_data = rvtrace_component_data(comp); + + coresight_trace_id_put_system_id(atbbridge_data->traceid); + coresight_unregister(atbbridge_data->csdev); +} + +static const struct of_device_id atbbridge_match[] = { + {.compatible = "riscv,trace-atbbridge"}, + {}, +}; + +static struct platform_driver atbbridge_driver = { + .probe = atbbridge_probe, + .remove = atbbridge_remove, + .driver = { + .name = "trace-atbbridge", + .of_match_table = atbbridge_match, + }, +}; + +module_platform_driver(atbbridge_driver); + +MODULE_DESCRIPTION("RISC-V Trace ATB Bridge driver"); +MODULE_LICENSE("GPL"); -- 2.34.1