* [PATCH v3 03/24] firmware: arm_scmi: Allow registration of unknown-size events/reports
From: Cristian Marussi @ 2026-03-29 16:33 UTC (permalink / raw)
To: linux-kernel, linux-arm-kernel, arm-scmi, linux-fsdevel,
linux-doc
Cc: sudeep.holla, james.quinlan, f.fainelli, vincent.guittot,
etienne.carriere, peng.fan, michal.simek, dan.carpenter, d-gole,
jonathan.cameron, elif.topuz, lukasz.luba, philip.radford,
brauner, souvik.chakravarty, Cristian Marussi
In-Reply-To: <20260329163337.637393-1-cristian.marussi@arm.com>
Allow protocols to register events with build-time unknown sizes: such
events can be declared zero-sized and let the core SCMI stack perform the
needed safe-net boundary checks based on the configured transport size.
Signed-off-by: Cristian Marussi <cristian.marussi@arm.com>
---
v2 --> v3
- split out of previous patch on protocol notifier
- use max() instead of max_t()
---
drivers/firmware/arm_scmi/notify.c | 24 +++++++++++++++++++-----
drivers/firmware/arm_scmi/notify.h | 8 ++++++--
2 files changed, 25 insertions(+), 7 deletions(-)
diff --git a/drivers/firmware/arm_scmi/notify.c b/drivers/firmware/arm_scmi/notify.c
index 40ec184eedae..3e4c97ab7b61 100644
--- a/drivers/firmware/arm_scmi/notify.c
+++ b/drivers/firmware/arm_scmi/notify.c
@@ -595,7 +595,13 @@ int scmi_notify(const struct scmi_handle *handle, u8 proto_id, u8 evt_id,
if (!r_evt)
return -EINVAL;
- if (len > r_evt->evt->max_payld_sz) {
+ /*
+ * Events with a zero max_payld_sz are sized to be of the maximum
+ * size allowed by the transport: no need to be size-checked here
+ * since the transport layer would have already dropped such
+ * over-sized messages.
+ */
+ if (r_evt->evt->max_payld_sz && len > r_evt->evt->max_payld_sz) {
dev_err(handle->dev, "discard badly sized message\n");
return -EINVAL;
}
@@ -754,7 +760,7 @@ int scmi_register_protocol_events(const struct scmi_handle *handle, u8 proto_id,
const struct scmi_protocol_handle *ph,
const struct scmi_protocol_events *ee)
{
- int i;
+ int i, max_msg_sz;
unsigned int num_sources;
size_t payld_sz = 0;
struct scmi_registered_events_desc *pd;
@@ -769,6 +775,8 @@ int scmi_register_protocol_events(const struct scmi_handle *handle, u8 proto_id,
if (!ni)
return -ENOMEM;
+ max_msg_sz = ph->hops->get_max_msg_size(ph);
+
/* num_sources cannot be <= 0 */
if (ee->num_sources) {
num_sources = ee->num_sources;
@@ -781,8 +789,13 @@ int scmi_register_protocol_events(const struct scmi_handle *handle, u8 proto_id,
}
evt = ee->evts;
- for (i = 0; i < ee->num_events; i++)
- payld_sz = max_t(size_t, payld_sz, evt[i].max_payld_sz);
+ for (i = 0; i < ee->num_events; i++) {
+ if (evt[i].max_payld_sz == 0) {
+ payld_sz = max_msg_sz;
+ break;
+ }
+ payld_sz = max(payld_sz, evt[i].max_payld_sz);
+ }
payld_sz += sizeof(struct scmi_event_header);
pd = scmi_allocate_registered_events_desc(ni, proto_id, ee->queue_sz,
@@ -811,7 +824,8 @@ int scmi_register_protocol_events(const struct scmi_handle *handle, u8 proto_id,
mutex_init(&r_evt->sources_mtx);
r_evt->report = devm_kzalloc(ni->handle->dev,
- evt->max_report_sz, GFP_KERNEL);
+ evt->max_report_sz ?: max_msg_sz,
+ GFP_KERNEL);
if (!r_evt->report)
return -ENOMEM;
diff --git a/drivers/firmware/arm_scmi/notify.h b/drivers/firmware/arm_scmi/notify.h
index 76758a736cf4..ecfa4b746487 100644
--- a/drivers/firmware/arm_scmi/notify.h
+++ b/drivers/firmware/arm_scmi/notify.h
@@ -18,8 +18,12 @@
/**
* struct scmi_event - Describes an event to be supported
* @id: Event ID
- * @max_payld_sz: Max possible size for the payload of a notification message
- * @max_report_sz: Max possible size for the report of a notification message
+ * @max_payld_sz: Max possible size for the payload of a notification message.
+ * Set to zero to use the maximum payload size allowed by the
+ * transport.
+ * @max_report_sz: Max possible size for the report of a notification message.
+ * Set to zero to use the maximum payload size allowed by the
+ * transport.
*
* Each SCMI protocol, during its initialization phase, can describe the events
* it wishes to support in a few struct scmi_event and pass them to the core
--
2.53.0
^ permalink raw reply related
* [PATCH v3 02/24] firmware: arm_scmi: Reduce the scope of protocols mutex
From: Cristian Marussi @ 2026-03-29 16:33 UTC (permalink / raw)
To: linux-kernel, linux-arm-kernel, arm-scmi, linux-fsdevel,
linux-doc
Cc: sudeep.holla, james.quinlan, f.fainelli, vincent.guittot,
etienne.carriere, peng.fan, michal.simek, dan.carpenter, d-gole,
jonathan.cameron, elif.topuz, lukasz.luba, philip.radford,
brauner, souvik.chakravarty, Cristian Marussi
In-Reply-To: <20260329163337.637393-1-cristian.marussi@arm.com>
Currently the mutex dedicated to the protection of the list of registered
protocols is held during all the protocol initialization phase.
Such a wide locking region is not needed and causes problem when trying to
initialize notifications from within a protocol initialization routine.
Reduce the scope of the protocol mutex.
Signed-off-by: Cristian Marussi <cristian.marussi@arm.com>
---
v1-->v2
- Fixed improper mixed usage of cleanup and goto constructs
---
drivers/firmware/arm_scmi/driver.c | 50 ++++++++++++++----------------
1 file changed, 24 insertions(+), 26 deletions(-)
diff --git a/drivers/firmware/arm_scmi/driver.c b/drivers/firmware/arm_scmi/driver.c
index 3e76a3204ba4..26f192b8d7a9 100644
--- a/drivers/firmware/arm_scmi/driver.c
+++ b/drivers/firmware/arm_scmi/driver.c
@@ -17,6 +17,7 @@
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
#include <linux/bitmap.h>
+#include <linux/cleanup.h>
#include <linux/debugfs.h>
#include <linux/device.h>
#include <linux/export.h>
@@ -2190,7 +2191,6 @@ static void scmi_protocol_version_initialize(struct device *dev,
* all resources management is handled via a dedicated per-protocol devres
* group.
*
- * Context: Assumes to be called with @protocols_mtx already acquired.
* Return: A reference to a freshly allocated and initialized protocol instance
* or ERR_PTR on failure. On failure the @proto reference is at first
* put using @scmi_protocol_put() before releasing all the devres group.
@@ -2236,8 +2236,10 @@ scmi_alloc_init_protocol_instance(struct scmi_info *info,
if (ret)
goto clean;
- ret = idr_alloc(&info->protocols, pi, proto->id, proto->id + 1,
- GFP_KERNEL);
+ /* Finally register the initialized protocol */
+ mutex_lock(&info->protocols_mtx);
+ ret = idr_alloc(&info->protocols, pi, proto->id, proto->id + 1, GFP_KERNEL);
+ mutex_unlock(&info->protocols_mtx);
if (ret != proto->id)
goto clean;
@@ -2284,27 +2286,25 @@ scmi_alloc_init_protocol_instance(struct scmi_info *info,
static struct scmi_protocol_instance * __must_check
scmi_get_protocol_instance(const struct scmi_handle *handle, u8 protocol_id)
{
- struct scmi_protocol_instance *pi;
struct scmi_info *info = handle_to_scmi_info(handle);
+ const struct scmi_protocol *proto;
- mutex_lock(&info->protocols_mtx);
- pi = idr_find(&info->protocols, protocol_id);
-
- if (pi) {
- refcount_inc(&pi->users);
- } else {
- const struct scmi_protocol *proto;
+ scoped_guard(mutex, &info->protocols_mtx) {
+ struct scmi_protocol_instance *pi;
- /* Fails if protocol not registered on bus */
- proto = scmi_protocol_get(protocol_id, &info->version);
- if (proto)
- pi = scmi_alloc_init_protocol_instance(info, proto);
- else
- pi = ERR_PTR(-EPROBE_DEFER);
+ pi = idr_find(&info->protocols, protocol_id);
+ if (pi) {
+ refcount_inc(&pi->users);
+ return pi;
+ }
}
- mutex_unlock(&info->protocols_mtx);
- return pi;
+ /* Fails if protocol not registered on bus */
+ proto = scmi_protocol_get(protocol_id, &info->version);
+ if (!proto)
+ return ERR_PTR(-EPROBE_DEFER);
+
+ return scmi_alloc_init_protocol_instance(info, proto);
}
/**
@@ -2335,10 +2335,11 @@ void scmi_protocol_release(const struct scmi_handle *handle, u8 protocol_id)
struct scmi_info *info = handle_to_scmi_info(handle);
struct scmi_protocol_instance *pi;
- mutex_lock(&info->protocols_mtx);
- pi = idr_find(&info->protocols, protocol_id);
- if (WARN_ON(!pi))
- goto out;
+ scoped_guard(mutex, &info->protocols_mtx) {
+ pi = idr_find(&info->protocols, protocol_id);
+ if (WARN_ON(!pi))
+ return;
+ }
if (refcount_dec_and_test(&pi->users)) {
void *gid = pi->gid;
@@ -2357,9 +2358,6 @@ void scmi_protocol_release(const struct scmi_handle *handle, u8 protocol_id)
dev_dbg(handle->dev, "De-Initialized protocol: 0x%X\n",
protocol_id);
}
-
-out:
- mutex_unlock(&info->protocols_mtx);
}
void scmi_setup_protocol_implemented(const struct scmi_protocol_handle *ph,
--
2.53.0
^ permalink raw reply related
* [PATCH v3 01/24] firmware: arm_scmi: Add new SCMIv4.0 error codes definitions
From: Cristian Marussi @ 2026-03-29 16:33 UTC (permalink / raw)
To: linux-kernel, linux-arm-kernel, arm-scmi, linux-fsdevel,
linux-doc
Cc: sudeep.holla, james.quinlan, f.fainelli, vincent.guittot,
etienne.carriere, peng.fan, michal.simek, dan.carpenter, d-gole,
jonathan.cameron, elif.topuz, lukasz.luba, philip.radford,
brauner, souvik.chakravarty, Cristian Marussi
In-Reply-To: <20260329163337.637393-1-cristian.marussi@arm.com>
SCMIv4.0 introduces a couple of new possible protocol error codes: add
the needed definitions and mappings to Linux error values.
Signed-off-by: Cristian Marussi <cristian.marussi@arm.com>
---
drivers/firmware/arm_scmi/common.h | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/drivers/firmware/arm_scmi/common.h b/drivers/firmware/arm_scmi/common.h
index 7c35c95fddba..44af2018e21d 100644
--- a/drivers/firmware/arm_scmi/common.h
+++ b/drivers/firmware/arm_scmi/common.h
@@ -45,6 +45,8 @@ enum scmi_error_codes {
SCMI_ERR_GENERIC = -8, /* Generic Error */
SCMI_ERR_HARDWARE = -9, /* Hardware Error */
SCMI_ERR_PROTOCOL = -10,/* Protocol Error */
+ SCMI_ERR_IN_USE = -11, /* In Use Error */
+ SCMI_ERR_PARTIAL = -12, /* Partial Error */
};
static const int scmi_linux_errmap[] = {
@@ -60,6 +62,8 @@ static const int scmi_linux_errmap[] = {
-EIO, /* SCMI_ERR_GENERIC */
-EREMOTEIO, /* SCMI_ERR_HARDWARE */
-EPROTO, /* SCMI_ERR_PROTOCOL */
+ -EPERM, /* SCMI_ERR_IN_USE */
+ -EINVAL, /* SCMI_ERR_PARTIAL */
};
static inline int scmi_to_linux_errno(int errno)
--
2.53.0
^ permalink raw reply related
* [PATCH v3 00/24] Introduce SCMI Telemetry FS support
From: Cristian Marussi @ 2026-03-29 16:33 UTC (permalink / raw)
To: linux-kernel, linux-arm-kernel, arm-scmi, linux-fsdevel,
linux-doc
Cc: sudeep.holla, james.quinlan, f.fainelli, vincent.guittot,
etienne.carriere, peng.fan, michal.simek, dan.carpenter, d-gole,
jonathan.cameron, elif.topuz, lukasz.luba, philip.radford,
brauner, souvik.chakravarty, Cristian Marussi
Hi all,
the upcoming SCMI v4.0 specification [0] introduces a new SCMI protocol
dedicated to System Telemetry.
In a nutshell, the SCMI Telemetry protocol allows an agent to discover at
runtime the set of Telemetry Data Events (DEs) available on a specific
platform and provides the means to configure the set of DEs that a user is
interested into, while reading them back using the collection method that
is deeemed more suitable for the usecase at hand. (...amongst the various
possible collection methods allowed by SCMI specification)
Without delving into the gory details of the whole SCMI Telemetry protocol
let's just say that the SCMI platform/server firmware advertises a number
of Telemetry Data Events, each one identified by a 32bit unique ID, and an
SCMI agent/client, like Linux, can discover them and read back at will the
associated data value in a number of ways.
Data collection is mainly intended to happen on demand via shared memory
areas exposed by the platform firmware, discovered dynamically via SCMI
Telemetry and accessed by Linux on-demand, but some DE can also be reported
via SCMI Notifications asynchronous messages or via direct dedicated
FastChannels (another kind of SCMI memory based access): all of this
underlying mechanism is anyway hidden to the user since it is mediated by
the kernel driver which will return the proper data value when queried.
Anyway, the set of well-known architected DE IDs defined by the spec is
limited to a dozen IDs, which means that the vast majority of DE IDs are
customizable per-platform: as a consequence, though, the same ID, say
'0x1234', could represent completely different things on different systems.
Precise definitions and semantic of such custom Data Event IDs are out of
the scope of the SCMI Telemetry specification and of this implementation:
they are supposed to be provided using some kind of JSON-like description
file that will have to be consumed by a userspace tool which would be
finally in charge of making sense of the set of available DEs.
IOW, in turn, this means that even though the DEs enumerated via SCMI come
with some sort of topological and qualitative description provided by the
protocol (like unit of measurements, name, topology info etc), kernel-wise
we CANNOT be completely sure of "what is what" without being fed-back some
sort of information about the DEs by the afore mentioned userspace tool.
For these reasons, currently this series does NOT attempt to register any
of these DEs with any of the usual in-kernel subsystems (like HWMON, IIO,
PERF etc), simply because we cannot be sure which DE is suitable, or even
desirable, for a given subsystem. This also means there are NO in-kernel
users of these Telemetry data events as of now.
So, while we do not exclude, for the future, to feed/register some of the
discovered DEs to/with some of the above mentioned Kernel subsystems, as
of now we have ONLY modeled a custom userspace API to make SCMI Telemetry
available to userspace tools.
In deciding which kind of interface to expose SCMI Telemetry data to a
user, this new SCMI Telemetry driver aims at satisfying 2 main reqs:
- exposing an FS-based human-readable interface that can be used to
discover, configure and access our Telemetry data directly also from
the shell without special tools
- exposing alternative machine-friendly, more-performant, binary
interfaces that can be used to avoid the overhead of multiple accesses
to the VFS and that can be more suitable to access with custom tools
In the initial RFC posted a few months ago [1], the above was achieved
with a combination of a SysFS interface, for the human-readable side of
the story, and a classic chardev/ioctl for the plain binary access.
Since V1, instead, we moved away from this combined approach, especially
away from SysFS, for the following reason:
1. "Abusing SysFS": SysFS is a handy way to expose device related
properties in a common way, using a few common helpers built on
kernfs; this means, though, that unfortunately in our scenario I had
to generate a dummy simple device for EACH SCMI Telemetry DataEvent
that I got to discover at runtime and attach to them, all of the
properties I need.
This by itself seemed to me abusing the SysFS framework, but, even
ignoring this, the impact on the system when we have to deal with
hundreds or tens of thousands of DEs is sensible.
In some test scenario I ended with 50k DE devices and half-a-millon
related property files ... O_o
2. "SysFS constraints": SysFS usage itself has its well-known constraints
and best practices, like the one-file/one-value rule, and due to the
fact that any virtual file with a complex structure or handling logic
is frowned upon, you can forget about IOCTLs and mmap'ing to provide
a more performant interface within SysFs, which is the reason why,
in the previous RFC, there was an additional alternative chardev
interface.
These latter limitations around the implementation of files with a
more complex semantic (i.e. with a broader set of file_operations)
derive from the underlying KernFS support, so KernFS is equally not
suitable as a building block for our implementation.
2. "Chardev limitations": Given the nature of the protocol, the hybrid
approach employing character devices was itself problematic: first
of all because there is an upper limit on the number of chardev we
can create, dictated by the range of available minor numbers, and
then because the fact itself to have to maintain 2 completely
different interfaces (FS + chardev) is painful.
As a final remark, please NOTE THAT all of this is supposed to be available
in production systems across a number of heterogeneous platforms: for these
reasons the easy choice, debugFS, is NOT an option here.
Due to the above reasoning, since V1 we opted for a new approach with the
proposed interfaces now based on a full fledged, unified, virtual pseudo
filesystem implemented from scratch, so that we can:
- expose all the DEs property we like as before with SysFS, but without
any of the constraint imposed by the usage of SysFs or kernfs.
- easily expose additional alternative views of the same set of DEs
using symlinking capabilities (e.g. alternative topological view)
- additionally expose a few alternative and more performant interfaces
by embedding in that same FS, a few special virtual files:
+ 'control': to issue IOCTLs for quicker discovery and on-demand access
to data
+ 'pipe' [TBD]: to provide a stream of events using a virtual
infinite-style file
+ 'raw_<N>' [TBD]: to provide direct memory mapped access to the raw
SCMI Telemetry data from userspace
- use a mount option to enable a lazy enumeration operation mode to delay
SCMI related background discovery activities to the effective point in
time when the user needs it (if ever) so as to mitigate the effect at
boot-time of the initial SCMI full discovery process
INTERFACES
===========
We propose a couple of interfaces, both rooted in the same unified
SCMI Telemetry Filesystem STLMFS, which can be mounted with:
mount -t stlmfs none /sys/fs/arm_telemetry/
The new pseudo FS rationale, design and related ABI interface is documented
in detail at:
- Documentation/filesystems/stlmfs.rst
- Documentation/ABI/testing/stlmfs
...anyway, roughly, STLMFS exposes the following interfaces, rooted at
different points in the FS:
1. a FS based human-readable API tree
This API present the discovered DEs and DEs-groups rooted under a
structrure like this:
/sys/fs/arm_telemetry/tlm_0/
|-- all_des_enable
|-- all_des_tstamp_enable
|-- available_update_intervals_ms
|-- current_update_interval_ms
|-- de_implementation_version
|-- des
| |-- 0x00000000/
| |-- 0x00000016/
| |-- 0x00001010/
| |-- 0x0000A000/
| |-- 0x0000A001/
| |-- 0x0000A002/
| |-- 0x0000A005/
| |-- 0x0000A007/
| |-- 0x0000A008/
| |-- 0x0000A00A/
| |-- 0x0000A00B/
| |-- 0x0000A00C/
| `-- 0x0000A010/
|-- des_bulk_read
|-- des_single_sample_read
|-- groups
| |-- 0/
| `-- 1/
|-- intervals_discrete
|-- reset
|-- tlm_enable
`-- version
At the top level we have general configuration knobs to:
- enable/disable all DEs with or without tstamp
- configure the update interval that the platform will use
- enable Telemetry as a whole
- read all the enabled DEs in a buffer one-per-line
<DE_ID> <TIMESTAMP> <DATA_VALUE>
- des_single_sample_read to request an immediate updated read of
all the enabled DEs in a single buffer one-per-line:
<DE_ID> <TIMESTAMP> <DATA_VALUE>
where each DE in turn is represented by a flat subtree like:
tlm_0/des/0x0000A001/
|-- compo_instance_id
|-- compo_type
|-- enable
|-- instance_id
|-- name
|-- persistent
|-- tstamp_enable
|-- tstamp_exp
|-- type
|-- unit
|-- unit_exp
`-- value
where, beside a bunch of description items, you can:
- enable/disable a single DE
- read back its tstamp and data from 'value' as in:
<TIMESTAMP>: <DATA_VALUE>
then for each (optionally) discovered group of DEs:
scmi_tlm_0/groups/0/
|-- available_update_intervals_ms
|-- composing_des
|-- current_update_interval_ms
|-- des_bulk_read
|-- des_single_sample_read
|-- enable
|-- intervals_discrete
`-- tstamp_enable
you can find the knobs to:
- enable/disable the group as a whole
- lookup group composition
- set a per-group update interval (if supported)
- des_bulk_read to read all the enabled DEs for this group in a
single buffer one-per-line:
<DE_ID> <TIMESTAMP> <DATA_VALUE>
- des_single_sample_read to request an immediate updated read of
all the enabled DEs for this group in a single buffer
one-per-line:
<DE_ID> <TIMESTAMP> <DATA_VALUE>
2. Leveraging the capabilities offered by the full-fledged filesystem
implementation and the topological information provided by SCMI
Telemetry we expose also and alternative view of the above tree, by
symlinking a few of the same entries above under another, topologically
sorted, subtree:
by_components/
├── cpu
│ ├── 0
│ │ ├── celsius
│ │ │ └── 0
│ │ │ └── 0x00000001[pe_0] -> ../../../../../des/0x00000001
│ │ └── cycles
│ │ ├── 0
│ │ │ └── 0x00001010[] -> ../../../../../des/0x00001010
│ │ └── 1
│ │ └── 0x00002020[] -> ../../../../../des/0x00002020
│ ├── 1
│ │ └── celsius
│ │ └── 0
│ │ └── 0x00000002[pe_1] -> ../../../../../des/0x00000002
│ └── 2
│ └── celsius
│ └── 0
│ └── 0x00000003[pe_2] -> ../../../../../des/0x00000003
├── interconnnect
│ └── 0
│ └── hertz
│ └── 0
│ ├── 0x0000A008[A008_de] -> ../../../../../des/0x0000A008
│ └── 0x0000A00B[] -> ../../../../../des/0x0000A00B
├── mem_cntrl
│ └── 0
│ ├── bps
│ │ └── 0
│ │ └── 0x0000A00A[] -> ../../../../../des/0x0000A00A
│ ├── celsius
│ │ └── 0
│ │ └── 0x0000A007[DRAM_temp] -> ../../../../../des/0x0000A007
│ └── joules
│ └── 0
│ └── 0x0000A002[DRAM_energy] -> ../../../../../des/0x0000A002
├── periph
│ ├── 0
│ │ └── messages
│ │ └── 0
│ │ └── 0x00000016[device_16] -> ../../../../../des/0x00000016
│ ├── 1
│ │ └── messages
│ │ └── 0
│ │ └── 0x00000017[device_17] -> ../../../../../des/0x00000017
│ └── 2
│ └── messages
│ └── 0
│ └── 0x00000018[device_18] -> ../../../../../des/0x00000018
└── unspec
└── 0
├── celsius
│ └── 0
│ └── 0x0000A005[] -> ../../../../../des/0x0000A005
├── counts
│ └── 0
│ └── 0x0000A00C[] -> ../../../../../des/0x0000A00C
├── joules
│ └── 0
│ ├── 0x0000A000[SOC_Energy] -> ../../../../../des/0x0000A000
│ └── 0x0000A001[] -> ../../../../../des/0x0000A001
└── state
└── 0
└── 0x0000A010[] -> ../../../../../des/0x0000A010
...so as to provide the human user with a more understandable topological
layout of the madness...
All of this is nice and fancy human-readable, easily scriptable, but
certainly not the fastest possible to access especially on huge trees...
... so for the afore-mentioned reasons we alternatively expose
3. a more performant API based on IOCTLs as described fully in:
include/uapi/linux/scmi.h
As described succinctly in the above UAPI header too, this API is meant
to be called on a few special files named 'control' that are populated
into the tree:
.
|-- all_des_enable
.....
|-- components
| |-- cpu
| |-- interconnnect
| |-- mem_cntrl
| |-- periph
| `-- unspec
|-- control
.....................
|-- groups
| |-- 0
| | |-- available_update_intervals_ms
| | |-- composing_des
| | |-- control
.....................
| |-- 1
| | |-- available_update_intervals_ms
| | |-- composing_des
| | |-- control
.....................
| `-- 2
| |-- available_update_intervals_ms
| |-- composing_des
| |-- control
.....................
This allows a tool to:
- use some IOCTLs to configure a set of properties equivalent to the
ones above in FS
- use some other IOCTLs for direct access to data in binary format
for a single DEs or all of them
4. [FUTURE/NOT IN THIS V3]
Add another alternative and completely binary direct raw access
interface via a new set of memory mappable special files so as to allow
userspace tools to access SCMI Telemetry data directly in binary form
without any kernel mediation.
NOTE THAT this series, at the firmware interface level NOW supports ONLY
the latest SCMI v4.0 BETA specification [0].
Missing feats & next steps
--------------------------
- add direct access interface via mmap-able 'raw' files
- add streaming mode interface via 'pipe' file (tentative)
- evolve/enhance app in tools/testing/scmi/stlm to be interactive
KNOWN ISSUES
------------
- STLMFS code layout and location...nothing lives in fs/ and no distinct
FS Kconfig...but the SCMI Telemetry driver itself has no point in existing
without the FS that exposes...so should I split the pure FS part into fs/
anyway or not ?
- residual sparse/smatch static analyzers errors
- stlm tool utility is minimal for testing or development
Based on V7.0-rc5, tested on an emulated setup.
This series is available also at [2].
If you still reading...any feedback welcome :P
Thanks,
Cristian
----
V2 --> V3
- rebased on v7.0-rc5
- ported the firmware interface to SCMI v4.0 BETA
- split the SCMI protocol layer in a lot of small patches
- completd filesystem and ABI documentation
- renamed components subtree to by_components
- fixed uninitialized var in scmi_telemetry_de_subdir_symlink
- renamd tstamp_exp to tstamp_rate
- swap logic in scmi_telemetry_initial_state_lookup
- use memcpy_from_le32 where required
- changed a dfew dev_err into Telemetry traces
- define and use new helper scmi_telemetry_de_unlink
- simplify a few assignments with ternary ops
- added a missing __mmust_check on the internal SCMI API
- reworked and clarified de_data_read returned errno:
ENODATA vs EINVAL vs ENODEV/ENOENT
- removed some risky/unneeded devres allocations
- various checkpatch fixes
- reworked and clarified usage of traces in Telemetry
- added the missing DT binding for protocol 0x1B
- split out unrelated change around notification from patch
adding support for protocol internal notifier
- more comments
V1 --> V2
- rebased on v6.19-rc3
- harden TDCF shared memory areas accesses by using proper accessors
- reworked protocol resources lifecycle to allow lazy enumeration
- using NEW FS mount API
- reworked FS inode allocation to use a std kmem_cache
- fixed a few IOCTLs support routine to support lazy enumeration
- added (RFC) a new FS lazy mount option to support lazily population of
some subtrees of the FS (des/ groups/ components/)
- reworked implementation of components/ alternative FS view to use
symlinks instead of hardlinks
- added a basic simple (RFC) testing tool to exercise UAPI ioctls interface
- hardened Telmetry protocol and driver to support partial out-of-spec FW
lacking some cmds (best effort)
- reworked probing races handling
- reviewed behaviour on unmount/unload
- added support for Boot_ON Telemetry by supporting SCMI Telemetry cmds:
+ DE_ENABLED_LIST
+ CONFIG_GET
- added FS and ABI docs
RFC --> V1
---
- moved from SysFS/chardev to a full fledged FS
- added support for SCMI Telemetry BLK timestamps
Thanks,
Cristian
[0]: https://developer.arm.com/documentation/den0056/fb/?lang=en
[1]: https://lore.kernel.org/arm-scmi/20250620192813.2463367-1-cristian.marussi@arm.com/
[2]: https://git.kernel.org/pub/scm/linux/kernel/git/cris/linux.git/log/?h=scmi/scmi_telemetry_unified_fs_V3
Cristian Marussi (24):
firmware: arm_scmi: Add new SCMIv4.0 error codes definitions
firmware: arm_scmi: Reduce the scope of protocols mutex
firmware: arm_scmi: Allow registration of unknown-size events/reports
firmware: arm_scmi: Allow protocols to register for notifications
uapi: Add ARM SCMI definitions
dt-bindings: firmware: arm,scmi: Add support for telemetry protocol
include: trace: Add Telemetry trace events
firmware: arm_scmi: Add basic Telemetry support
firmware: arm_scmi: Add support to parse SHMTIs areas
firmware: arm_scmi: Add Telemetry configuration operations
firmware: arm_scmi: Add Telemetry DataEvent read capabilities
firmware: arm_scmi: Add support for Telemetry reset
firmware: arm_scmi: Add Telemetry notification support
firmware: arm_scmi: Add support for boot-on Telemetry
firmware: arm_scmi: Add System Telemetry filesystem driver
fs/stlmfs: Document ARM SCMI Telemetry filesystem
firmware: arm_scmi: Add System Telemetry ioctls support
fs/stlmfs: Document alternative ioctl based binary interface
firmware: arm_scmi: Add Telemetry components view
fs/stlmfs: Document alternative topological view
[RFC] docs: stlmfs: Document ARM SCMI Telemetry FS ABI
firmware: arm_scmi: Add lazy population support to Telemetry FS
fs/stlmfs: Document lazy mode and related mount option
[RFC] tools/scmi: Add SCMI Telemetry testing tool
Documentation/ABI/testing/stlmfs | 297 ++
.../bindings/firmware/arm,scmi.yaml | 8 +
Documentation/filesystems/stlmfs.rst | 312 ++
MAINTAINERS | 1 +
drivers/firmware/arm_scmi/Kconfig | 10 +
drivers/firmware/arm_scmi/Makefile | 3 +-
drivers/firmware/arm_scmi/common.h | 10 +
drivers/firmware/arm_scmi/driver.c | 64 +-
drivers/firmware/arm_scmi/notify.c | 30 +-
drivers/firmware/arm_scmi/notify.h | 8 +-
drivers/firmware/arm_scmi/protocols.h | 7 +
.../firmware/arm_scmi/scmi_system_telemetry.c | 2946 ++++++++++++++++
drivers/firmware/arm_scmi/telemetry.c | 3081 +++++++++++++++++
include/linux/scmi_protocol.h | 185 +-
include/trace/events/scmi.h | 48 +-
include/uapi/linux/scmi.h | 289 ++
tools/testing/scmi/Makefile | 25 +
tools/testing/scmi/stlm.c | 385 ++
18 files changed, 7670 insertions(+), 39 deletions(-)
create mode 100644 Documentation/ABI/testing/stlmfs
create mode 100644 Documentation/filesystems/stlmfs.rst
create mode 100644 drivers/firmware/arm_scmi/scmi_system_telemetry.c
create mode 100644 drivers/firmware/arm_scmi/telemetry.c
create mode 100644 include/uapi/linux/scmi.h
create mode 100644 tools/testing/scmi/Makefile
create mode 100644 tools/testing/scmi/stlm.c
--
2.53.0
^ permalink raw reply
* Re: [PATCH] mailbox: Fix NULL message support in mbox_send_message()
From: Jassi Brar @ 2026-03-29 16:33 UTC (permalink / raw)
To: linux-kernel, linux-arm-kernel
Cc: dianders, shawn.guo, maz, andersson, tglx, joonwonkang
In-Reply-To: <20260327220040.53326-1-jassisinghbrar@gmail.com>
On Fri, Mar 27, 2026 at 5:00 PM <jassisinghbrar@gmail.com> wrote:
>
> From: Jassi Brar <jassisinghbrar@gmail.com>
>
> The active_req field serves double duty as both the "is a TX in
> flight" flag (NULL means idle) and the storage for the in-flight
> message pointer. When a client sends NULL via mbox_send_message(),
> active_req is set to NULL, which the framework misinterprets as
> "no active request". This breaks the TX state machine by:
>
> - tx_tick() short-circuits on (!mssg), skipping the tx_done
> callback and the tx_complete completion
> - txdone_hrtimer() skips the channel entirely since active_req
> is NULL, so poll-based TX-done detection never fires.
>
> Fix this by introducing a MBOX_NO_MSG sentinel value that means
> "no active request," freeing NULL to be valid message data. The
> sentinel is defined in the subsystem-internal mailbox.h so that
> controller drivers within drivers/mailbox/ can reference it, but
> it is not exposed to clients outside the subsystem.
>
> Fifteen in-tree callers send NULL (doorbell-style IPCs on Qualcomm,
> Tegra, TI, Xilinx, i.MX, SCMI, and PCC platforms). All were
> audited for regression:
>
> - Most already work around the bug via knows_txdone=true with a
> manual mbox_client_txdone() call, making the framework's
> tracking irrelevant. These are unaffected.
>
> - Poll-based callers (Xilinx zynqmp/r5) are strictly better off:
> the poll timer now correctly detects NULL-active channels
> instead of silently skipping them.
>
> - irq-qcom-mpm.c was a pre-existing bug -- the only Qualcomm
> caller that omitted the knows_txdone + mbox_client_txdone()
> pattern. Fixed in a companion commit ("irqchip/qcom-mpm: Fix
> missing mailbox TX done acknowledgment").
>
> - No caller sets both a tx_done callback and sends NULL, nor
> combines tx_block=true with NULL sends, so the newly reachable
> callback/completion paths are never exercised.
>
> Also update tegra-hsp's flush callback, which directly inspects
> active_req to wait for the channel to drain: the old "!= NULL"
> check becomes "!= MBOX_NO_MSG", otherwise flush spins until
> timeout since the sentinel is non-NULL.
>
> The only tradeoff is that 'MBOX_NO_MSG' can not be used as a message
> by clients.
>
> Reported-by: Joonwon Kang <joonwonkang@google.com>
> Reviewed-by: Douglas Anderson <dianders@chromium.org>
> Signed-off-by: Jassi Brar <jassisinghbrar@gmail.com>
> ---
> drivers/mailbox/mailbox.c | 15 ++++++++-------
> drivers/mailbox/mailbox.h | 3 +++
> drivers/mailbox/tegra-hsp.c | 2 +-
> 3 files changed, 12 insertions(+), 8 deletions(-)
>
> diff --git a/drivers/mailbox/mailbox.c b/drivers/mailbox/mailbox.c
> index 617ba505691d..9622369cab66 100644
> --- a/drivers/mailbox/mailbox.c
> +++ b/drivers/mailbox/mailbox.c
> @@ -52,7 +52,7 @@ static void msg_submit(struct mbox_chan *chan)
> int err = -EBUSY;
>
> scoped_guard(spinlock_irqsave, &chan->lock) {
> - if (!chan->msg_count || chan->active_req)
> + if (!chan->msg_count || chan->active_req != MBOX_NO_MSG)
> break;
>
> count = chan->msg_count;
> @@ -87,13 +87,13 @@ static void tx_tick(struct mbox_chan *chan, int r)
>
> scoped_guard(spinlock_irqsave, &chan->lock) {
> mssg = chan->active_req;
> - chan->active_req = NULL;
> + chan->active_req = MBOX_NO_MSG;
> }
>
> /* Submit next message */
> msg_submit(chan);
>
> - if (!mssg)
> + if (mssg == MBOX_NO_MSG)
> return;
>
> /* Notify the client */
> @@ -114,7 +114,7 @@ static enum hrtimer_restart txdone_hrtimer(struct hrtimer *hrtimer)
> for (i = 0; i < mbox->num_chans; i++) {
> struct mbox_chan *chan = &mbox->chans[i];
>
> - if (chan->active_req && chan->cl) {
> + if (chan->active_req != MBOX_NO_MSG && chan->cl) {
> txdone = chan->mbox->ops->last_tx_done(chan);
> if (txdone)
> tx_tick(chan, 0);
> @@ -246,7 +246,7 @@ int mbox_send_message(struct mbox_chan *chan, void *mssg)
> {
> int t;
>
> - if (!chan || !chan->cl)
> + if (!chan || !chan->cl || mssg == MBOX_NO_MSG)
> return -EINVAL;
>
> t = add_to_rbuf(chan, mssg);
> @@ -319,7 +319,7 @@ static int __mbox_bind_client(struct mbox_chan *chan, struct mbox_client *cl)
> scoped_guard(spinlock_irqsave, &chan->lock) {
> chan->msg_free = 0;
> chan->msg_count = 0;
> - chan->active_req = NULL;
> + chan->active_req = MBOX_NO_MSG;
> chan->cl = cl;
> init_completion(&chan->tx_complete);
>
> @@ -477,7 +477,7 @@ void mbox_free_channel(struct mbox_chan *chan)
> /* The queued TX requests are simply aborted, no callbacks are made */
> scoped_guard(spinlock_irqsave, &chan->lock) {
> chan->cl = NULL;
> - chan->active_req = NULL;
> + chan->active_req = MBOX_NO_MSG;
> if (chan->txdone_method == TXDONE_BY_ACK)
> chan->txdone_method = TXDONE_BY_POLL;
> }
> @@ -532,6 +532,7 @@ int mbox_controller_register(struct mbox_controller *mbox)
>
> chan->cl = NULL;
> chan->mbox = mbox;
> + chan->active_req = MBOX_NO_MSG;
> chan->txdone_method = txdone;
> spin_lock_init(&chan->lock);
> }
> diff --git a/drivers/mailbox/mailbox.h b/drivers/mailbox/mailbox.h
> index e1ec4efab693..c77dd6fc5b8a 100644
> --- a/drivers/mailbox/mailbox.h
> +++ b/drivers/mailbox/mailbox.h
> @@ -5,6 +5,9 @@
>
> #include <linux/bits.h>
>
> +/* Sentinel value distinguishing "no active request" from "NULL message data" */
> +#define MBOX_NO_MSG ((void *)-1)
> +
> #define TXDONE_BY_IRQ BIT(0) /* controller has remote RTR irq */
> #define TXDONE_BY_POLL BIT(1) /* controller can read status of last TX */
> #define TXDONE_BY_ACK BIT(2) /* S/W ACK received by Client ticks the TX */
> diff --git a/drivers/mailbox/tegra-hsp.c b/drivers/mailbox/tegra-hsp.c
> index ed9a0bb2bcd8..7991e8dba579 100644
> --- a/drivers/mailbox/tegra-hsp.c
> +++ b/drivers/mailbox/tegra-hsp.c
> @@ -497,7 +497,7 @@ static int tegra_hsp_mailbox_flush(struct mbox_chan *chan,
> mbox_chan_txdone(chan, 0);
>
> /* Wait until channel is empty */
> - if (chan->active_req != NULL)
> + if (chan->active_req != MBOX_NO_MSG)
> continue;
>
> return 0;
> --
> 2.52.0
>
Applied to mailbox/for-next
^ permalink raw reply
* Re: [PATCH] mailbox: cix: Add IRQF_NO_SUSPEND to mailbox interrupt
From: Jassi Brar @ 2026-03-29 16:32 UTC (permalink / raw)
To: Dylan Wu
Cc: Peter Chen, Fugang Duan, cix-kernel-upstream, linux-arm-kernel,
linux-kernel
In-Reply-To: <20260209083452.154983-1-fredwudi0305@gmail.com>
On Mon, Feb 9, 2026 at 2:34 AM Dylan Wu <fredwudi0305@gmail.com> wrote:
>
> During the system suspend process, device interrupts are masked in the
> noirq phase. However, SCMI often needs to exchange final messages with the
> firmware to complete the power-down transition. Without the IRQF_NO_SUSPEND
> flag, the mailbox ISR cannot run during this late stage, leading to SCMI
> communication timeouts and error messages like "SCMI protocol wait for
> resp timeout" during suspend.
>
> Add the IRQF_NO_SUSPEND flag to the interrupt request to ensure the mailbox
> can continue to handle responses during the noirq stages of suspend and
> resume, thereby ensuring a reliable power state transition.
>
> Signed-off-by: Dylan Wu <fredwudi0305@gmail.com>
> ---
> drivers/mailbox/cix-mailbox.c | 2 +-
> 1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/drivers/mailbox/cix-mailbox.c b/drivers/mailbox/cix-mailbox.c
> index 5bb1416c26a5..5e27c2bf3492 100644
> --- a/drivers/mailbox/cix-mailbox.c
> +++ b/drivers/mailbox/cix-mailbox.c
> @@ -405,7 +405,7 @@ static int cix_mbox_startup(struct mbox_chan *chan)
> int index = cp->index, ret;
> u32 val;
>
> - ret = request_irq(priv->irq, cix_mbox_isr, 0,
> + ret = request_irq(priv->irq, cix_mbox_isr, IRQF_NO_SUSPEND,
> dev_name(priv->dev), chan);
> if (ret) {
> dev_err(priv->dev, "Unable to acquire IRQ %d\n", priv->irq);
> --
> 2.52.0
>
Applied to mailbox/for-next
Thanks
Jassi
^ permalink raw reply
* Re: [PATCH v2 1/2] dt-bindings: perf: marvell: Document CN20K DDR PMU
From: Rob Herring (Arm) @ 2026-03-29 16:31 UTC (permalink / raw)
To: Geetha sowjanya
Cc: krzk+dt, mark.rutland, linux-kernel, will, linux-perf-users,
linux-arm-kernel, devicetree
In-Reply-To: <20260329152439.10573-2-gakula@marvell.com>
On Sun, 29 Mar 2026 20:54:38 +0530, Geetha sowjanya wrote:
> Add a devicetree binding for the Marvell CN20K DDR performance
> monitor block, including the marvell,cn20k-ddr-pmu compatible
> string and the required MMIO reg region.
>
> Signed-off-by: Geetha sowjanya <gakula@marvell.com>
> ---
>
> Changes in v1:
> - Added a description field to the binding.
> - Simplified the compatible property using 'const' instead of 'items/enum'.
> - Updated the example node name to include a unit-address matching the reg base.
>
> .../bindings/perf/marvell-cn20k-ddr.yaml | 39 +++++++++++++++++++
> 1 file changed, 39 insertions(+)
> create mode 100644 Documentation/devicetree/bindings/perf/marvell-cn20k-ddr.yaml
>
My bot found errors running 'make dt_binding_check' on your patch:
yamllint warnings/errors:
./Documentation/devicetree/bindings/perf/marvell-cn20k-ddr.yaml:35:1: [error] syntax error: found character '\t' that cannot start any token (syntax)
dtschema/dtc warnings/errors:
/builds/robherring/dt-review-ci/linux/Documentation/devicetree/bindings/perf/marvell-cn20k-ddr.yaml: ignoring, error parsing file
./Documentation/devicetree/bindings/perf/marvell-cn20k-ddr.yaml:35:1: found character '\t' that cannot start any token
make[2]: *** Deleting file 'Documentation/devicetree/bindings/perf/marvell-cn20k-ddr.example.dts'
Documentation/devicetree/bindings/perf/marvell-cn20k-ddr.yaml:35:1: found character '\t' that cannot start any token
make[2]: *** [Documentation/devicetree/bindings/Makefile:26: Documentation/devicetree/bindings/perf/marvell-cn20k-ddr.example.dts] Error 1
make[2]: *** Waiting for unfinished jobs....
make[1]: *** [/builds/robherring/dt-review-ci/linux/Makefile:1614: dt_binding_check] Error 2
make: *** [Makefile:248: __sub-make] Error 2
doc reference errors (make refcheckdocs):
See https://patchwork.kernel.org/project/devicetree/patch/20260329152439.10573-2-gakula@marvell.com
The base for the series is generally the latest rc1. A different dependency
should be noted in *this* patch.
If you already ran 'make dt_binding_check' and didn't see the above
error(s), then make sure 'yamllint' is installed and dt-schema is up to
date:
pip3 install dtschema --upgrade
Please check and re-submit after running the above command yourself. Note
that DT_SCHEMA_FILES can be set to your schema file to speed up checking
your schema. However, it must be unset to test all examples with your schema.
^ permalink raw reply
* Re: [PATCH] mailbox: mtk-vcp-mailbox: Fix the return value in mtk_vcp_mbox_xlate()
From: Jassi Brar @ 2026-03-29 16:29 UTC (permalink / raw)
To: Felix Gu
Cc: Matthias Brugger, AngeloGioacchino Del Regno, Jjian Zhou,
Chen-Yu Tsai, linux-kernel, linux-arm-kernel, linux-mediatek
In-Reply-To: <20260226-vcp-v1-1-766c5877017d@gmail.com>
On Wed, Feb 25, 2026 at 10:33 AM Felix Gu <ustc.gu@gmail.com> wrote:
>
> The return value of mtk_vcp_mbox_xlate() is checked by IS_ERR(), so
> return NULL is incorrect and could lead to a NULL pointer dereference.
>
> Fixes: b562abd95672 ("mailbox: mediatek: Add mtk-vcp-mailbox driver")
> Signed-off-by: Felix Gu <ustc.gu@gmail.com>
> ---
> drivers/mailbox/mtk-vcp-mailbox.c | 2 +-
> 1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/drivers/mailbox/mtk-vcp-mailbox.c b/drivers/mailbox/mtk-vcp-mailbox.c
> index cedad575528f..1b291b8ea15a 100644
> --- a/drivers/mailbox/mtk-vcp-mailbox.c
> +++ b/drivers/mailbox/mtk-vcp-mailbox.c
> @@ -50,7 +50,7 @@ static struct mbox_chan *mtk_vcp_mbox_xlate(struct mbox_controller *mbox,
> const struct of_phandle_args *sp)
> {
> if (sp->args_count)
> - return NULL;
> + return ERR_PTR(-EINVAL);
>
> return &mbox->chans[0];
> }
>
Applied to mailbox/for-next
Thanks
Jassi
^ permalink raw reply
* Re: [PATCH] mailbox: rockchip: kzalloc + kcalloc to kzalloc
From: Jassi Brar @ 2026-03-29 16:28 UTC (permalink / raw)
To: Rosen Penev
Cc: linux-kernel, Heiko Stuebner,
moderated list:ARM/Rockchip SoC support,
open list:ARM/Rockchip SoC support
In-Reply-To: <20260311003744.32099-1-rosenp@gmail.com>
On Tue, Mar 10, 2026 at 7:38 PM Rosen Penev <rosenp@gmail.com> wrote:
>
> Use a flexible array member to reduce allocations.
>
> Signed-off-by: Rosen Penev <rosenp@gmail.com>
> ---
> drivers/mailbox/rockchip-mailbox.c | 9 ++-------
> 1 file changed, 2 insertions(+), 7 deletions(-)
>
> diff --git a/drivers/mailbox/rockchip-mailbox.c b/drivers/mailbox/rockchip-mailbox.c
> index 4d966cb2ed03..a1a7dee64356 100644
> --- a/drivers/mailbox/rockchip-mailbox.c
> +++ b/drivers/mailbox/rockchip-mailbox.c
> @@ -46,7 +46,7 @@ struct rockchip_mbox {
> /* The maximum size of buf for each channel */
> u32 buf_size;
>
> - struct rockchip_mbox_chan *chans;
> + struct rockchip_mbox_chan chans[];
> };
>
> static int rockchip_mbox_send_data(struct mbox_chan *chan, void *data)
> @@ -173,15 +173,10 @@ static int rockchip_mbox_probe(struct platform_device *pdev)
>
> drv_data = (const struct rockchip_mbox_data *) device_get_match_data(&pdev->dev);
>
> - mb = devm_kzalloc(&pdev->dev, sizeof(*mb), GFP_KERNEL);
> + mb = devm_kzalloc(&pdev->dev, struct_size(mb, chans, drv_data->num_chans), GFP_KERNEL);
> if (!mb)
> return -ENOMEM;
>
> - mb->chans = devm_kcalloc(&pdev->dev, drv_data->num_chans,
> - sizeof(*mb->chans), GFP_KERNEL);
> - if (!mb->chans)
> - return -ENOMEM;
> -
> mb->mbox.chans = devm_kcalloc(&pdev->dev, drv_data->num_chans,
> sizeof(*mb->mbox.chans), GFP_KERNEL);
> if (!mb->mbox.chans)
> --
> 2.53.0
>
Applied to mailbox/for-next
Thanks
Jassi
^ permalink raw reply
* Re: [PATCH] mailbox: mtk-cmdq: Fix CURR and END addr for task insert case
From: Jassi Brar @ 2026-03-29 16:18 UTC (permalink / raw)
To: Jason-JH Lin
Cc: Chun-Kuang Hu, AngeloGioacchino Del Regno, Matthias Brugger,
Nancy Lin, Singo Chang, Paul-PL Chen, Xiandong Wang, Sirius Wang,
Fei Shao, Chen-yu Tsai, Project_Global_Chrome_Upstream_Group,
linux-kernel, linux-mediatek, linux-arm-kernel
In-Reply-To: <20260323090742.1522607-1-jason-jh.lin@mediatek.com>
On Mon, Mar 23, 2026 at 4:07 AM Jason-JH Lin <jason-jh.lin@mediatek.com> wrote:
>
> Fix CURR and END address calculation for inserting a cmdq task into the
> task list by using cmdq_reg_shift_addr() for proper address converting.
> This ensures both CURR and END addresses are set correctly when
> enabling the thread.
>
> Fixes: a195c7ccfb7a ("mailbox: mtk-cmdq: Refine DMA address handling for the command buffer")
> Signed-off-by: Jason-JH Lin <jason-jh.lin@mediatek.com>
> ---
> drivers/mailbox/mtk-cmdq-mailbox.c | 8 ++++----
> 1 file changed, 4 insertions(+), 4 deletions(-)
>
> diff --git a/drivers/mailbox/mtk-cmdq-mailbox.c b/drivers/mailbox/mtk-cmdq-mailbox.c
> index d7c6b38888a3..547a10a8fad3 100644
> --- a/drivers/mailbox/mtk-cmdq-mailbox.c
> +++ b/drivers/mailbox/mtk-cmdq-mailbox.c
> @@ -493,14 +493,14 @@ static int cmdq_mbox_send_data(struct mbox_chan *chan, void *data)
> if (curr_pa == end_pa - CMDQ_INST_SIZE ||
> curr_pa == end_pa) {
> /* set to this task directly */
> - writel(task->pa_base >> cmdq->pdata->shift,
> - thread->base + CMDQ_THR_CURR_ADDR);
> + gce_addr = cmdq_convert_gce_addr(task->pa_base, cmdq->pdata);
> + writel(gce_addr, thread->base + CMDQ_THR_CURR_ADDR);
> } else {
> cmdq_task_insert_into_thread(task);
> smp_mb(); /* modify jump before enable thread */
> }
> - writel((task->pa_base + pkt->cmd_buf_size) >> cmdq->pdata->shift,
> - thread->base + CMDQ_THR_END_ADDR);
> + gce_addr = cmdq_convert_gce_addr(task->pa_base + pkt->cmd_buf_size, cmdq->pdata);
> + writel(gce_addr, thread->base + CMDQ_THR_END_ADDR);
> cmdq_thread_resume(thread);
> }
> list_move_tail(&task->list_entry, &thread->task_busy_list);
> --
> 2.43.0
>
Applied to mailbox/for-next
Thanks
Jassi
^ permalink raw reply
* Re: [PATCH v3] mailbox: remove superfluous internal header
From: Jassi Brar @ 2026-03-29 16:18 UTC (permalink / raw)
To: Wolfram Sang
Cc: linux-renesas-soc, Sudeep Holla, Daniel Baluta, Peter Chen,
Fugang Duan, CIX Linux Kernel Upstream Group, Frank Li,
Sascha Hauer, Pengutronix Kernel Team, Fabio Estevam,
Thierry Reding, Jonathan Hunter, linux-kernel, linux-arm-kernel,
imx, linux-acpi, linux-tegra
In-Reply-To: <20260327151112.5202-2-wsa+renesas@sang-engineering.com>
On Fri, Mar 27, 2026 at 10:11 AM Wolfram Sang
<wsa+renesas@sang-engineering.com> wrote:
>
> Quite some controller drivers use the defines from the internal header
> already. This prevents controller drivers outside the mailbox directory.
> Move the defines to the public controller header to allow this again as
> the defines are not strictly internal anyhow.
>
> Signed-off-by: Wolfram Sang <wsa+renesas@sang-engineering.com>
> Reviewed-by: Sudeep Holla <sudeep.holla@kernel.org>
> Reviewed-by: Daniel Baluta <daniel.baluta@nxp.com>
> ---
>
> Changes since v2:
> * rebased to 7.0-rc5
> * add tag (Thanks, Daniel!)
>
> drivers/mailbox/cix-mailbox.c | 2 --
> drivers/mailbox/hi3660-mailbox.c | 2 --
> drivers/mailbox/imx-mailbox.c | 2 --
> drivers/mailbox/mailbox-sti.c | 2 --
> drivers/mailbox/mailbox.c | 2 --
> drivers/mailbox/mailbox.h | 12 ------------
> drivers/mailbox/omap-mailbox.c | 2 --
> drivers/mailbox/pcc.c | 2 --
> drivers/mailbox/tegra-hsp.c | 2 --
> include/linux/mailbox_controller.h | 5 +++++
> 10 files changed, 5 insertions(+), 28 deletions(-)
> delete mode 100644 drivers/mailbox/mailbox.h
>
> diff --git a/drivers/mailbox/cix-mailbox.c b/drivers/mailbox/cix-mailbox.c
> index 443620e8ae37..864f98f21fc3 100644
> --- a/drivers/mailbox/cix-mailbox.c
> +++ b/drivers/mailbox/cix-mailbox.c
> @@ -12,8 +12,6 @@
> #include <linux/module.h>
> #include <linux/platform_device.h>
>
> -#include "mailbox.h"
> -
> /*
> * The maximum transmission size is 32 words or 128 bytes.
> */
> diff --git a/drivers/mailbox/hi3660-mailbox.c b/drivers/mailbox/hi3660-mailbox.c
> index 17c29e960fbf..9b727a2b54a5 100644
> --- a/drivers/mailbox/hi3660-mailbox.c
> +++ b/drivers/mailbox/hi3660-mailbox.c
> @@ -15,8 +15,6 @@
> #include <linux/platform_device.h>
> #include <linux/slab.h>
>
> -#include "mailbox.h"
> -
> #define MBOX_CHAN_MAX 32
>
> #define MBOX_RX 0x0
> diff --git a/drivers/mailbox/imx-mailbox.c b/drivers/mailbox/imx-mailbox.c
> index 003f9236c35e..22331b579489 100644
> --- a/drivers/mailbox/imx-mailbox.c
> +++ b/drivers/mailbox/imx-mailbox.c
> @@ -23,8 +23,6 @@
> #include <linux/slab.h>
> #include <linux/workqueue.h>
>
> -#include "mailbox.h"
> -
> #define IMX_MU_CHANS 24
> /* TX0/RX0/RXDB[0-3] */
> #define IMX_MU_SCU_CHANS 6
> diff --git a/drivers/mailbox/mailbox-sti.c b/drivers/mailbox/mailbox-sti.c
> index b4b5bdd503cf..b6c9ecbbc8ec 100644
> --- a/drivers/mailbox/mailbox-sti.c
> +++ b/drivers/mailbox/mailbox-sti.c
> @@ -21,8 +21,6 @@
> #include <linux/property.h>
> #include <linux/slab.h>
>
> -#include "mailbox.h"
> -
> #define STI_MBOX_INST_MAX 4 /* RAM saving: Max supported instances */
> #define STI_MBOX_CHAN_MAX 20 /* RAM saving: Max supported channels */
>
> diff --git a/drivers/mailbox/mailbox.c b/drivers/mailbox/mailbox.c
> index e63b2292ee7a..9d41a1ab9018 100644
> --- a/drivers/mailbox/mailbox.c
> +++ b/drivers/mailbox/mailbox.c
> @@ -18,8 +18,6 @@
> #include <linux/property.h>
> #include <linux/spinlock.h>
>
> -#include "mailbox.h"
> -
> static LIST_HEAD(mbox_cons);
> static DEFINE_MUTEX(con_mutex);
>
> diff --git a/drivers/mailbox/mailbox.h b/drivers/mailbox/mailbox.h
> deleted file mode 100644
> index e1ec4efab693..000000000000
> --- a/drivers/mailbox/mailbox.h
> +++ /dev/null
> @@ -1,12 +0,0 @@
> -/* SPDX-License-Identifier: GPL-2.0-only */
> -
> -#ifndef __MAILBOX_H
> -#define __MAILBOX_H
> -
> -#include <linux/bits.h>
> -
> -#define TXDONE_BY_IRQ BIT(0) /* controller has remote RTR irq */
> -#define TXDONE_BY_POLL BIT(1) /* controller can read status of last TX */
> -#define TXDONE_BY_ACK BIT(2) /* S/W ACK received by Client ticks the TX */
> -
> -#endif /* __MAILBOX_H */
> diff --git a/drivers/mailbox/omap-mailbox.c b/drivers/mailbox/omap-mailbox.c
> index d9f100c18895..5772c6b9886a 100644
> --- a/drivers/mailbox/omap-mailbox.c
> +++ b/drivers/mailbox/omap-mailbox.c
> @@ -22,8 +22,6 @@
> #include <linux/pm_runtime.h>
> #include <linux/mailbox_controller.h>
>
> -#include "mailbox.h"
> -
> #define MAILBOX_REVISION 0x000
> #define MAILBOX_MESSAGE(m) (0x040 + 4 * (m))
> #define MAILBOX_FIFOSTATUS(m) (0x080 + 4 * (m))
> diff --git a/drivers/mailbox/pcc.c b/drivers/mailbox/pcc.c
> index 22e70af1ae5d..636879ae1db7 100644
> --- a/drivers/mailbox/pcc.c
> +++ b/drivers/mailbox/pcc.c
> @@ -59,8 +59,6 @@
> #include <linux/io-64-nonatomic-lo-hi.h>
> #include <acpi/pcc.h>
>
> -#include "mailbox.h"
> -
> #define MBOX_IRQ_NAME "pcc-mbox"
>
> /**
> diff --git a/drivers/mailbox/tegra-hsp.c b/drivers/mailbox/tegra-hsp.c
> index ed9a0bb2bcd8..2231050bb5a9 100644
> --- a/drivers/mailbox/tegra-hsp.c
> +++ b/drivers/mailbox/tegra-hsp.c
> @@ -16,8 +16,6 @@
>
> #include <dt-bindings/mailbox/tegra186-hsp.h>
>
> -#include "mailbox.h"
> -
> #define HSP_INT_IE(x) (0x100 + ((x) * 4))
> #define HSP_INT_IV 0x300
> #define HSP_INT_IR 0x304
> diff --git a/include/linux/mailbox_controller.h b/include/linux/mailbox_controller.h
> index 80a427c7ca29..16fef421c30c 100644
> --- a/include/linux/mailbox_controller.h
> +++ b/include/linux/mailbox_controller.h
> @@ -3,6 +3,7 @@
> #ifndef __MAILBOX_CONTROLLER_H
> #define __MAILBOX_CONTROLLER_H
>
> +#include <linux/bits.h>
> #include <linux/completion.h>
> #include <linux/device.h>
> #include <linux/hrtimer.h>
> @@ -11,6 +12,10 @@
>
> struct mbox_chan;
>
> +#define TXDONE_BY_IRQ BIT(0) /* controller has remote RTR irq */
> +#define TXDONE_BY_POLL BIT(1) /* controller can read status of last TX */
> +#define TXDONE_BY_ACK BIT(2) /* S/W ACK received by Client ticks the TX */
> +
> /**
> * struct mbox_chan_ops - methods to control mailbox channels
> * @send_data: The API asks the MBOX controller driver, in atomic
> --
> 2.51.0
>
Applied to mailbox/for-next
Thanks
Jassi
^ permalink raw reply
* Re: [PATCH v2] mailbox: exynos: drop superfluous mbox setting per channel
From: Jassi Brar @ 2026-03-29 16:18 UTC (permalink / raw)
To: Wolfram Sang
Cc: linux-renesas-soc, Tudor Ambarus, Krzysztof Kozlowski,
Alim Akhtar, linux-kernel, linux-samsung-soc, linux-arm-kernel
In-Reply-To: <20260327151332.5425-2-wsa+renesas@sang-engineering.com>
On Fri, Mar 27, 2026 at 10:13 AM Wolfram Sang
<wsa+renesas@sang-engineering.com> wrote:
>
> The core initializes the 'mbox' field exactly like this, so don't
> duplicate it in the driver.
>
> Signed-off-by: Wolfram Sang <wsa+renesas@sang-engineering.com>
> Reviewed-by: Tudor Ambarus <tudor.ambarus@linaro.org>
> Tested-by: Tudor Ambarus <tudor.ambarus@linaro.org>
> ---
> Changes since v1:
> * rebased to 7.0-rc5
> * add tags (Thanks, Tudor!) and dropped RFT
>
> drivers/mailbox/exynos-mailbox.c | 4 ----
> 1 file changed, 4 deletions(-)
>
> diff --git a/drivers/mailbox/exynos-mailbox.c b/drivers/mailbox/exynos-mailbox.c
> index 5f2d3b81c1db..d2355b128ba4 100644
> --- a/drivers/mailbox/exynos-mailbox.c
> +++ b/drivers/mailbox/exynos-mailbox.c
> @@ -99,7 +99,6 @@ static int exynos_mbox_probe(struct platform_device *pdev)
> struct mbox_controller *mbox;
> struct mbox_chan *chans;
> struct clk *pclk;
> - int i;
>
> exynos_mbox = devm_kzalloc(dev, sizeof(*exynos_mbox), GFP_KERNEL);
> if (!exynos_mbox)
> @@ -129,9 +128,6 @@ static int exynos_mbox_probe(struct platform_device *pdev)
> mbox->ops = &exynos_mbox_chan_ops;
> mbox->of_xlate = exynos_mbox_of_xlate;
>
> - for (i = 0; i < EXYNOS_MBOX_CHAN_COUNT; i++)
> - chans[i].mbox = mbox;
> -
> exynos_mbox->mbox = mbox;
>
> platform_set_drvdata(pdev, exynos_mbox);
> --
> 2.51.0
>
Applied to mailbox/for-next
Thanks
Jassi
^ permalink raw reply
* Re: [PATCH v2 3/3] mailbox: mtk-cmdq: Remove unsued cmdq_get_shift_pa()
From: Jassi Brar @ 2026-03-29 16:03 UTC (permalink / raw)
To: Jason-JH Lin
Cc: Chun-Kuang Hu, AngeloGioacchino Del Regno, Nicolas Dufresne,
Mauro Carvalho Chehab, Matthias Brugger, Nancy Lin, Singo Chang,
Paul-PL Chen, Moudy Ho, Xiandong Wang, Sirius Wang, Fei Shao,
Chen-yu Tsai, Project_Global_Chrome_Upstream_Group, linux-kernel,
dri-devel, linux-mediatek, linux-arm-kernel, linux-media
In-Reply-To: <20260325040457.2113120-4-jason-jh.lin@mediatek.com>
On Tue, Mar 24, 2026 at 11:05 PM Jason-JH Lin <jason-jh.lin@mediatek.com> wrote:
>
> Since the mailbox driver data can be obtained using cmdq_get_mbox_priv()
> and all CMDQ users have transitioned to cmdq_get_mbox_priv(),
> cmdq_get_shift_pa() can be removed.
>
> Signed-off-by: Jason-JH Lin <jason-jh.lin@mediatek.com>
> Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
> ---
> drivers/mailbox/mtk-cmdq-mailbox.c | 8 --------
> include/linux/mailbox/mtk-cmdq-mailbox.h | 12 ------------
> 2 files changed, 20 deletions(-)
>
> diff --git a/drivers/mailbox/mtk-cmdq-mailbox.c b/drivers/mailbox/mtk-cmdq-mailbox.c
> index d7c6b38888a3..f463f443e834 100644
> --- a/drivers/mailbox/mtk-cmdq-mailbox.c
> +++ b/drivers/mailbox/mtk-cmdq-mailbox.c
> @@ -123,14 +123,6 @@ void cmdq_get_mbox_priv(struct mbox_chan *chan, struct cmdq_mbox_priv *priv)
> }
> EXPORT_SYMBOL(cmdq_get_mbox_priv);
>
> -u8 cmdq_get_shift_pa(struct mbox_chan *chan)
> -{
> - struct cmdq *cmdq = container_of(chan->mbox, struct cmdq, mbox);
> -
> - return cmdq->pdata->shift;
> -}
> -EXPORT_SYMBOL(cmdq_get_shift_pa);
> -
> static void cmdq_vm_init(struct cmdq *cmdq)
> {
> int i;
> diff --git a/include/linux/mailbox/mtk-cmdq-mailbox.h b/include/linux/mailbox/mtk-cmdq-mailbox.h
> index 07c1bfbdb8c4..a42b44d5fd49 100644
> --- a/include/linux/mailbox/mtk-cmdq-mailbox.h
> +++ b/include/linux/mailbox/mtk-cmdq-mailbox.h
> @@ -96,16 +96,4 @@ struct cmdq_pkt {
> */
> void cmdq_get_mbox_priv(struct mbox_chan *chan, struct cmdq_mbox_priv *priv);
>
> -/**
> - * cmdq_get_shift_pa() - get the shift bits of physical address
> - * @chan: mailbox channel
> - *
> - * GCE can only fetch the command buffer address from a 32-bit register.
> - * Some SOCs support more than 32-bit command buffer address for GCE, which
> - * requires some shift bits to make the address fit into the 32-bit register.
> - *
> - * Return: the shift bits of physical address
> - */
> -u8 cmdq_get_shift_pa(struct mbox_chan *chan);
> -
> #endif /* __MTK_CMDQ_MAILBOX_H__ */
I think the simplest would be to take this with the other two
predecessor patches.
Acked-by: Jassi Brar <jassisinghbrar@gmail.com>
^ permalink raw reply
* [PATCH v2 2/2] perf: marvell: Add CN20K DDR PMU support
From: Geetha sowjanya @ 2026-03-29 15:24 UTC (permalink / raw)
To: linux-perf-users, linux-kernel, linux-arm-kernel, devicetree
Cc: mark.rutland, will, krzk+dt
In-Reply-To: <20260329152439.10573-1-gakula@marvell.com>
The CN20K DRAM Subsystem exposes eight programmable
performance counters and two fixed counters for DDR
read and write traffic. Software selects events for
the programmable counters from traffic at the DDR PHY
interface, the CHI interconnect, or inside the DDR controller.
Add CN20K register offsets, event maps, and sysfs attributes;
match the device via OF (marvell,cn20k-ddr-pmu) and ACPI (MRVL000B).
Represent the SoC variant in platform data with bit flags so
CN20K can reuse the Odyssey PMU code path where appropriate.
Signed-off-by: Geetha sowjanya <gakula@marvell.com>
---
drivers/perf/marvell_cn10k_ddr_pmu.c | 187 ++++++++++++++++++++++++---
1 file changed, 171 insertions(+), 16 deletions(-)
diff --git a/drivers/perf/marvell_cn10k_ddr_pmu.c b/drivers/perf/marvell_cn10k_ddr_pmu.c
index 72ac17efd846..7e2e1823b009 100644
--- a/drivers/perf/marvell_cn10k_ddr_pmu.c
+++ b/drivers/perf/marvell_cn10k_ddr_pmu.c
@@ -13,31 +13,43 @@
#include <linux/hrtimer.h>
#include <linux/acpi.h>
#include <linux/platform_device.h>
+#include <linux/bits.h>
+
+/* SoC variant flags for struct ddr_pmu_platform_data (mutually exclusive in pdata) */
+#define IS_CN10K BIT(0)
+#define IS_ODY BIT(1)
+#define IS_CN20K BIT(2)
/* Performance Counters Operating Mode Control Registers */
#define CN10K_DDRC_PERF_CNT_OP_MODE_CTRL 0x8020
#define ODY_DDRC_PERF_CNT_OP_MODE_CTRL 0x20020
+#define CN20K_DDRC_PERF_CNT_OP_MODE_CTRL 0x20000
#define OP_MODE_CTRL_VAL_MANUAL 0x1
/* Performance Counters Start Operation Control Registers */
#define CN10K_DDRC_PERF_CNT_START_OP_CTRL 0x8028
#define ODY_DDRC_PERF_CNT_START_OP_CTRL 0x200A0
+#define CN20K_DDRC_PERF_CNT_START_OP_CTRL 0x20080
#define START_OP_CTRL_VAL_START 0x1ULL
#define START_OP_CTRL_VAL_ACTIVE 0x2
/* Performance Counters End Operation Control Registers */
#define CN10K_DDRC_PERF_CNT_END_OP_CTRL 0x8030
#define ODY_DDRC_PERF_CNT_END_OP_CTRL 0x200E0
+#define CN20K_DDRC_PERF_CNT_END_OP_CTRL 0x200C0
#define END_OP_CTRL_VAL_END 0x1ULL
/* Performance Counters End Status Registers */
#define CN10K_DDRC_PERF_CNT_END_STATUS 0x8038
#define ODY_DDRC_PERF_CNT_END_STATUS 0x20120
+#define CN20K_DDRC_PERF_CNT_END_STATUS 0x20100
#define END_STATUS_VAL_END_TIMER_MODE_END 0x1
/* Performance Counters Configuration Registers */
#define CN10K_DDRC_PERF_CFG_BASE 0x8040
#define ODY_DDRC_PERF_CFG_BASE 0x20160
+#define CN20K_DDRC_PERF_CFG_BASE 0x20140
+#define CN20K_DDRC_PERF_CFG1_BASE 0x20180
/* 8 Generic event counter + 2 fixed event counters */
#define DDRC_PERF_NUM_GEN_COUNTERS 8
@@ -61,6 +73,23 @@
* DO NOT change these event-id numbers, they are used to
* program event bitmap in h/w.
*/
+
+/* CN20K specific events */
+#define EVENT_PERF_OP_IS_RD16 61
+#define EVENT_PERF_OP_IS_RD32 60
+#define EVENT_PERF_OP_IS_WR16 59
+#define EVENT_PERF_OP_IS_WR32 58
+#define EVENT_OP_IS_ENTER_DSM 44
+#define EVENT_OP_IS_RFM 43
+
+#define EVENT_CN20K_OP_IS_TCR_MRR 50
+#define EVENT_CN20K_OP_IS_DQSOSC_MRR 49
+#define EVENT_CN20K_OP_IS_DQSOSC_MPC 48
+#define EVENT_CN20K_VISIBLE_WIN_LIMIT_REACHED_WR 47
+#define EVENT_CN20K_VISIBLE_WIN_LIMIT_REACHED_RD 46
+#define EVENT_CN20K_OP_IS_ZQLATCH 21
+#define EVENT_CN20K_OP_IS_ZQSTART 22
+
#define EVENT_DFI_CMD_IS_RETRY 61
#define EVENT_RD_UC_ECC_ERROR 60
#define EVENT_RD_CRC_ERROR 59
@@ -87,6 +116,9 @@
#define EVENT_OP_IS_SPEC_REF 41
#define EVENT_OP_IS_CRIT_REF 40
#define EVENT_OP_IS_REFRESH 39
+#define EVENT_OP_IS_CAS_WCK_SUS 38
+#define EVENT_OP_IS_CAS_WS_OFF 37
+#define EVENT_OP_IS_CAS_WS 36
#define EVENT_OP_IS_ENTER_MPSM 35
#define EVENT_OP_IS_ENTER_POWERDOWN 31
#define EVENT_OP_IS_ENTER_SELFREF 27
@@ -183,8 +215,8 @@ struct ddr_pmu_platform_data {
u64 cnt_freerun_clr;
u64 cnt_value_wr_op;
u64 cnt_value_rd_op;
- bool is_cn10k;
- bool is_ody;
+ u64 cfg1_base;
+ unsigned int silicon_flags; /* IS_CN10K, IS_ODY, or IS_CN20K */
};
static ssize_t cn10k_ddr_pmu_event_show(struct device *dev,
@@ -336,6 +368,80 @@ static struct attribute *odyssey_ddr_perf_events_attrs[] = {
NULL
};
+static struct attribute *cn20k_ddr_perf_events_attrs[] = {
+ /* Programmable */
+ CN10K_DDR_PMU_EVENT_ATTR(ddr_hif_rd_or_wr_access, EVENT_HIF_RD_OR_WR),
+ CN10K_DDR_PMU_EVENT_ATTR(ddr_hif_wr_access, EVENT_HIF_WR),
+ CN10K_DDR_PMU_EVENT_ATTR(ddr_hif_rd_access, EVENT_HIF_RD),
+ CN10K_DDR_PMU_EVENT_ATTR(ddr_hif_rmw_access, EVENT_HIF_RMW),
+ CN10K_DDR_PMU_EVENT_ATTR(ddr_hif_pri_rdaccess, EVENT_HIF_HI_PRI_RD),
+ CN10K_DDR_PMU_EVENT_ATTR(ddr_rd_bypass_access, EVENT_READ_BYPASS),
+ CN10K_DDR_PMU_EVENT_ATTR(ddr_act_bypass_access, EVENT_ACT_BYPASS),
+ CN10K_DDR_PMU_EVENT_ATTR(ddr_dfi_wr_data_access,
+ EVENT_DFI_WR_DATA_CYCLES),
+ CN10K_DDR_PMU_EVENT_ATTR(ddr_dfi_rd_data_access,
+ EVENT_DFI_RD_DATA_CYCLES),
+ CN10K_DDR_PMU_EVENT_ATTR(ddr_hpri_sched_rd_crit_access,
+ EVENT_HPR_XACT_WHEN_CRITICAL),
+ CN10K_DDR_PMU_EVENT_ATTR(ddr_lpri_sched_rd_crit_access,
+ EVENT_LPR_XACT_WHEN_CRITICAL),
+ CN10K_DDR_PMU_EVENT_ATTR(ddr_wr_trxn_crit_access,
+ EVENT_WR_XACT_WHEN_CRITICAL),
+ CN10K_DDR_PMU_EVENT_ATTR(ddr_cam_active_access, EVENT_OP_IS_ACTIVATE),
+ CN10K_DDR_PMU_EVENT_ATTR(ddr_cam_rd_or_wr_access,
+ EVENT_OP_IS_RD_OR_WR),
+ CN10K_DDR_PMU_EVENT_ATTR(ddr_cam_rd_active_access,
+ EVENT_OP_IS_RD_ACTIVATE),
+ CN10K_DDR_PMU_EVENT_ATTR(ddr_cam_read, EVENT_OP_IS_RD),
+ CN10K_DDR_PMU_EVENT_ATTR(ddr_cam_write, EVENT_OP_IS_WR),
+ CN10K_DDR_PMU_EVENT_ATTR(ddr_cam_mwr, EVENT_OP_IS_MWR),
+ CN10K_DDR_PMU_EVENT_ATTR(ddr_precharge, EVENT_OP_IS_PRECHARGE),
+ CN10K_DDR_PMU_EVENT_ATTR(ddr_precharge_for_rdwr,
+ EVENT_PRECHARGE_FOR_RDWR),
+ CN10K_DDR_PMU_EVENT_ATTR(ddr_precharge_for_other,
+ EVENT_PRECHARGE_FOR_OTHER),
+ CN10K_DDR_PMU_EVENT_ATTR(ddr_rdwr_transitions, EVENT_RDWR_TRANSITIONS),
+ CN10K_DDR_PMU_EVENT_ATTR(ddr_write_combine, EVENT_WRITE_COMBINE),
+ CN10K_DDR_PMU_EVENT_ATTR(ddr_war_hazard, EVENT_WAR_HAZARD),
+ CN10K_DDR_PMU_EVENT_ATTR(ddr_raw_hazard, EVENT_RAW_HAZARD),
+ CN10K_DDR_PMU_EVENT_ATTR(ddr_waw_hazard, EVENT_WAW_HAZARD),
+ CN10K_DDR_PMU_EVENT_ATTR(ddr_enter_selfref, EVENT_OP_IS_ENTER_SELFREF),
+ CN10K_DDR_PMU_EVENT_ATTR(ddr_enter_powerdown,
+ EVENT_OP_IS_ENTER_POWERDOWN),
+ CN10K_DDR_PMU_EVENT_ATTR(ddr_cas_ws, EVENT_OP_IS_CAS_WS),
+ CN10K_DDR_PMU_EVENT_ATTR(ddr_cas_ws_off, EVENT_OP_IS_CAS_WS_OFF),
+ CN10K_DDR_PMU_EVENT_ATTR(ddr_cas_wck_sus, EVENT_OP_IS_CAS_WCK_SUS),
+ CN10K_DDR_PMU_EVENT_ATTR(ddr_refresh, EVENT_OP_IS_REFRESH),
+ CN10K_DDR_PMU_EVENT_ATTR(ddr_crit_ref, EVENT_OP_IS_CRIT_REF),
+ CN10K_DDR_PMU_EVENT_ATTR(ddr_spec_ref, EVENT_OP_IS_SPEC_REF),
+ CN10K_DDR_PMU_EVENT_ATTR(ddr_load_mode, EVENT_OP_IS_LOAD_MODE),
+ CN10K_DDR_PMU_EVENT_ATTR(ddr_rfm, EVENT_OP_IS_RFM),
+ CN10K_DDR_PMU_EVENT_ATTR(ddr_enter_dsm, EVENT_OP_IS_ENTER_DSM),
+ CN10K_DDR_PMU_EVENT_ATTR(ddr_dfi_cycles, EVENT_DFI_CYCLES),
+ CN10K_DDR_PMU_EVENT_ATTR(ddr_win_limit_reached_rd,
+ EVENT_CN20K_VISIBLE_WIN_LIMIT_REACHED_RD),
+ CN10K_DDR_PMU_EVENT_ATTR(ddr_win_limit_reached_wr,
+ EVENT_CN20K_VISIBLE_WIN_LIMIT_REACHED_WR),
+ CN10K_DDR_PMU_EVENT_ATTR(ddr_dqsosc_mpc, EVENT_CN20K_OP_IS_DQSOSC_MPC),
+ CN10K_DDR_PMU_EVENT_ATTR(ddr_dqsosc_mrr, EVENT_CN20K_OP_IS_DQSOSC_MRR),
+ CN10K_DDR_PMU_EVENT_ATTR(ddr_tcr_mrr, EVENT_CN20K_OP_IS_TCR_MRR),
+ CN10K_DDR_PMU_EVENT_ATTR(ddr_zqstart, EVENT_CN20K_OP_IS_ZQSTART),
+ CN10K_DDR_PMU_EVENT_ATTR(ddr_zqlatch, EVENT_CN20K_OP_IS_ZQLATCH),
+ CN10K_DDR_PMU_EVENT_ATTR(ddr_read16, EVENT_PERF_OP_IS_RD16),
+ CN10K_DDR_PMU_EVENT_ATTR(ddr_read32, EVENT_PERF_OP_IS_RD32),
+ CN10K_DDR_PMU_EVENT_ATTR(ddr_write16, EVENT_PERF_OP_IS_WR16),
+ CN10K_DDR_PMU_EVENT_ATTR(ddr_write32, EVENT_PERF_OP_IS_WR32),
+ /* Free run event counters */
+ CN10K_DDR_PMU_EVENT_ATTR(ddr_ddr_reads, EVENT_DDR_READS),
+ CN10K_DDR_PMU_EVENT_ATTR(ddr_ddr_writes, EVENT_DDR_WRITES),
+ NULL
+};
+
+static struct attribute_group cn20k_ddr_perf_events_attr_group = {
+ .name = "events",
+ .attrs = cn20k_ddr_perf_events_attrs,
+};
+
static struct attribute_group odyssey_ddr_perf_events_attr_group = {
.name = "events",
.attrs = odyssey_ddr_perf_events_attrs,
@@ -393,6 +499,13 @@ static const struct attribute_group *odyssey_attr_groups[] = {
NULL
};
+static const struct attribute_group *cn20k_attr_groups[] = {
+ &cn20k_ddr_perf_events_attr_group,
+ &cn10k_ddr_perf_format_attr_group,
+ &cn10k_ddr_perf_cpumask_attr_group,
+ NULL
+};
+
/* Default poll timeout is 100 sec, which is very sufficient for
* 48 bit counter incremented max at 5.6 GT/s, which may take many
* hours to overflow.
@@ -412,7 +525,7 @@ static int ddr_perf_get_event_bitmap(int eventid, u64 *event_bitmap,
switch (eventid) {
case EVENT_DFI_PARITY_POISON ...EVENT_DFI_CMD_IS_RETRY:
- if (!ddr_pmu->p_data->is_ody) {
+ if (!(ddr_pmu->p_data->silicon_flags & IS_ODY)) {
err = -EINVAL;
break;
}
@@ -524,9 +637,9 @@ static void cn10k_ddr_perf_counter_enable(struct cn10k_ddr_pmu *pmu,
int counter, bool enable)
{
const struct ddr_pmu_platform_data *p_data = pmu->p_data;
+ unsigned int silicon_flags = pmu->p_data->silicon_flags;
u64 ctrl_reg = pmu->p_data->cnt_op_mode_ctrl;
const struct ddr_pmu_ops *ops = pmu->ops;
- bool is_ody = pmu->p_data->is_ody;
u32 reg;
u64 val;
@@ -546,7 +659,7 @@ static void cn10k_ddr_perf_counter_enable(struct cn10k_ddr_pmu *pmu,
writeq_relaxed(val, pmu->base + reg);
- if (is_ody) {
+ if (silicon_flags & IS_ODY) {
if (enable) {
/*
* Setup the PMU counter to work in
@@ -621,6 +734,7 @@ static int cn10k_ddr_perf_event_add(struct perf_event *event, int flags)
{
struct cn10k_ddr_pmu *pmu = to_cn10k_ddr_pmu(event->pmu);
const struct ddr_pmu_platform_data *p_data = pmu->p_data;
+ unsigned int silicon_flags = pmu->p_data->silicon_flags;
const struct ddr_pmu_ops *ops = pmu->ops;
struct hw_perf_event *hwc = &event->hw;
u8 config = event->attr.config;
@@ -642,10 +756,17 @@ static int cn10k_ddr_perf_event_add(struct perf_event *event, int flags)
if (counter < DDRC_PERF_NUM_GEN_COUNTERS) {
/* Generic counters, configure event id */
reg_offset = DDRC_PERF_CFG(p_data->cfg_base, counter);
- ret = ddr_perf_get_event_bitmap(config, &val, pmu);
- if (ret)
- return ret;
+ if (silicon_flags & IS_CN20K) {
+ val = (1ULL << (config - 1));
+ if (config == EVENT_CN20K_OP_IS_ZQSTART ||
+ config == EVENT_CN20K_OP_IS_ZQLATCH)
+ reg_offset = DDRC_PERF_CFG(p_data->cfg1_base, counter);
+ } else {
+ ret = ddr_perf_get_event_bitmap(config, &val, pmu);
+ if (ret)
+ return ret;
+ }
writeq_relaxed(val, pmu->base + reg_offset);
} else {
/* fixed event counter, clear counter value */
@@ -952,7 +1073,25 @@ static const struct ddr_pmu_platform_data cn10k_ddr_pmu_pdata = {
.cnt_freerun_clr = 0,
.cnt_value_wr_op = CN10K_DDRC_PERF_CNT_VALUE_WR_OP,
.cnt_value_rd_op = CN10K_DDRC_PERF_CNT_VALUE_RD_OP,
- .is_cn10k = TRUE,
+ .silicon_flags = IS_CN10K,
+};
+
+static const struct ddr_pmu_platform_data cn20k_ddr_pmu_pdata = {
+ .counter_overflow_val = 0,
+ .counter_max_val = GENMASK_ULL(63, 0),
+ .cnt_base = ODY_DDRC_PERF_CNT_VALUE_BASE,
+ .cfg_base = CN20K_DDRC_PERF_CFG_BASE,
+ .cfg1_base = CN20K_DDRC_PERF_CFG1_BASE,
+ .cnt_op_mode_ctrl = CN20K_DDRC_PERF_CNT_OP_MODE_CTRL,
+ .cnt_start_op_ctrl = CN20K_DDRC_PERF_CNT_START_OP_CTRL,
+ .cnt_end_op_ctrl = CN20K_DDRC_PERF_CNT_END_OP_CTRL,
+ .cnt_end_status = CN20K_DDRC_PERF_CNT_END_STATUS,
+ .cnt_freerun_en = 0,
+ .cnt_freerun_ctrl = ODY_DDRC_PERF_CNT_FREERUN_CTRL,
+ .cnt_freerun_clr = ODY_DDRC_PERF_CNT_FREERUN_CLR,
+ .cnt_value_wr_op = ODY_DDRC_PERF_CNT_VALUE_WR_OP,
+ .cnt_value_rd_op = ODY_DDRC_PERF_CNT_VALUE_RD_OP,
+ .silicon_flags = IS_CN20K,
};
#endif
@@ -979,7 +1118,7 @@ static const struct ddr_pmu_platform_data odyssey_ddr_pmu_pdata = {
.cnt_freerun_clr = ODY_DDRC_PERF_CNT_FREERUN_CLR,
.cnt_value_wr_op = ODY_DDRC_PERF_CNT_VALUE_WR_OP,
.cnt_value_rd_op = ODY_DDRC_PERF_CNT_VALUE_RD_OP,
- .is_ody = TRUE,
+ .silicon_flags = IS_ODY,
};
#endif
@@ -989,8 +1128,7 @@ static int cn10k_ddr_perf_probe(struct platform_device *pdev)
struct cn10k_ddr_pmu *ddr_pmu;
struct resource *res;
void __iomem *base;
- bool is_cn10k;
- bool is_ody;
+ unsigned int silicon_flags;
char *name;
int ret;
@@ -1014,10 +1152,9 @@ static int cn10k_ddr_perf_probe(struct platform_device *pdev)
ddr_pmu->base = base;
ddr_pmu->p_data = dev_data;
- is_cn10k = ddr_pmu->p_data->is_cn10k;
- is_ody = ddr_pmu->p_data->is_ody;
+ silicon_flags = ddr_pmu->p_data->silicon_flags;
- if (is_cn10k) {
+ if (silicon_flags & IS_CN10K) {
ddr_pmu->ops = &ddr_pmu_ops;
/* Setup the PMU counter to work in manual mode */
writeq_relaxed(OP_MODE_CTRL_VAL_MANUAL, ddr_pmu->base +
@@ -1039,7 +1176,7 @@ static int cn10k_ddr_perf_probe(struct platform_device *pdev)
};
}
- if (is_ody) {
+ if (silicon_flags & IS_ODY) {
ddr_pmu->ops = &ddr_pmu_ody_ops;
ddr_pmu->pmu = (struct pmu) {
@@ -1056,6 +1193,22 @@ static int cn10k_ddr_perf_probe(struct platform_device *pdev)
};
}
+ if (silicon_flags & IS_CN20K) {
+ ddr_pmu->ops = &ddr_pmu_ody_ops;
+
+ ddr_pmu->pmu = (struct pmu) {
+ .module = THIS_MODULE,
+ .capabilities = PERF_PMU_CAP_NO_EXCLUDE,
+ .task_ctx_nr = perf_invalid_context,
+ .attr_groups = cn20k_attr_groups,
+ .event_init = cn10k_ddr_perf_event_init,
+ .add = cn10k_ddr_perf_event_add,
+ .del = cn10k_ddr_perf_event_del,
+ .start = cn10k_ddr_perf_event_start,
+ .stop = cn10k_ddr_perf_event_stop,
+ .read = cn10k_ddr_perf_event_update,
+ };
+ }
/* Choose this cpu to collect perf data */
ddr_pmu->cpu = raw_smp_processor_id();
@@ -1098,6 +1251,7 @@ static void cn10k_ddr_perf_remove(struct platform_device *pdev)
#ifdef CONFIG_OF
static const struct of_device_id cn10k_ddr_pmu_of_match[] = {
{ .compatible = "marvell,cn10k-ddr-pmu", .data = &cn10k_ddr_pmu_pdata },
+ { .compatible = "marvell,cn20k-ddr-pmu", .data = &cn20k_ddr_pmu_pdata },
{ },
};
MODULE_DEVICE_TABLE(of, cn10k_ddr_pmu_of_match);
@@ -1107,6 +1261,7 @@ MODULE_DEVICE_TABLE(of, cn10k_ddr_pmu_of_match);
static const struct acpi_device_id cn10k_ddr_pmu_acpi_match[] = {
{"MRVL000A", (kernel_ulong_t)&cn10k_ddr_pmu_pdata },
{"MRVL000C", (kernel_ulong_t)&odyssey_ddr_pmu_pdata},
+ {"MRVL000B", (kernel_ulong_t)&cn20k_ddr_pmu_pdata},
{},
};
MODULE_DEVICE_TABLE(acpi, cn10k_ddr_pmu_acpi_match);
--
2.25.1
^ permalink raw reply related
* [PATCH v2 1/2] dt-bindings: perf: marvell: Document CN20K DDR PMU
From: Geetha sowjanya @ 2026-03-29 15:24 UTC (permalink / raw)
To: linux-perf-users, linux-kernel, linux-arm-kernel, devicetree
Cc: mark.rutland, will, krzk+dt
In-Reply-To: <20260329152439.10573-1-gakula@marvell.com>
Add a devicetree binding for the Marvell CN20K DDR performance
monitor block, including the marvell,cn20k-ddr-pmu compatible
string and the required MMIO reg region.
Signed-off-by: Geetha sowjanya <gakula@marvell.com>
---
Changes in v1:
- Added a description field to the binding.
- Simplified the compatible property using 'const' instead of 'items/enum'.
- Updated the example node name to include a unit-address matching the reg base.
.../bindings/perf/marvell-cn20k-ddr.yaml | 39 +++++++++++++++++++
1 file changed, 39 insertions(+)
create mode 100644 Documentation/devicetree/bindings/perf/marvell-cn20k-ddr.yaml
diff --git a/Documentation/devicetree/bindings/perf/marvell-cn20k-ddr.yaml b/Documentation/devicetree/bindings/perf/marvell-cn20k-ddr.yaml
new file mode 100644
index 000000000000..470eac0a53c4
--- /dev/null
+++ b/Documentation/devicetree/bindings/perf/marvell-cn20k-ddr.yaml
@@ -0,0 +1,39 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/perf/marvell-cn20k-ddr.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Marvell CN20K DDR performance monitor
+
+description:
+ Performance Monitoring Unit (PMU) for the DDR controller
+ in Marvell CN20K SoCs.
+
+maintainers:
+ - Geetha sowjanya <gakula@marvell.com>
+
+properties:
+ compatible:
+ const: marvell,cn20k-ddr-pmu
+
+ reg:
+ maxItems: 1
+
+required:
+ - compatible
+ - reg
+
+additionalProperties: false
+
+examples:
+ - |
+ bus {
+ #address-cells = <2>;
+ #size-cells = <2>;
+
+ ddr-pmu@c200000000 {
+ compatible = "marvell,cn20k-ddr-pmu";
+ reg = <0xc200 0x00000000 0x0 0x100000>;
+ };
+ };
--
2.25.1
^ permalink raw reply related
* [PATCH v2 0/2] perf: marvell: Add CN20K DDR PMU support
From: Geetha sowjanya @ 2026-03-29 15:24 UTC (permalink / raw)
To: linux-perf-users, linux-kernel, linux-arm-kernel, devicetree
Cc: mark.rutland, will, krzk+dt
This series adds support for the Marvell CN20K DRAM Subsystem (DSS)
performance monitor in the existing marvell_cn10k_ddr_pmu driver, and
documents the device tree binding for the new compatible string.
The CN20K PMU provides eight programmable counters and two fixed
counters (DDR reads and writes). Patch 1 adds the devicetree schema for
"marvell,cn20k-ddr-pmu". Patch 2 wires OF and ACPI (MRVL000B) match
entries, adds CN20K register offsets and event maps, and refactors
platform data to use silicon variant flags.
Signed-off-by: Geetha sowjanya <gakula@marvell.com>
Changes in v1:
- Added a description field to the binding.
- Simplified the compatible property using 'const' instead of 'items/enum'.
- Updated the example node name to include a unit-address matching the reg base.
Geetha sowjanya (2):
dt-bindings: perf: marvell: Document CN20K DDR PMU
perf: marvell: Add CN20K DDR PMU support
.../bindings/perf/marvell-cn20k-ddr.yaml | 37 ++++
drivers/perf/marvell_cn10k_ddr_pmu.c | 186 ++++++++++++++++--
2 files changed, 207 insertions(+), 16 deletions(-)
create mode 100644 Documentation/devicetree/bindings/perf/marvell-cn20k-ddr.yaml
--
2.25.1
^ permalink raw reply
* [GIT PULL 7/7] arm64: tegra: Default configuration changes for v7.1-rc1
From: Thierry Reding @ 2026-03-29 15:10 UTC (permalink / raw)
To: arm, soc; +Cc: Thierry Reding, Jon Hunter, linux-tegra, linux-arm-kernel
In-Reply-To: <20260329151045.1443133-1-thierry.reding@kernel.org>
From: Thierry Reding <thierry.reding@gmail.com>
Hi ARM SoC maintainers,
The following changes since commit 6de23f81a5e08be8fbf5e8d7e9febc72a5b5f27f:
Linux 7.0-rc1 (2026-02-22 13:18:59 -0800)
are available in the Git repository at:
git://git.kernel.org/pub/scm/linux/kernel/git/tegra/linux.git tags/tegra-for-7.1-arm64-defconfig
for you to fetch changes up to c655a14958363aea8a1d0bbf3358fcee7f89a210:
arm64: tegra: defconfig: Drop redundant ARCH_TEGRA_foo_SOC (2026-03-25 10:49:46 +0100)
Thanks,
Thierry
----------------------------------------------------------------
arm64: tegra: Default configuration changes for v7.1-rc1
Drop the various ARCH_TEGRA_*_SOC options from the default configurations
since they are now enabled by default for ARCH_TEGRA.
----------------------------------------------------------------
Krzysztof Kozlowski (2):
soc/tegra: Make ARCH_TEGRA_SOC_FOO defaults for NVIDIA Tegra
arm64: tegra: defconfig: Drop redundant ARCH_TEGRA_foo_SOC
Thierry Reding (1):
Merge branch 'for-7.1/soc' into for-7.1/arm64/defconfig
arch/arm64/configs/defconfig | 7 -------
drivers/soc/tegra/Kconfig | 11 +++++++++++
2 files changed, 11 insertions(+), 7 deletions(-)
^ permalink raw reply
* [GIT PULL 5/7] ARM: tegra: Default configuration changes for v7.1-rc1
From: Thierry Reding @ 2026-03-29 15:10 UTC (permalink / raw)
To: arm, soc; +Cc: Thierry Reding, Jon Hunter, linux-tegra, linux-arm-kernel
In-Reply-To: <20260329151045.1443133-1-thierry.reding@kernel.org>
From: Thierry Reding <thierry.reding@gmail.com>
Hi ARM SoC maintainers,
The following changes since commit 6de23f81a5e08be8fbf5e8d7e9febc72a5b5f27f:
Linux 7.0-rc1 (2026-02-22 13:18:59 -0800)
are available in the Git repository at:
git://git.kernel.org/pub/scm/linux/kernel/git/tegra/linux.git tags/tegra-for-7.1-arm-defconfig
for you to fetch changes up to 21e380f272415387454d81788f2d62642e1fe93a:
ARM: tegra: defconfig: Drop redundant ARCH_TEGRA_foo_SOC (2026-03-25 10:49:00 +0100)
Thanks,
Thierry
----------------------------------------------------------------
ARM: tegra: Default configuration changes for v7.1-rc1
Drop the various ARCH_TEGRA_*_SOC options from the default configurations
since they are now enabled by default for ARCH_TEGRA.
----------------------------------------------------------------
Krzysztof Kozlowski (2):
soc/tegra: Make ARCH_TEGRA_SOC_FOO defaults for NVIDIA Tegra
ARM: tegra: defconfig: Drop redundant ARCH_TEGRA_foo_SOC
Thierry Reding (1):
Merge branch 'for-7.1/soc' into for-7.1/arm/defconfig
arch/arm/configs/multi_v7_defconfig | 4 ----
arch/arm/configs/tegra_defconfig | 4 ----
drivers/soc/tegra/Kconfig | 11 +++++++++++
3 files changed, 11 insertions(+), 8 deletions(-)
^ permalink raw reply
* [GIT PULL 2/7] soc/tegra: Changes for v7.1-rc1
From: Thierry Reding @ 2026-03-29 15:10 UTC (permalink / raw)
To: arm, soc; +Cc: Thierry Reding, Jon Hunter, linux-tegra, linux-arm-kernel
In-Reply-To: <20260329151045.1443133-1-thierry.reding@kernel.org>
From: Thierry Reding <thierry.reding@gmail.com>
Hi ARM SoC maintainers,
The following changes since commit 6de23f81a5e08be8fbf5e8d7e9febc72a5b5f27f:
Linux 7.0-rc1 (2026-02-22 13:18:59 -0800)
are available in the Git repository at:
git://git.kernel.org/pub/scm/linux/kernel/git/tegra/linux.git tags/tegra-for-7.1-soc
for you to fetch changes up to 4b23febb6b11cd06183bed3d21b87ba7d6a8a1e0:
MAINTAINERS: Change email address for Thierry Reding (2026-03-28 01:41:07 +0100)
Thanks,
Thierry
----------------------------------------------------------------
soc/tegra: Changes for v7.1-rc1
A number of fixes went into this for the PMC and CBB drivers. The PMC
driver also gains support for Tegra264 and a Kconfig symbol for the
upcoming Tegra238 is added. The various per-generation Kconfig symbols
are now also enabled by default for ARCH_TEGRA in order to reduce the
number of configuration options that need to be explicitly enabled.
----------------------------------------------------------------
Jon Hunter (10):
soc/tegra: pmc: Add kerneldoc for reboot notifier
soc/tegra: pmc: Correct function names in kerneldoc
soc/tegra: pmc: Add kerneldoc for wake-up variables
soc/tegra: pmc: Remove unused AOWAKE definitions
soc/tegra: pmc: Add support for SoC specific AOWAKE offsets
soc/tegra: pmc: Add AOWAKE regs for Tegra264
soc/tegra: pmc: Add Tegra264 wake events
soc/tegra: pmc: Refactor IO pad voltage control
soc/tegra: pmc: Rename has_impl_33v_pwr flag
soc/tegra: pmc: Add IO pads for Tegra264
Krzysztof Kozlowski (1):
soc/tegra: Make ARCH_TEGRA_SOC_FOO defaults for NVIDIA Tegra
Sumit Gupta (4):
soc/tegra: cbb: Add support for CBB fabrics in Tegra238
soc/tegra: cbb: Set ERD on resume for err interrupt
soc/tegra: cbb: Fix incorrect ARRAY_SIZE in fabric lookup tables
soc/tegra: cbb: Fix cross-fabric target timeout lookup
Svyatoslav Ryhel (2):
soc/tegra: pmc: Enable core domain support for Tegra114
soc/tegra: common: Add Tegra114 support to devm_tegra_core_dev_init_opp_table
Thierry Reding (2):
soc/tegra: Add Tegra238 Kconfig symbol
MAINTAINERS: Change email address for Thierry Reding
MAINTAINERS | 14 +-
drivers/soc/tegra/Kconfig | 20 ++
drivers/soc/tegra/cbb/tegra234-cbb.c | 169 ++++++++-
drivers/soc/tegra/common.c | 5 +-
drivers/soc/tegra/pmc.c | 662 ++++++++++++++++++++++-------------
5 files changed, 611 insertions(+), 259 deletions(-)
^ permalink raw reply
* [GIT PULL 6/7] arm64: tegra: Device tree changes for v7.1-rc1
From: Thierry Reding @ 2026-03-29 15:10 UTC (permalink / raw)
To: arm, soc; +Cc: Thierry Reding, Jon Hunter, linux-tegra, linux-arm-kernel
In-Reply-To: <20260329151045.1443133-1-thierry.reding@kernel.org>
From: Thierry Reding <thierry.reding@gmail.com>
Hi ARM SoC maintainers,
The following changes since commit 6de23f81a5e08be8fbf5e8d7e9febc72a5b5f27f:
Linux 7.0-rc1 (2026-02-22 13:18:59 -0800)
are available in the Git repository at:
git://git.kernel.org/pub/scm/linux/kernel/git/tegra/linux.git tags/tegra-for-7.1-arm64-dt
for you to fetch changes up to c70e6bc11d2008fbb19695394b69fd941ab39030:
arm64: tegra: Add Tegra264 GPIO controllers (2026-03-28 01:36:46 +0100)
Thanks,
Thierry
----------------------------------------------------------------
arm64: tegra: Device tree changes for v7.1-rc1
Various fixes and new additions across a number of devices. GPIO and PCI
are enabled on Tegra264 and the Jetson AGX Thor Developer Kit, allowing
it to boot via network and mass storage.
----------------------------------------------------------------
Diogo Ivo (1):
arm64: tegra: smaug: Enable SPI-NOR flash
Jon Hunter (1):
arm64: tegra: Fix RTC aliases
Prathamesh Shete (1):
arm64: tegra: Add Tegra264 GPIO controllers
Thierry Reding (6):
dt-bindings: pci: Document the NVIDIA Tegra264 PCIe controller
Merge branch for-7.1/dt-bindings into for-7.1/pci
arm64: tegra: Fix snps,blen properties
arm64: tegra: Drop redundant clock and reset names for TSEC
arm64: tegra: Add PCI controllers on Tegra264
arm64: tegra: Add Jetson AGX Thor Developer Kit support
.../bindings/pci/nvidia,tegra264-pcie.yaml | 149 +++++++++
arch/arm64/boot/dts/nvidia/Makefile | 2 +
arch/arm64/boot/dts/nvidia/tegra210-smaug.dts | 12 +
arch/arm64/boot/dts/nvidia/tegra210.dtsi | 2 -
arch/arm64/boot/dts/nvidia/tegra234-p3701.dtsi | 1 +
arch/arm64/boot/dts/nvidia/tegra234-p3767.dtsi | 1 +
arch/arm64/boot/dts/nvidia/tegra234.dtsi | 6 +-
.../dts/nvidia/tegra264-p4071-0000+p3834-0008.dts | 11 +
.../boot/dts/nvidia/tegra264-p4071-0000+p3834.dtsi | 12 +
arch/arm64/boot/dts/nvidia/tegra264.dtsi | 336 +++++++++++++++++++--
10 files changed, 500 insertions(+), 32 deletions(-)
create mode 100644 Documentation/devicetree/bindings/pci/nvidia,tegra264-pcie.yaml
create mode 100644 arch/arm64/boot/dts/nvidia/tegra264-p4071-0000+p3834-0008.dts
create mode 100644 arch/arm64/boot/dts/nvidia/tegra264-p4071-0000+p3834.dtsi
^ permalink raw reply
* [GIT PULL 4/7] ARM: tegra: Device tree changes for v7.1-rc1
From: Thierry Reding @ 2026-03-29 15:10 UTC (permalink / raw)
To: arm, soc; +Cc: Thierry Reding, Jon Hunter, linux-tegra, linux-arm-kernel
In-Reply-To: <20260329151045.1443133-1-thierry.reding@kernel.org>
From: Thierry Reding <thierry.reding@gmail.com>
Hi ARM SoC maintainers,
The following changes since commit 6de23f81a5e08be8fbf5e8d7e9febc72a5b5f27f:
Linux 7.0-rc1 (2026-02-22 13:18:59 -0800)
are available in the Git repository at:
git://git.kernel.org/pub/scm/linux/kernel/git/tegra/linux.git tags/tegra-for-7.1-arm-dt
for you to fetch changes up to ce74a6c6d88ba9ee29a6b99ac97ffcded577c85d:
ARM: tegra: paz00: Configure WiFi rfkill switch through device tree (2026-03-28 00:56:36 +0100)
Thanks,
Thierry
----------------------------------------------------------------
ARM: tegra: Device tree changes for v7.1-rc1
Various improvements for Tegra114 boards, as well as some legacy cleanup
for PAZ00 and Transformers devices.
----------------------------------------------------------------
Dmitry Torokhov (1):
ARM: tegra: paz00: Configure WiFi rfkill switch through device tree
Svyatoslav Ryhel (8):
ARM: tegra: Add SOCTHERM support on Tegra114
ARM: tn7: Adjust panel node
ARM: tegra: lg-x3: Add panel and bridge nodes
ARM: tegra: lg-x3: Add USB and power related nodes
ARM: tegra: lg-x3: Add node for capacitive buttons
ARM: tegra: Add ACTMON node to Tegra114 device tree
ARM: tegra: Add External Memory Controller node on Tegra114
ARM: tegra: transformers: Add connector node
arch/arm/boot/dts/nvidia/tegra114-tn7.dts | 13 +-
arch/arm/boot/dts/nvidia/tegra114.dtsi | 221 +++++++++++++++++++++++
arch/arm/boot/dts/nvidia/tegra20-paz00.dts | 8 +
arch/arm/boot/dts/nvidia/tegra30-asus-tf600t.dts | 21 ++-
arch/arm/boot/dts/nvidia/tegra30-lg-p880.dts | 23 +++
arch/arm/boot/dts/nvidia/tegra30-lg-p895.dts | 33 ++++
arch/arm/boot/dts/nvidia/tegra30-lg-x3.dtsi | 174 +++++++++++++++++-
arch/arm/mach-tegra/Makefile | 2 -
arch/arm/mach-tegra/board-paz00.c | 56 ------
arch/arm/mach-tegra/board.h | 2 -
arch/arm/mach-tegra/tegra.c | 4 -
11 files changed, 482 insertions(+), 75 deletions(-)
delete mode 100644 arch/arm/mach-tegra/board-paz00.c
^ permalink raw reply
* [GIT PULL 1/7] dt-bindings: Changes for v7.1-rc1
From: Thierry Reding @ 2026-03-29 15:10 UTC (permalink / raw)
To: arm, soc; +Cc: Thierry Reding, Jon Hunter, linux-tegra, linux-arm-kernel
From: Thierry Reding <thierry.reding@gmail.com>
Hi ARM SoC maintainers,
The following changes since commit 6de23f81a5e08be8fbf5e8d7e9febc72a5b5f27f:
Linux 7.0-rc1 (2026-02-22 13:18:59 -0800)
are available in the Git repository at:
git://git.kernel.org/pub/scm/linux/kernel/git/tegra/linux.git tags/tegra-for-7.1-dt-bindings
for you to fetch changes up to bed2f5b4de6c6fd8f8928f6373ad92e8795c370f:
dt-bindings: arm: tegra: Document Jetson AGX Thor DevKit (2026-03-28 01:05:24 +0100)
Thanks,
Thierry
----------------------------------------------------------------
dt-bindings: Changes for v7.1-rc1
This contains a few conversions to DT schema along with various
additions and fixes to reduce the amount of validation warnings.
Included are also a new binding for the PCIe controller found on
Tegra264 as well as compatible strings for the Jetson AGX Thor
Developer Kit.
----------------------------------------------------------------
Sumit Gupta (1):
dt-bindings: arm: tegra: Add Tegra238 CBB compatible strings
Svyatoslav Ryhel (1):
dt-bindings: display: tegra: Document Tegra20 HDMI port
Thierry Reding (9):
dt-bindings: pci: Document the NVIDIA Tegra264 PCIe controller
dt-bindings: phy: tegra-xusb: Document Type C support
dt-bindings: clock: tegra124-dfll: Convert to json-schema
dt-bindings: interrupt-controller: tegra: Fix reg entries
dt-bindings: arm: tegra: Add missing compatible strings
dt-bindings: phy: tegra: Document Tegra210 USB PHY
dt-bindings: memory: Add Tegra210 memory controller bindings
dt-bindings: memory: tegra210: Mark EMC as cooling device
dt-bindings: arm: tegra: Document Jetson AGX Thor DevKit
Documentation/devicetree/bindings/arm/tegra.yaml | 56 +++-
.../bindings/arm/tegra/nvidia,tegra234-cbb.yaml | 4 +
.../bindings/clock/nvidia,tegra124-dfll.txt | 155 -----------
.../bindings/clock/nvidia,tegra124-dfll.yaml | 290 +++++++++++++++++++++
.../display/tegra/nvidia,tegra20-hdmi.yaml | 13 +-
.../interrupt-controller/nvidia,tegra20-ictlr.yaml | 23 +-
.../memory-controllers/nvidia,tegra210-emc.yaml | 6 +-
.../memory-controllers/nvidia,tegra210-mc.yaml | 77 ++++++
.../bindings/pci/nvidia,tegra264-pcie.yaml | 149 +++++++++++
.../bindings/phy/nvidia,tegra194-xusb-padctl.yaml | 39 ++-
.../bindings/phy/nvidia,tegra20-usb-phy.yaml | 1 +
11 files changed, 649 insertions(+), 164 deletions(-)
delete mode 100644 Documentation/devicetree/bindings/clock/nvidia,tegra124-dfll.txt
create mode 100644 Documentation/devicetree/bindings/clock/nvidia,tegra124-dfll.yaml
create mode 100644 Documentation/devicetree/bindings/memory-controllers/nvidia,tegra210-mc.yaml
create mode 100644 Documentation/devicetree/bindings/pci/nvidia,tegra264-pcie.yaml
^ permalink raw reply
* [GIT PULL 3/7] firmware: tegra: Changes for v7.1-rc1
From: Thierry Reding @ 2026-03-29 15:10 UTC (permalink / raw)
To: arm, soc; +Cc: Thierry Reding, Jon Hunter, linux-tegra, linux-arm-kernel
In-Reply-To: <20260329151045.1443133-1-thierry.reding@kernel.org>
From: Thierry Reding <thierry.reding@gmail.com>
Hi ARM SoC maintainers,
The following changes since commit 6de23f81a5e08be8fbf5e8d7e9febc72a5b5f27f:
Linux 7.0-rc1 (2026-02-22 13:18:59 -0800)
are available in the Git repository at:
git://git.kernel.org/pub/scm/linux/kernel/git/tegra/linux.git tags/tegra-for-7.1-firmware
for you to fetch changes up to e68d494b8946e9060e60427f365107194f90ba0d:
soc/tegra: bpmp: Use ENODEV instead of ENOTSUPP (2026-03-27 16:30:54 +0100)
Thanks,
Thierry
----------------------------------------------------------------
firmware: tegra: Changes for v7.1-rc1
This introduces a new API for the BPMP to be pass along a specifier from
DT when getting a reference from a phandle. This is used to reference
specific instances of the PCI controller on Tegra264. The ABI header for
BPMP is updated to the latest version and BPMP APIs now use the more
intuitive ENODEV instead of the non SUSV4 ENOTSUPP error code for stub
implementations.
----------------------------------------------------------------
Thierry Reding (4):
firmware: tegra: bpmp: Rename Tegra239 to Tegra238
soc/tegra: Update BPMP ABI header
firmware: tegra: bpmp: Add tegra_bpmp_get_with_id() function
soc/tegra: bpmp: Use ENODEV instead of ENOTSUPP
drivers/firmware/tegra/bpmp.c | 34 +
include/soc/tegra/bpmp-abi.h | 4573 +++++++++++++++++++++++++++++++++--------
include/soc/tegra/bpmp.h | 20 +-
3 files changed, 3725 insertions(+), 902 deletions(-)
^ permalink raw reply
* Re: (subset) [PATCH net-next v4 0/2] Add ICSSG0 dual EMAC support for AM642 EVM
From: Vignesh Raghavendra @ 2026-03-29 14:49 UTC (permalink / raw)
To: Nishanth Menon, Meghana Malladi
Cc: Tero Kristo, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
linux-arm-kernel, devicetree, linux-kernel, netdev, srk,
danishanwar
In-Reply-To: <20260323090358.632329-1-m-malladi@ti.com>
Hi Meghana Malladi,
On Mon, 23 Mar 2026 14:33:56 +0530, Meghana Malladi wrote:
> Add ICSSG0 dual EMAC support for AM642 EVM
>
> This series adds device tree overlay support for enabling ICSSG0 dual EMAC
> on the AM642 EVM, along with the necessary PHY driver configuration.
>
> The overlay enables both ICSSG0 Ethernet interfaces (port0 and port1) in
> dual EMAC mode and can be combined with the existing ICSSG1 overlay to
> enable all four ICSSG interfaces if needed.
>
> [...]
I have applied the following to branch ti-k3-config-next on [1].
Thank you!
[2/2] arm64: defconfig: Enable DP83TG720 PHY driver
commit: 192c7f34d2f63552211ef4cb8bbd2933f95106e2
All being well this means that it will be integrated into the linux-next
tree (usually sometime in the next 24 hours) and sent up the chain during
the next merge window (or sooner if it is a relevant bug fix), however if
problems are discovered then the patch may be dropped or reverted.
You may get further e-mails resulting from automated or manual testing
and review of the tree, please engage with people reporting problems and
send followup patches addressing any issues that are reported if needed.
If any updates are required or you are submitting further changes they
should be sent as incremental updates against current git, existing
patches will not be replaced.
Please add any relevant lists and maintainers to the CCs when replying
to this mail.
[1] https://git.kernel.org/pub/scm/linux/kernel/git/ti/linux.git
--
Vignesh
^ permalink raw reply
* Re: [PATCH v9 0/5] PCI: of: Remove max-link-speed generation validation
From: Hans Zhang @ 2026-03-29 14:47 UTC (permalink / raw)
To: Bjorn Helgaas
Cc: lpieralisi, jingoohan1, mani, kwilczynski, bhelgaas,
florian.fainelli, jim2101024, robh, ilpo.jarvinen, linux-arm-msm,
linux-arm-kernel, linux-renesas-soc, claudiu.beznea.uj,
linux-mediatek, linux-tegra, linux-omap, bcm-kernel-feedback-list,
linux-pci, linux-kernel, shawn.lin
In-Reply-To: <20260327164250.GA1513325@bhelgaas>
On 3/28/26 00:42, Bjorn Helgaas wrote:
> On Sat, Mar 14, 2026 at 12:55:17AM +0800, Hans Zhang wrote:
>> Hi,
>>
>> This series moves the validation from the common OF function to the
>> individual PCIe controller drivers. To protect against out-of-bounds
>> accesses to the pcie_link_speed[] array, we first introduce a helper
>> function pcie_get_link_speed() that safely returns the speed value
>> (or PCI_SPEED_UNKNOWN) for a given generation number.
>>
>> Then all direct uses of pcie_link_speed[] as an array are converted to
>> use the new helper, ensuring that even if an invalid generation number
>> reaches those code paths, no out-of-bounds access occurs.
>>
>> For several drivers that read the "max-link-speed" property
>> (pci-j721e, brcmstb, mediatek-gen3, rzg3s-host), we add an explicit
>> validation step: if the value is missing, out of range, or unsupported
>> by the hardware, a safe default is used (usually Gen2). Other drivers
>> (mainly DesignWare glue drivers) rely on the helper to safely handle
>> invalid values, but do not yet include fallback logic or warnings.
>>
>> Finally, the range check is removed from of_pci_get_max_link_speed(),
>> so that future PCIe generations can be supported without modifying
>> drivers/pci/of.c.
>
> Thanks for this series.
>
> We still have a couple references to pcie_link_speed[] that bypass
> pcie_get_link_speed(). These are safe because PCI_EXP_LNKSTA_CLS is
> 0xf and pcie_link_speed[] is size 16, but I'm not sure the direct
> reference is necessary.
>
> The array itself is exported, which I suppose we needed for modular
> PCI controller drivers, but we probably don't need it now that
> pcie_get_link_speed() is exported?
>
> $ git grep "\<pcie_link_speed\>"
> drivers/pci/pci-sysfs.c: speed = pcie_link_speed[linkstat & PCI_EXP_LNKSTA_CLS];
> drivers/pci/pci.c: return pcie_link_speed[FIELD_GET(PCI_EXP_LNKSTA_CLS, lnksta)];
> drivers/pci/pci.h:extern const unsigned char pcie_link_speed[];
> drivers/pci/pci.h: bus->cur_bus_speed = pcie_link_speed[linksta & PCI_EXP_LNKSTA_CLS];
> drivers/pci/probe.c:const unsigned char pcie_link_speed[] = {
> drivers/pci/probe.c:EXPORT_SYMBOL_GPL(pcie_link_speed);
> drivers/pci/probe.c: if (speed >= ARRAY_SIZE(pcie_link_speed))
> drivers/pci/probe.c: return pcie_link_speed[speed];
> drivers/pci/probe.c: bus->max_bus_speed = pcie_link_speed[linkcap & PCI_EXP_LNKCAP_SLS];
Hi Bjorn,
Yes, I also realized that this array is directly used in other places.
So I submitted this series and I would appreciate it if you could review
it to ensure its correctness.
See also this series:
https://patchwork.kernel.org/project/linux-pci/patch/20260315160057.127639-1-18255117159@163.com/
Best regards,
Hans
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox