* [PATCH v4 0/4] arm64: cross-CPU NMI via SDEI
From: Kiryl Shutsemau @ 2026-06-17 19:20 UTC (permalink / raw)
To: Catalin Marinas, Will Deacon, James Morse
Cc: Mark Rutland, Marc Zyngier, Doug Anderson, Petr Mladek,
Thomas Gleixner, Andrew Morton, Baoquan He, Puranjay Mohan,
Usama Arif, Breno Leitao, Julien Thierry, Lecopzer Chen,
Sumit Garg, kernel-team, kexec, linux-arm-kernel, linux-kernel,
Kiryl Shutsemau (Meta)
From: "Kiryl Shutsemau (Meta)" <kas@kernel.org>
A class of debug/observability features needs to interrupt a CPU that has
its interrupts locally masked: the all-CPU backtrace behind sysrq-l /
RCU-stall / hung-task / hard-lockup dumps, and crash_smp_send_stop()
capturing a stuck CPU's state into the vmcore. On arm64 these need a
mechanism that reaches a CPU spinning with DAIF masked, which a normal IPI
cannot.
arm64 has two such mechanisms today:
- GICv3 pseudo-NMI (interrupt priority masking). Its cost is on the
interrupt mask/unmask hot path: local_irq_enable() becomes an
ICC_PMR_EL1 write plus a synchronising barrier, and exception
entry/exit save and restore the PMR, paid on every CPU whether or not
an NMI is ever delivered. In our measurements, enabling pseudo-NMI
costs up to ~5% on real workloads, and ~66% on a syscall-in-a-loop
microbenchmark. A fleet-wide ~5% regression is not acceptable, so
these systems run with pseudo-NMI disabled.
- FEAT_NMI (Armv8.8) -- the architectural fix, but absent from deployed
silicon and from most of the fleet for years to come.
For deployments that do not run pseudo-NMI, the backtrace and crash paths
are degraded: a plain IPI can't reach the masked CPU, so the backtrace of
the CPU you care about comes back empty and the kdump is missing the
culprit's registers. The hard-lockup detector on these systems is the
software buddy detector (HARDLOCKUP_DETECTOR_BUDDY): it detects a stall
from a neighbour CPU, but it cannot itself interrupt the wedged CPU, so
its report has no stack for the culprit and (with hardlockup_panic) the
panic runs on the bystander.
This series adds a third delivery backend that costs nothing on the hot
path: SDEI. Firmware delivers an SDEI event into a CPU regardless of its
DAIF state, so interrupt masking stays the cheap PSTATE.DAIF operation and
the firmware round-trip is paid only at the rare moment a CPU must be
interrupted.
It does not add a hard-lockup detector. Detection stays with the buddy
detector (CONFIG_HARDLOCKUP_DETECTOR_PREFER_BUDDY); this series gives the
backtrace and crash-stop paths -- including the buddy detector's
backtrace of the stalled CPU -- a way to actually reach a masked CPU.
Mechanism
=========
It uses the standard SDEI software-signalled event (event 0) and the
SDEI_EVENT_SIGNAL call (DEN0054) -- a spec-defined cross-PE signal, not a
vendor extension. The driver registers a handler for event 0 and pokes a
target CPU with sdei_event_signal(0, target_mpidr); firmware makes event 0
pending on that PE and dispatches the handler NMI-like.
No firmware change is required beyond SDEI being enabled, which
firmware-first RAS (APEI/GHES) deployments already have; the only
SDEI-core addition is a thin sdei_event_signal() wrapper over the standard
call.
Prior SDEI watchdog work
========================
Out-of-tree SDEI hard-lockup watchdogs exist (e.g. in the openEuler and
Anolis kernels). They bind the secure physical timer as an SDEI event, so
firmware delivers a periodic self-CPU tick that drives a detector. That
requires a new SDEI interrupt-binding API, pushes the watchdog period into
firmware, and adds secure-timer EOI handling on the kexec path. This
series instead uses only the standard software-signalled event 0, keeps
all timing in the kernel (the buddy detector), and the same delivery
primitive serves the backtrace and crash-stop users, not just lockup
reporting.
Not included / follow-ups
=========================
- No SDEI hard-lockup-detector backend. v1 had one; it is dropped here.
The buddy detector plus this series' backtrace already cover the
no-pseudo-NMI case, and a dedicated SDEI backend duplicated the
perf-NMI detector it had to compile-exclude. Run PREFER_BUDDY.
- A CPU stopped by the SDEI rung is parked, not powered off via PSCI
CPU_OFF. Reaching and dumping the wedged CPU -- the point of the
series -- works, and it matches the shared stop path's own park
fallback when CPU_OFF is unavailable. The consequence is that an SMP
crash-capture kernel cannot re-online such a CPU (it stays "already
on"); the capture kernel boots and runs on the remaining CPUs.
Powering the stopped CPU off so a capture kernel can reclaim it
requires completing the SDEI event and then CPU_OFF, which hit a
firmware-specific issue still under investigation; it is left as a
follow-up and does not affect the dump's contents.
Testing
=======
Developed on QEMU 'virt' (Trusted Firmware-A with SDEI enabled) and
validated on NVIDIA Grace (Neoverse V2) hardware, under
irqchip.gicv3_pseudo_nmi=0 with HARDLOCKUP_DETECTOR_PREFER_BUDDY=y:
- sysrq-l backtrace of an interrupt-masked CPU returns its real stack,
pstate showing DAIF set -- proof SDEI delivered into the masked CPU;
- buddy detector catches a hard lockup (LKDTM) and the wedged CPU's
stack is fetched via the SDEI backtrace;
- reboot/halt and the panic/kdump crash stop reach a wedged CPU via the
SDEI rung ("SMP: retry stop with SDEI NMI for CPUs N"), and the kdump
captures the wedged CPU's registers in the vmcore;
- with SDEI absent (plain QEMU 'virt', no firmware support) the driver
stays inert: no event registration and no boot-time warning.
Changes since v3
================
- New sdei_is_present() patch; the NMI initcall now skips registration
(and its boot warning) on non-SDEI systems (Puranjay Mohan).
- Fixed a NULL deref on a parallel-panic crash stop and the
CONFIG_KEXEC_CORE=n build (Puranjay Mohan).
- kernel-doc + barrier comments on the stop path; reordered the two
arm_sdei core patches (Doug Anderson).
Changes since v2
================
- Unified the CPU-stop paths into one arm64_nmi_cpu_stop(regs,
die_on_crash), dropping local_cpu_stop()/ipi_cpu_crash_stop().
- SDEI rung tests sdei_nmi_active() first; sdei_nmi_stop_cpus() is void.
- Replaced the per-CPU stop cpumask with a write-once flag.
- Commented the SDEI-park / no-CPU_OFF rationale.
Changes since v1
================
- Dropped the SDEI hard-lockup-detector patch; use the buddy detector.
- Reworked crash-stop into a third rung of smp_send_stop().
- Renamed the driver to arm_sdei_nmi.c; widened the MAINTAINERS glob.
v3: https://lore.kernel.org/all/cover.1781490440.git.kas@kernel.org
v2: https://lore.kernel.org/all/cover.1781082212.git.kas@kernel.org
v1: https://lore.kernel.org/all/cover.1780496779.git.kas@kernel.org
Also available at:
git://git.kernel.org/pub/scm/linux/kernel/git/kas/linux.git sdei-nmi/v4
Kiryl Shutsemau (Meta) (4):
firmware: arm_sdei: add sdei_is_present()
firmware: arm_sdei: add SDEI_EVENT_SIGNAL support
drivers/firmware: add SDEI cross-CPU NMI service for arm64
arm64: escalate smp_send_stop() to an SDEI NMI as a last resort
MAINTAINERS | 2 +-
arch/arm64/include/asm/nmi.h | 48 +++++++
arch/arm64/kernel/smp.c | 124 ++++++++++++-----
drivers/firmware/Kconfig | 21 +++
drivers/firmware/Makefile | 1 +
drivers/firmware/arm_sdei.c | 22 +++
drivers/firmware/arm_sdei_nmi.c | 238 ++++++++++++++++++++++++++++++++
include/linux/arm_sdei.h | 9 ++
include/uapi/linux/arm_sdei.h | 1 +
9 files changed, 427 insertions(+), 39 deletions(-)
create mode 100644 arch/arm64/include/asm/nmi.h
create mode 100644 drivers/firmware/arm_sdei_nmi.c
base-commit: 8cd9520d35a6c38db6567e97dd93b1f11f185dc6
--
2.54.0
^ permalink raw reply
* Re: [PATCH] nvmem: rockchip-otp: initialize ret in rk3588_otp_read
From: Jonas Karlman @ 2026-06-17 19:15 UTC (permalink / raw)
To: Ruoyu Wang
Cc: Srinivas Kandagatla, Heiko Stuebner, linux-arm-kernel,
linux-rockchip, linux-kernel
In-Reply-To: <20260617183803.1106486-1-ruoyuw560@gmail.com>
Hi Ruoyu,
On 6/17/2026 8:38 PM, Ruoyu Wang wrote:
> rk3588_otp_read() returns ret after a count-controlled loop. If count is
> zero, the loop is skipped and ret is not assigned. Initialize ret to 0
> for the empty read path.
To my knowledge core will protect against bytes<=0 read, if that is not
the case we should likely fix so that rockchip_otp_read() never calls
the internal reg_read ops with bytes/count<=0.
Regards,
Jonas
>
> Signed-off-by: Ruoyu Wang <ruoyuw560@gmail.com>
> ---
> drivers/nvmem/rockchip-otp.c | 2 +-
> 1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/drivers/nvmem/rockchip-otp.c b/drivers/nvmem/rockchip-otp.c
> index 0ec78b5e19e7d..50a19b6dc4027 100644
> --- a/drivers/nvmem/rockchip-otp.c
> +++ b/drivers/nvmem/rockchip-otp.c
> @@ -242,7 +242,7 @@ static int rk3588_otp_read(void *context, unsigned int offset,
> {
> struct rockchip_otp *otp = context;
> u32 *buf = val;
> - int ret;
> + int ret = 0;
>
> while (count--) {
> writel((offset++ << RK3588_ADDR_SHIFT) |
^ permalink raw reply
* [PATCH 9/9] arm64: dts: rockchip: Add RK3588 VOP2 resets
From: Cristian Ciocaltea @ 2026-06-17 18:52 UTC (permalink / raw)
To: Sandy Huang, Heiko Stübner, Andy Yan, David Airlie,
Simona Vetter, Maarten Lankhorst, Maxime Ripard,
Thomas Zimmermann, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Philipp Zabel, Andrzej Hajda, Neil Armstrong, Robert Foss,
Laurent Pinchart, Jonas Karlman, Jernej Skrabec, Luca Ceresoli
Cc: kernel, Andy Yan, dri-devel, devicetree, linux-arm-kernel,
linux-rockchip, linux-kernel
In-Reply-To: <20260617-dw-hdmi-qp-yuv-v1-0-a665cfd06d7d@collabora.com>
Add the missing reset properties to VOP2 on RK3588.
Co-developed-by: Andy Yan <andy.yan@rock-chips.com>
Signed-off-by: Andy Yan <andy.yan@rock-chips.com>
Signed-off-by: Cristian Ciocaltea <cristian.ciocaltea@collabora.com>
---
arch/arm64/boot/dts/rockchip/rk3588-base.dtsi | 12 ++++++++++++
1 file changed, 12 insertions(+)
diff --git a/arch/arm64/boot/dts/rockchip/rk3588-base.dtsi b/arch/arm64/boot/dts/rockchip/rk3588-base.dtsi
index 4fb8888c281c..1404cd7ecf02 100644
--- a/arch/arm64/boot/dts/rockchip/rk3588-base.dtsi
+++ b/arch/arm64/boot/dts/rockchip/rk3588-base.dtsi
@@ -1453,6 +1453,18 @@ vop: vop@fdd90000 {
"pll_hdmiphy0";
iommus = <&vop_mmu>;
power-domains = <&power RK3588_PD_VOP>;
+ resets = <&cru SRST_A_VOP>,
+ <&cru SRST_H_VOP>,
+ <&cru SRST_D_VOP0>,
+ <&cru SRST_D_VOP1>,
+ <&cru SRST_D_VOP2>,
+ <&cru SRST_D_VOP3>;
+ reset-names = "axi",
+ "ahb",
+ "dclk_vp0",
+ "dclk_vp1",
+ "dclk_vp2",
+ "dclk_vp3";
rockchip,grf = <&sys_grf>;
rockchip,vop-grf = <&vop_grf>;
rockchip,vo1-grf = <&vo1_grf>;
--
2.54.0
^ permalink raw reply related
* [PATCH 5/9] drm/rockchip: vop2: Switch to enum vop_csc_format
From: Cristian Ciocaltea @ 2026-06-17 18:51 UTC (permalink / raw)
To: Sandy Huang, Heiko Stübner, Andy Yan, David Airlie,
Simona Vetter, Maarten Lankhorst, Maxime Ripard,
Thomas Zimmermann, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Philipp Zabel, Andrzej Hajda, Neil Armstrong, Robert Foss,
Laurent Pinchart, Jonas Karlman, Jernej Skrabec, Luca Ceresoli
Cc: kernel, Andy Yan, dri-devel, devicetree, linux-arm-kernel,
linux-rockchip, linux-kernel
In-Reply-To: <20260617-dw-hdmi-qp-yuv-v1-0-a665cfd06d7d@collabora.com>
Improve code readability in vop2_setup_csc_mode() by using enum
vop_csc_format for the csc_mode variable, as well as for the return type
of the vop2_convert_csc_mode() helper, which already returns CSC_*
enumerators.
While at it, replace the nonsensical 'csc_mode = false' assignment in
the no-conversion branch with the equivalent CSC_BT601L, which carries
the same value (0) but is type-correct.
Signed-off-by: Cristian Ciocaltea <cristian.ciocaltea@collabora.com>
---
drivers/gpu/drm/rockchip/rockchip_drm_vop2.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
index df475173dc8e..e0d6e42fedb1 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
@@ -648,7 +648,7 @@ static void vop2_setup_scale(struct vop2 *vop2, const struct vop2_win *win,
}
}
-static int vop2_convert_csc_mode(int csc_mode)
+static enum vop_csc_format vop2_convert_csc_mode(int csc_mode)
{
switch (csc_mode) {
case V4L2_COLORSPACE_SMPTE170M:
@@ -711,7 +711,7 @@ static void vop2_setup_csc_mode(struct vop2_video_port *vp,
int input_csc = V4L2_COLORSPACE_DEFAULT;
int output_csc = vcstate->color_space;
bool r2y_en, y2r_en;
- int csc_mode;
+ enum vop_csc_format csc_mode;
if (is_input_yuv && !is_output_yuv) {
y2r_en = true;
@@ -724,7 +724,7 @@ static void vop2_setup_csc_mode(struct vop2_video_port *vp,
} else {
y2r_en = false;
r2y_en = false;
- csc_mode = false;
+ csc_mode = CSC_BT601L;
}
vop2_win_write(win, VOP2_WIN_Y2R_EN, y2r_en);
--
2.54.0
^ permalink raw reply related
* [PATCH 8/9] drm/rockchip: dw_hdmi_qp: Enable YUV420 output format
From: Cristian Ciocaltea @ 2026-06-17 18:52 UTC (permalink / raw)
To: Sandy Huang, Heiko Stübner, Andy Yan, David Airlie,
Simona Vetter, Maarten Lankhorst, Maxime Ripard,
Thomas Zimmermann, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Philipp Zabel, Andrzej Hajda, Neil Armstrong, Robert Foss,
Laurent Pinchart, Jonas Karlman, Jernej Skrabec, Luca Ceresoli
Cc: kernel, Andy Yan, dri-devel, devicetree, linux-arm-kernel,
linux-rockchip, linux-kernel
In-Reply-To: <20260617-dw-hdmi-qp-yuv-v1-0-a665cfd06d7d@collabora.com>
Both RK3576 and RK3588 SoCs are capable of driving the YUV420 output
color format, and the required bus-format handling and VOP2 support are
already in place. Advertise it via the platform supported formats so
the HDMI core can select it.
YUV420 halves the TMDS bandwidth compared to RGB/YUV444, which enables
high-resolution modes such as 4K@60Hz on links that cannot otherwise
carry the full-bandwidth signal.
Signed-off-by: Cristian Ciocaltea <cristian.ciocaltea@collabora.com>
---
drivers/gpu/drm/rockchip/dw_hdmi_qp-rockchip.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/rockchip/dw_hdmi_qp-rockchip.c b/drivers/gpu/drm/rockchip/dw_hdmi_qp-rockchip.c
index 3a1c027aa90b..e29522afc6f0 100644
--- a/drivers/gpu/drm/rockchip/dw_hdmi_qp-rockchip.c
+++ b/drivers/gpu/drm/rockchip/dw_hdmi_qp-rockchip.c
@@ -612,7 +612,8 @@ static int dw_hdmi_qp_rockchip_bind(struct device *dev, struct device *master,
plat_data.supported_formats = BIT(DRM_OUTPUT_COLOR_FORMAT_RGB444) |
BIT(DRM_OUTPUT_COLOR_FORMAT_YCBCR444) |
- BIT(DRM_OUTPUT_COLOR_FORMAT_YCBCR422);
+ BIT(DRM_OUTPUT_COLOR_FORMAT_YCBCR422) |
+ BIT(DRM_OUTPUT_COLOR_FORMAT_YCBCR420);
encoder = &hdmi->encoder.encoder;
encoder->possible_crtcs = drm_of_find_possible_crtcs(drm, dev->of_node);
--
2.54.0
^ permalink raw reply related
* [PATCH 7/9] drm/rockchip: dw_hdmi_qp: Support 10-bit YUV422 output format
From: Cristian Ciocaltea @ 2026-06-17 18:52 UTC (permalink / raw)
To: Sandy Huang, Heiko Stübner, Andy Yan, David Airlie,
Simona Vetter, Maarten Lankhorst, Maxime Ripard,
Thomas Zimmermann, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Philipp Zabel, Andrzej Hajda, Neil Armstrong, Robert Foss,
Laurent Pinchart, Jonas Karlman, Jernej Skrabec, Luca Ceresoli
Cc: kernel, Andy Yan, dri-devel, devicetree, linux-arm-kernel,
linux-rockchip, linux-kernel
In-Reply-To: <20260617-dw-hdmi-qp-yuv-v1-0-a665cfd06d7d@collabora.com>
Rockchip DW HDMI QP encoder supports YUV 4:2:2 output through
ROCKCHIP_OUT_MODE_YUV422, but was limited to 8-bit depth via
MEDIA_BUS_FMT_UYVY8_1X16. Add support for its 10-bit counterpart
MEDIA_BUS_FMT_UYVY10_1X20, which carries two 10-bit components per clock
cycle on a 20-bit wide bus.
YUV 4:2:2 always transmits two 12-bit components per pixel, regardless
of the color depth. From a clock-rate perspective this is equivalent to
three 8-bit RGB components, so configure the HDMI PHY with 8 bpc when
YUV 4:2:2 is in use to keep its output clock aligned with the TMDS
character rate. Otherwise the PHY PLL output would be scaled by bpc/8
for higher color depths, producing a clock rate that confuses downstream
consumers such as the VOP2 display controller.
Signed-off-by: Cristian Ciocaltea <cristian.ciocaltea@collabora.com>
---
drivers/gpu/drm/rockchip/dw_hdmi_qp-rockchip.c | 10 +++++++++-
1 file changed, 9 insertions(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/rockchip/dw_hdmi_qp-rockchip.c b/drivers/gpu/drm/rockchip/dw_hdmi_qp-rockchip.c
index 815f9ea7bcbe..3a1c027aa90b 100644
--- a/drivers/gpu/drm/rockchip/dw_hdmi_qp-rockchip.c
+++ b/drivers/gpu/drm/rockchip/dw_hdmi_qp-rockchip.c
@@ -216,6 +216,7 @@ dw_hdmi_qp_rockchip_encoder_atomic_check(struct drm_encoder *encoder,
s->output_mode = ROCKCHIP_OUT_MODE_AAAA;
break;
case MEDIA_BUS_FMT_UYVY8_1X16:
+ case MEDIA_BUS_FMT_UYVY10_1X20:
s->output_mode = ROCKCHIP_OUT_MODE_YUV422;
break;
case MEDIA_BUS_FMT_UYYVYY8_0_5X24:
@@ -227,7 +228,14 @@ dw_hdmi_qp_rockchip_encoder_atomic_check(struct drm_encoder *encoder,
}
phy_cfg.hdmi.tmds_char_rate = conn_state->hdmi.tmds_char_rate;
- phy_cfg.hdmi.bpc = conn_state->hdmi.output_bpc;
+ /*
+ * YUV422 always transmits two 12-bit components per clock cycle,
+ * regardless of the color depth, which from a rate perspective is
+ * equivalent to three 8-bit RGB components. Force 8 bpc here to
+ * keep the PHY PLL output aligned with the TMDS character rate.
+ */
+ phy_cfg.hdmi.bpc = (s->output_mode == ROCKCHIP_OUT_MODE_YUV422 ?
+ 8 : conn_state->hdmi.output_bpc);
ret = phy_configure(hdmi->phy, &phy_cfg);
if (!ret) {
--
2.54.0
^ permalink raw reply related
* [PATCH 2/9] drm/rockchip: vop2: Reset AXI and DCLK to improve robustness
From: Cristian Ciocaltea @ 2026-06-17 18:51 UTC (permalink / raw)
To: Sandy Huang, Heiko Stübner, Andy Yan, David Airlie,
Simona Vetter, Maarten Lankhorst, Maxime Ripard,
Thomas Zimmermann, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Philipp Zabel, Andrzej Hajda, Neil Armstrong, Robert Foss,
Laurent Pinchart, Jonas Karlman, Jernej Skrabec, Luca Ceresoli
Cc: kernel, Andy Yan, dri-devel, devicetree, linux-arm-kernel,
linux-rockchip, linux-kernel
In-Reply-To: <20260617-dw-hdmi-qp-yuv-v1-0-a665cfd06d7d@collabora.com>
Assert the AXI reset in the CRTC disable path, and the VP DCLK reset in
the enable path.
These resets are intended to leave the hardware in a clean state for the
next use, helping recover from exceptions such as IOMMU page faults, as
well as to prevent random display output glitches, such as a blank
image, observed when switching modes that also change the color format,
e.g. from RGB to YUV420 and vice versa.
For now this seems to affect only the RK3588, hence the resets are
optional and will be provided in the device tree for this SoC only.
Co-developed-by: Andy Yan <andy.yan@rock-chips.com>
Signed-off-by: Andy Yan <andy.yan@rock-chips.com>
Signed-off-by: Cristian Ciocaltea <cristian.ciocaltea@collabora.com>
---
drivers/gpu/drm/rockchip/rockchip_drm_vop2.c | 35 ++++++++++++++++++++++++++++
drivers/gpu/drm/rockchip/rockchip_drm_vop2.h | 4 ++++
2 files changed, 39 insertions(+)
diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
index 4cce3e336f5b..2833fb49ad81 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
@@ -17,6 +17,7 @@
#include <linux/platform_device.h>
#include <linux/pm_runtime.h>
#include <linux/regmap.h>
+#include <linux/reset.h>
#include <linux/swab.h>
#include <drm/drm.h>
@@ -860,6 +861,26 @@ static int vop2_core_clks_prepare_enable(struct vop2 *vop2)
return ret;
}
+static void vop2_clk_reset(struct vop2 *vop2, struct reset_control *rstc)
+{
+ int ret;
+
+ if (!rstc)
+ return;
+
+ ret = reset_control_assert(rstc);
+ if (ret < 0) {
+ drm_warn(vop2->drm, "failed to assert reset: %d\n", ret);
+ return;
+ }
+
+ udelay(10);
+
+ ret = reset_control_deassert(rstc);
+ if (ret < 0)
+ drm_err(vop2->drm, "failed to deassert reset: %d\n", ret);
+}
+
static void rk3588_vop2_power_domain_enable_all(struct vop2 *vop2)
{
u32 pd;
@@ -938,6 +959,8 @@ static void vop2_disable(struct vop2 *vop2)
{
rockchip_drm_dma_detach_device(vop2->drm, vop2->dev);
+ vop2_clk_reset(vop2, vop2->axi_rst);
+
pm_runtime_put_sync(vop2->dev);
regcache_drop_region(vop2->map, 0, vop2_regmap_config.max_register);
@@ -1948,6 +1971,8 @@ static void vop2_crtc_atomic_enable(struct drm_crtc *crtc,
vop2_crtc_atomic_try_set_gamma(vop2, vp, crtc, crtc_state);
+ vop2_clk_reset(vop2, vp->dclk_rst);
+
drm_crtc_vblank_on(crtc);
vop2_unlock(vop2);
@@ -2531,6 +2556,11 @@ static int vop2_create_crtcs(struct vop2 *vop2)
return dev_err_probe(drm->dev, PTR_ERR(vp->dclk),
"failed to get %s\n", dclk_name);
+ vp->dclk_rst = devm_reset_control_get_optional(vop2->dev, dclk_name);
+ if (IS_ERR(vp->dclk_rst))
+ return dev_err_probe(drm->dev, PTR_ERR(vp->dclk_rst),
+ "failed to get %s reset\n", dclk_name);
+
np = of_graph_get_remote_node(dev->of_node, i, -1);
if (!np) {
drm_dbg(vop2->drm, "%s: No remote for vp%d\n", __func__, i);
@@ -2890,6 +2920,11 @@ static int vop2_bind(struct device *dev, struct device *master, void *data)
return dev_err_probe(drm->dev, PTR_ERR(vop2->pll_hdmiphy1),
"failed to get pll_hdmiphy1\n");
+ vop2->axi_rst = devm_reset_control_get_optional(vop2->dev, "axi");
+ if (IS_ERR(vop2->axi_rst))
+ return dev_err_probe(drm->dev, PTR_ERR(vop2->axi_rst),
+ "failed to get axi reset\n");
+
vop2->irq = platform_get_irq(pdev, 0);
if (vop2->irq < 0)
return dev_err_probe(drm->dev, vop2->irq, "cannot find irq for vop2\n");
diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.h b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.h
index ffcb39c130aa..14b437d2d088 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.h
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.h
@@ -165,6 +165,8 @@ enum vop2_win_regs {
VOP2_WIN_MAX_REG,
};
+struct reset_control;
+
struct vop2_regs_dump {
const char *name;
u32 base;
@@ -238,6 +240,7 @@ struct vop2_video_port {
struct vop2 *vop2;
struct clk *dclk;
struct clk *dclk_src;
+ struct reset_control *dclk_rst;
unsigned int id;
const struct vop2_video_port_data *data;
@@ -329,6 +332,7 @@ struct vop2 {
struct clk *pclk;
struct clk *pll_hdmiphy0;
struct clk *pll_hdmiphy1;
+ struct reset_control *axi_rst;
/* optional internal rgb encoder */
struct rockchip_rgb *rgb;
--
2.54.0
^ permalink raw reply related
* [PATCH 4/9] drm/rockchip: vop2: Consolidate HDMI PHY PLL clock parent switch
From: Cristian Ciocaltea @ 2026-06-17 18:51 UTC (permalink / raw)
To: Sandy Huang, Heiko Stübner, Andy Yan, David Airlie,
Simona Vetter, Maarten Lankhorst, Maxime Ripard,
Thomas Zimmermann, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Philipp Zabel, Andrzej Hajda, Neil Armstrong, Robert Foss,
Laurent Pinchart, Jonas Karlman, Jernej Skrabec, Luca Ceresoli
Cc: kernel, Andy Yan, dri-devel, devicetree, linux-arm-kernel,
linux-rockchip, linux-kernel
In-Reply-To: <20260617-dw-hdmi-qp-yuv-v1-0-a665cfd06d7d@collabora.com>
The DCLK parent switch logic for HDMI0 and HDMI1 PHY PLLs was
duplicated, with each endpoint repeating the same clk_get_parent(),
clk_set_parent() and error handling calls.
Refactor this by first selecting the appropriate PHY PLL clock handle
based on the active HDMI endpoint, then performing the parent switch in
a single shared code path.
Signed-off-by: Cristian Ciocaltea <cristian.ciocaltea@collabora.com>
---
drivers/gpu/drm/rockchip/rockchip_drm_vop2.c | 36 +++++++++++-----------------
1 file changed, 14 insertions(+), 22 deletions(-)
diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
index 17d21e08ad97..df475173dc8e 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
@@ -1932,42 +1932,34 @@ static void vop2_crtc_atomic_enable(struct drm_crtc *crtc,
unsigned int bpc = vcstate->output_mode == ROCKCHIP_OUT_MODE_YUV422 ?
8 : vcstate->output_bpc;
unsigned long max_dclk = DIV_ROUND_CLOSEST_ULL(VOP2_MAX_DCLK_RATE * 8, bpc);
+ struct clk *pll_hdmiphy = NULL;
if (clock <= max_dclk) {
drm_for_each_encoder_mask(encoder, crtc->dev, crtc_state->encoder_mask) {
struct rockchip_encoder *rkencoder = to_rockchip_encoder(encoder);
if (rkencoder->crtc_endpoint_id == ROCKCHIP_VOP2_EP_HDMI0) {
- if (!vop2->pll_hdmiphy0)
- break;
-
- if (!vp->dclk_src)
- vp->dclk_src = clk_get_parent(vp->dclk);
-
- ret = clk_set_parent(vp->dclk, vop2->pll_hdmiphy0);
- if (ret < 0)
- drm_warn(vop2->drm,
- "Could not switch to HDMI0 PHY PLL: %d\n",
- ret);
+ pll_hdmiphy = vop2->pll_hdmiphy0;
break;
}
if (rkencoder->crtc_endpoint_id == ROCKCHIP_VOP2_EP_HDMI1) {
- if (!vop2->pll_hdmiphy1)
- break;
-
- if (!vp->dclk_src)
- vp->dclk_src = clk_get_parent(vp->dclk);
-
- ret = clk_set_parent(vp->dclk, vop2->pll_hdmiphy1);
- if (ret < 0)
- drm_warn(vop2->drm,
- "Could not switch to HDMI1 PHY PLL: %d\n",
- ret);
+ pll_hdmiphy = vop2->pll_hdmiphy1;
break;
}
}
}
+
+ if (pll_hdmiphy) {
+ if (!vp->dclk_src)
+ vp->dclk_src = clk_get_parent(vp->dclk);
+
+ ret = clk_set_parent(vp->dclk, pll_hdmiphy);
+ if (ret < 0)
+ drm_warn(vop2->drm,
+ "Failed to switch DCLK to HDMI PHY PLL: %d\n",
+ ret);
+ }
}
clk_set_rate(vp->dclk, clock);
--
2.54.0
^ permalink raw reply related
* [PATCH 6/9] drm/bridge: dw-hdmi-qp: Log resolution and refresh rate in atomic_enable()
From: Cristian Ciocaltea @ 2026-06-17 18:51 UTC (permalink / raw)
To: Sandy Huang, Heiko Stübner, Andy Yan, David Airlie,
Simona Vetter, Maarten Lankhorst, Maxime Ripard,
Thomas Zimmermann, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Philipp Zabel, Andrzej Hajda, Neil Armstrong, Robert Foss,
Laurent Pinchart, Jonas Karlman, Jernej Skrabec, Luca Ceresoli
Cc: kernel, Andy Yan, dri-devel, devicetree, linux-arm-kernel,
linux-rockchip, linux-kernel
In-Reply-To: <20260617-dw-hdmi-qp-yuv-v1-0-a665cfd06d7d@collabora.com>
The debug entry in the HDMI branch of dw_hdmi_qp_bridge_atomic_enable()
previously printed the literal string 'HDMI' as the mode field, giving
no information about the actual display timing being configured.
Extend it to include the active resolution and refresh rate by
retrieving the CRTC mode from the incoming atomic state:
dw_hdmi_qp_bridge_atomic_enable mode=1920x1080@50Hz fmt=RGB rate=185625000 bpc=10
This makes the log line self-contained and directly useful when
debugging mode-setting issues, format negotiation, or TMDS rate
mismatches without having to cross-reference a separate mode dump.
Signed-off-by: Cristian Ciocaltea <cristian.ciocaltea@collabora.com>
---
drivers/gpu/drm/bridge/synopsys/dw-hdmi-qp.c | 10 +++++++++-
1 file changed, 9 insertions(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi-qp.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi-qp.c
index 13fddd5ebc82..d73307ac4232 100644
--- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi-qp.c
+++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi-qp.c
@@ -752,6 +752,8 @@ static void dw_hdmi_qp_bridge_atomic_enable(struct drm_bridge *bridge,
{
struct dw_hdmi_qp *hdmi = bridge->driver_private;
struct drm_connector_state *conn_state;
+ const struct drm_display_mode *mode;
+ struct drm_crtc_state *crtc_state;
struct drm_connector *connector;
unsigned int op_mode;
@@ -764,9 +766,15 @@ static void dw_hdmi_qp_bridge_atomic_enable(struct drm_bridge *bridge,
return;
if (connector->display_info.is_hdmi) {
- dev_dbg(hdmi->dev, "%s mode=HDMI %s rate=%llu bpc=%u\n", __func__,
+ crtc_state = drm_atomic_get_new_crtc_state(state, conn_state->crtc);
+ mode = &crtc_state->mode;
+ dev_dbg(hdmi->dev,
+ "%s mode=HDMI %ux%u@%uHz fmt=%s rate=%llu bpc=%u\n",
+ __func__, mode->hdisplay, mode->vdisplay,
+ drm_mode_vrefresh(mode),
drm_hdmi_connector_get_output_format_name(conn_state->hdmi.output_format),
conn_state->hdmi.tmds_char_rate, conn_state->hdmi.output_bpc);
+
op_mode = 0;
hdmi->tmds_char_rate = conn_state->hdmi.tmds_char_rate;
} else {
--
2.54.0
^ permalink raw reply related
* [PATCH 3/9] drm/rockchip: vop2: Avoid DCLK source switch for 10-bit YUV422 output
From: Cristian Ciocaltea @ 2026-06-17 18:51 UTC (permalink / raw)
To: Sandy Huang, Heiko Stübner, Andy Yan, David Airlie,
Simona Vetter, Maarten Lankhorst, Maxime Ripard,
Thomas Zimmermann, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Philipp Zabel, Andrzej Hajda, Neil Armstrong, Robert Foss,
Laurent Pinchart, Jonas Karlman, Jernej Skrabec, Luca Ceresoli
Cc: kernel, Andy Yan, dri-devel, devicetree, linux-arm-kernel,
linux-rockchip, linux-kernel
In-Reply-To: <20260617-dw-hdmi-qp-yuv-v1-0-a665cfd06d7d@collabora.com>
Currently the color depth is always factored into the DCLK source
decision for HDMI output, which can break certain modes when operating
with depths greater than 8 bpc.
When the required transmission rate exceeds the 600 MHz limit of the
HDMI PHY PLL, e.g. for 4K@60Hz 10-bit RGB output, VOP2 will normally
fall back to using the less accurate system CRU as a DCLK source,
assuming HDMI 2.1 FRL is supported by the pipeline, otherwise the mode
will be rejected. For YUV420 output format this never happens, as it
uses half of the RGB bandwidth, hence the rate remains within the PHY
PLL limits.
On the other hand, YUV422 always transmits two 12-bit components per
clock cycle, regardless of the color depth, which from a clock-rate
perspective is equivalent to three 8-bit RGB components. For example,
4K@60Hz 10-bit YUV422 requires the same bandwidth as 4K@60Hz 8-bit RGB,
typically 594 MHz. However, VOP2 wrongly assumes it needs 742.5 MHz
(594 * 10 / 8) and ends up switching the DCLK source.
As a consequence, the modes requiring uncommon pixel clocks, such as
those corresponding to fractional refresh rates, will fail. An example
is 3840x2160@59.94Hz, which would likely rely on the 593.407 MHz clock
rate unsupported by the system CRU.
Note this only affects YUV422 with color depths greater than 8 bpc; for
8-bit YUV422 the 8/bpc factor is unity and the bandwidth check is
already correct.
Prevent the incorrect switches of DCLK source to system CRU for YUV422
output format by forcing 8 bpc when checking the bandwidth.
Signed-off-by: Cristian Ciocaltea <cristian.ciocaltea@collabora.com>
---
drivers/gpu/drm/rockchip/rockchip_drm_vop2.c | 13 +++++++++++--
1 file changed, 11 insertions(+), 2 deletions(-)
diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
index 2833fb49ad81..17d21e08ad97 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c
@@ -1922,8 +1922,17 @@ static void vop2_crtc_atomic_enable(struct drm_crtc *crtc,
* to 4K@60Hz, if available, otherwise keep using the system CRU.
*/
if (vop2->pll_hdmiphy0 || vop2->pll_hdmiphy1) {
- unsigned long max_dclk = DIV_ROUND_CLOSEST_ULL(VOP2_MAX_DCLK_RATE * 8,
- vcstate->output_bpc);
+ /*
+ * YUV422 always transmits two 12-bit components per clock
+ * cycle, regardless of the color depth, which from a rate
+ * perspective is equivalent to three 8-bit RGB components.
+ * Force 8 bpc here so the bandwidth check reflects the actual
+ * TMDS rate and avoids an unnecessary DCLK source switch.
+ */
+ unsigned int bpc = vcstate->output_mode == ROCKCHIP_OUT_MODE_YUV422 ?
+ 8 : vcstate->output_bpc;
+ unsigned long max_dclk = DIV_ROUND_CLOSEST_ULL(VOP2_MAX_DCLK_RATE * 8, bpc);
+
if (clock <= max_dclk) {
drm_for_each_encoder_mask(encoder, crtc->dev, crtc_state->encoder_mask) {
struct rockchip_encoder *rkencoder = to_rockchip_encoder(encoder);
--
2.54.0
^ permalink raw reply related
* [PATCH 1/9] dt-bindings: display: vop2: Add missing reset properties
From: Cristian Ciocaltea @ 2026-06-17 18:51 UTC (permalink / raw)
To: Sandy Huang, Heiko Stübner, Andy Yan, David Airlie,
Simona Vetter, Maarten Lankhorst, Maxime Ripard,
Thomas Zimmermann, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Philipp Zabel, Andrzej Hajda, Neil Armstrong, Robert Foss,
Laurent Pinchart, Jonas Karlman, Jernej Skrabec, Luca Ceresoli
Cc: kernel, Andy Yan, dri-devel, devicetree, linux-arm-kernel,
linux-rockchip, linux-kernel
In-Reply-To: <20260617-dw-hdmi-qp-yuv-v1-0-a665cfd06d7d@collabora.com>
Document the VOP2 resets corresponding to the AXI, AHB and DCLK_VP0..2
clocks, which are common to all supported SoCs, plus DCLK_VP3 which is
provided only on RK3588.
Signed-off-by: Cristian Ciocaltea <cristian.ciocaltea@collabora.com>
---
.../bindings/display/rockchip/rockchip-vop2.yaml | 42 ++++++++++++++++++++++
1 file changed, 42 insertions(+)
diff --git a/Documentation/devicetree/bindings/display/rockchip/rockchip-vop2.yaml b/Documentation/devicetree/bindings/display/rockchip/rockchip-vop2.yaml
index 93da1fb9adc4..d3bc5380f910 100644
--- a/Documentation/devicetree/bindings/display/rockchip/rockchip-vop2.yaml
+++ b/Documentation/devicetree/bindings/display/rockchip/rockchip-vop2.yaml
@@ -82,6 +82,20 @@ properties:
- {}
- {}
+ resets:
+ minItems: 5
+ maxItems: 6
+
+ reset-names:
+ minItems: 5
+ items:
+ - const: axi
+ - const: ahb
+ - const: dclk_vp0
+ - const: dclk_vp1
+ - const: dclk_vp2
+ - const: dclk_vp3
+
rockchip,grf:
$ref: /schemas/types.yaml#/definitions/phandle
description:
@@ -148,6 +162,12 @@ allOf:
clock-names:
maxItems: 5
+ resets:
+ maxItems: 5
+
+ reset-names:
+ maxItems: 5
+
interrupts:
maxItems: 1
@@ -194,6 +214,12 @@ allOf:
- {}
- const: pll_hdmiphy0
+ resets:
+ maxItems: 5
+
+ reset-names:
+ maxItems: 5
+
interrupts:
minItems: 4
@@ -246,6 +272,12 @@ allOf:
- const: pll_hdmiphy0
- const: pll_hdmiphy1
+ resets:
+ minItems: 6
+
+ reset-names:
+ minItems: 6
+
interrupts:
maxItems: 1
@@ -289,6 +321,16 @@ examples:
"dclk_vp0",
"dclk_vp1",
"dclk_vp2";
+ resets = <&cru SRST_A_VOP>,
+ <&cru SRST_H_VOP>,
+ <&cru SRST_VOP0>,
+ <&cru SRST_VOP1>,
+ <&cru SRST_VOP2>;
+ reset-names = "axi",
+ "ahb",
+ "dclk_vp0",
+ "dclk_vp1",
+ "dclk_vp2";
power-domains = <&power RK3568_PD_VO>;
rockchip,grf = <&grf>;
iommus = <&vop_mmu>;
--
2.54.0
^ permalink raw reply related
* [PATCH 0/9] Support 10-bit YUV422 and 8/10-bit YUV420 color format on DW HDMI QP
From: Cristian Ciocaltea @ 2026-06-17 18:51 UTC (permalink / raw)
To: Sandy Huang, Heiko Stübner, Andy Yan, David Airlie,
Simona Vetter, Maarten Lankhorst, Maxime Ripard,
Thomas Zimmermann, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Philipp Zabel, Andrzej Hajda, Neil Armstrong, Robert Foss,
Laurent Pinchart, Jonas Karlman, Jernej Skrabec, Luca Ceresoli
Cc: kernel, Andy Yan, dri-devel, devicetree, linux-arm-kernel,
linux-rockchip, linux-kernel
This series extends the output color format support of the Rockchip DW
HDMI QP controller to cover 10-bit YUV 4:2:2 and 8/10-bit YUV 4:2:0.
Please note this has a runtime dependency on the Rockchip Samsung HDPTX
PHY driver bug fixes posted separately as [1]. While there is no build
dependency, those fixes are required to address clock rate calculation
and synchronization issues that arise when changing the color depth
(bpc) while keeping the modeline constant.
Patches 1, 2 & 9 improve VOP2 robustness on RK3588, helping recover from
exceptions and preventing random display output glitches observed when
switching modes that also change the color format, e.g. from RGB to YUV
4:2:0 and vice versa.
Patch 3 avoids an incorrect DCLK source switch for 10-bit YUV 4:2:2 by
forcing 8 bpc in the bandwidth check.
Patches 4-6 are independent cleanups/improvements and can be applied on
their own.
Patch 7 adds MEDIA_BUS_FMT_UYVY10_1X20 for 10-bit YUV 4:2:2 output,
configuring the PHY with 8 bpc. YUV 4:2:2 always transmits two 12-bit
components per pixel regardless of color depth, so from a clock-rate
perspective it is equivalent to three 8-bit RGB components.
Patch 8 advertises YUV 4:2:0 output, now that the bus-format and VOP2
support are in place.
Tested on Radxa ROCK 5B (RK3588) and Radxa ROCK 4D (RK3576), up to
4K@60Hz YUV 4:2:0 and 4K@30Hz RGB.
[1] https://lore.kernel.org/all/20260612-hdptx-clk-fixes-v4-0-ce5e1d456cda@collabora.com/
Signed-off-by: Cristian Ciocaltea <cristian.ciocaltea@collabora.com>
---
Cristian Ciocaltea (9):
dt-bindings: display: vop2: Add missing reset properties
drm/rockchip: vop2: Reset AXI and DCLK to improve robustness
drm/rockchip: vop2: Avoid DCLK source switch for 10-bit YUV422 output
drm/rockchip: vop2: Consolidate HDMI PHY PLL clock parent switch
drm/rockchip: vop2: Switch to enum vop_csc_format
drm/bridge: dw-hdmi-qp: Log resolution and refresh rate in atomic_enable()
drm/rockchip: dw_hdmi_qp: Support 10-bit YUV422 output format
drm/rockchip: dw_hdmi_qp: Enable YUV420 output format
arm64: dts: rockchip: Add RK3588 VOP2 resets
.../bindings/display/rockchip/rockchip-vop2.yaml | 42 ++++++++++
arch/arm64/boot/dts/rockchip/rk3588-base.dtsi | 12 +++
drivers/gpu/drm/bridge/synopsys/dw-hdmi-qp.c | 10 ++-
drivers/gpu/drm/rockchip/dw_hdmi_qp-rockchip.c | 13 +++-
drivers/gpu/drm/rockchip/rockchip_drm_vop2.c | 90 +++++++++++++++-------
drivers/gpu/drm/rockchip/rockchip_drm_vop2.h | 4 +
6 files changed, 141 insertions(+), 30 deletions(-)
---
base-commit: 2bfa2e7f19a106966ca97e0aaaad49e17f614cbb
change-id: 20260617-dw-hdmi-qp-yuv-2b0f7bb5ba81
^ permalink raw reply
* Re: [RFC PATCH 3/6] arm64: mm: fix restoring linear map permissions on execmem cache clean
From: Mike Rapoport @ 2026-06-17 18:40 UTC (permalink / raw)
To: Adrian Barnaś
Cc: Brendan Jackman, linux-arm-kernel, linux-mm, Catalin Marinas,
Will Deacon, Ryan Roberts, David Hildenbrand, Ard Biesheuvel,
Christoph Lameter, Yang Shi, Brendan Jackman, owner-linux-mm
In-Reply-To: <ajK6w3YTFpVaUl3v@google.com>
Hi Adrian,
On Wed, Jun 17, 2026 at 03:18:27PM +0000, Adrian Barnaś wrote:
> On Fri, Jun 12, 2026 at 10:17:55AM +0300, Mike Rapoport wrote:
> > >
> > > Hm, maybe desirable for execmem but that doesn't really mean the x86
> > > behaviour is correct. Maybe it makes more sense to change the x86
> > > to align with the arm64 behaviour here?
> > >
> > > BTW we should probably document this API a little bit, I never thought
> > > abut what "valid" actually means until now. I had thought of it as "I
> > > can access this memory" but that's an unclear concept and now I realise
> > > "valid" is a technical concept in Arm that's confusing. And it's extra
> > > confusing if the kernel API uses "valid" to mean a _different_ thing.
> >
> > I've got confused too and that's how set_direct_map_valid() got into x86
> > with a different semantics than on arm64.
> >
> > What execmem really needs is set_direct_map_default() variant that gets
> > nr_pages.
> >
> > AFAIR, set_direct_map_default() has a single 'page' parameter because it
> > was added to reset permissions for the direct map alias for vmalloc()'ed
> > pages before there was VMALLOC_HUGE and each page had to be reset
> > independently anyway.
> >
> > Maybe it's time to add nr_pages to set_direct_map_valid().
>
> I was also quite confused by this initially. I spent some time debugging
> until I realized why unloading all the modules was causing the kernel to
> crash.
>
> The reason I took this approach was that I wanted to send out a working
> prototype for arm64 that wouldn't interfere with the existing, working
> implementation on x86.
>
> Following your suggestion, I can put together a preparatory patch series to
> refactor the set_direct_map_* APIs to accept a nr_pages parameter. This
There was a patch Nikita sent a while ago that does something similar:
https://lore.kernel.org/all/20260410151746.61150-2-kalyazin@amazon.com
I believe you can start from there.
> refactoring would also allow us to drop the redundant set_area_direct_map
We can't drop set_area_direct_map() because vmalloc pages might be not
physically contiguous.
> helper. I could then rebase the rox_cache series on top of that.
>
> Does this sound like a good path forward?
>
> Thanks,
> Adrian
--
Sincerely yours,
Mike.
^ permalink raw reply
* [PATCH] nvmem: rockchip-otp: initialize ret in rk3588_otp_read
From: Ruoyu Wang @ 2026-06-17 18:38 UTC (permalink / raw)
To: Srinivas Kandagatla, Heiko Stuebner, linux-arm-kernel,
linux-rockchip, linux-kernel
rk3588_otp_read() returns ret after a count-controlled loop. If count is
zero, the loop is skipped and ret is not assigned. Initialize ret to 0
for the empty read path.
Signed-off-by: Ruoyu Wang <ruoyuw560@gmail.com>
---
drivers/nvmem/rockchip-otp.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/nvmem/rockchip-otp.c b/drivers/nvmem/rockchip-otp.c
index 0ec78b5e19e7d..50a19b6dc4027 100644
--- a/drivers/nvmem/rockchip-otp.c
+++ b/drivers/nvmem/rockchip-otp.c
@@ -242,7 +242,7 @@ static int rk3588_otp_read(void *context, unsigned int offset,
{
struct rockchip_otp *otp = context;
u32 *buf = val;
- int ret;
+ int ret = 0;
while (count--) {
writel((offset++ << RK3588_ADDR_SHIFT) |
--
2.51.0
^ permalink raw reply related
* Re: [GIT PULL 4/4] soc: arm code changes for 7.2
From: pr-tracker-bot @ 2026-06-17 18:36 UTC (permalink / raw)
To: Arnd Bergmann
Cc: Linus Torvalds, soc, linux-arm-kernel, Krzysztof Kozlowski,
Linus Walleij, linux-kernel
In-Reply-To: <c00cadd6-b8ae-4d09-bcdf-adbeab2f0e11@app.fastmail.com>
The pull request you sent on Tue, 16 Jun 2026 09:55:00 +0200:
> https://git.kernel.org/pub/scm/linux/kernel/git/soc/soc.git tags/soc-arm-7.2
has been merged into torvalds/linux.git:
https://git.kernel.org/torvalds/c/6505114e82e7541414b176b5da4a3c015a1214ea
Thank you!
--
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/prtracker.html
^ permalink raw reply
* Re: [GIT PULL 2/4] soc: drivers for 7.2
From: pr-tracker-bot @ 2026-06-17 18:36 UTC (permalink / raw)
To: Arnd Bergmann
Cc: Linus Torvalds, soc, linux-arm-kernel, Krzysztof Kozlowski,
Linus Walleij, Marek Vasut, linux-kernel
In-Reply-To: <528465a7-4ffb-45ed-82e4-898b01d2da98@app.fastmail.com>
The pull request you sent on Tue, 16 Jun 2026 09:53:00 +0200:
> https://git.kernel.org/pub/scm/linux/kernel/git/soc/soc.git tags/soc-drivers-7.2
has been merged into torvalds/linux.git:
https://git.kernel.org/torvalds/c/70cb95c736807da2c4952423c9f9afe470341996
Thank you!
--
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/prtracker.html
^ permalink raw reply
* Re: [GIT PULL 0/4] soc: defconfig updates for 7.2
From: pr-tracker-bot @ 2026-06-17 18:36 UTC (permalink / raw)
To: Arnd Bergmann
Cc: Linus Torvalds, soc, linux-arm-kernel, Krzysztof Kozlowski,
Linus Walleij, linux-kernel
In-Reply-To: <287ca074-9329-4a51-a5f7-35abc0d977f7@app.fastmail.com>
The pull request you sent on Tue, 16 Jun 2026 09:53:53 +0200:
> https://git.kernel.org/pub/scm/linux/kernel/git/soc/soc.git tags/soc-defconfig-7.2
has been merged into torvalds/linux.git:
https://git.kernel.org/torvalds/c/61cf9588108762323c4c186f94a0c6e7ce5cb9f6
Thank you!
--
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/prtracker.html
^ permalink raw reply
* Re: [GIT PULL 1/4] soc: devicetree updates for 7.2
From: pr-tracker-bot @ 2026-06-17 18:36 UTC (permalink / raw)
To: Arnd Bergmann
Cc: Linus Torvalds, soc, linux-arm-kernel, Krzysztof Kozlowski,
Linus Walleij, linux-kernel
In-Reply-To: <ef5fa237-1d2f-4c1d-8940-0e8c6c156759@app.fastmail.com>
The pull request you sent on Tue, 16 Jun 2026 09:51:35 +0200:
> https://git.kernel.org/pub/scm/linux/kernel/git/soc/soc.git tags/soc-dt-7.2
has been merged into torvalds/linux.git:
https://git.kernel.org/torvalds/c/aab799b1bdd1ff3e6912f96e66c910b8a5d011bb
Thank you!
--
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/prtracker.html
^ permalink raw reply
* [PATCH] memory: stm32_omm: initialize ret in stm32_omm_set_amcr
From: Ruoyu Wang @ 2026-06-17 18:22 UTC (permalink / raw)
To: Patrice Chotard, Krzysztof Kozlowski, Maxime Coquelin,
Alexandre Torgue, linux-kernel, linux-stm32, linux-arm-kernel
stm32_omm_set_amcr() returns ret after checking whether the AMCR value
matches the device tree description. On the normal matching path ret is
not otherwise assigned, so initialize it to 0 before the checks.
Signed-off-by: Ruoyu Wang <ruoyuw560@gmail.com>
---
drivers/memory/stm32_omm.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/memory/stm32_omm.c b/drivers/memory/stm32_omm.c
index 5d06623f3f689..2a1af229d2444 100644
--- a/drivers/memory/stm32_omm.c
+++ b/drivers/memory/stm32_omm.c
@@ -47,7 +47,7 @@ static int stm32_omm_set_amcr(struct device *dev, bool set)
struct device_node *node;
struct resource res, res1;
unsigned int syscon_args[2];
- int ret, idx;
+ int ret = 0, idx;
unsigned int i, amcr, read_amcr;
for (i = 0; i < omm->nb_child; i++) {
--
2.51.0
^ permalink raw reply related
* [PATCH v2 4/5] media: hantro: add per-context fdinfo usage stats
From: Detlev Casanova @ 2026-06-17 18:10 UTC (permalink / raw)
To: Mauro Carvalho Chehab, Nicolas Dufresne, Benjamin Gaignard,
Philipp Zabel, Ezequiel Garcia, Heiko Stuebner
Cc: linux-media, linux-kernel, linux-rockchip, kernel,
Detlev Casanova, linux-arm-kernel, Christopher Healy
In-Reply-To: <20260617-v4l2-add-fdinfo-v2-0-d298e98ce06a@collabora.com>
From: Christopher Healy <healych@amazon.com>
Add per-file-descriptor hardware utilization tracking to the Hantro
VPU stateless codec driver, exposed via v4l2_stats.
Update the v4l2_stats instance each time a job completes with the
time it took in ns.
This enables userspace monitoring tools to compute per-process decoder
and encoder utilization. The current and max frequency keys report the
same value today since the driver lacks devfreq support, but will
diverge once DVFS is added, allowing userspace to approximate true
capacity utilization without any fdinfo code changes. A future series
can add hardware cycle counter support (via media-cycles) to v4l2_stats
for exact utilization under DVFS, with no changes to the existing uAPI.
Signed-off-by: Christopher Healy <healych@amazon.com>
Signed-off-by: Detlev Casanova <detlev.casanova@collabora.com>
---
drivers/media/platform/verisilicon/hantro.h | 3 +++
drivers/media/platform/verisilicon/hantro_drv.c | 19 +++++++++++++++++++
2 files changed, 22 insertions(+)
diff --git a/drivers/media/platform/verisilicon/hantro.h b/drivers/media/platform/verisilicon/hantro.h
index 0353de154a1e..37fd13cc7afa 100644
--- a/drivers/media/platform/verisilicon/hantro.h
+++ b/drivers/media/platform/verisilicon/hantro.h
@@ -16,6 +16,7 @@
#include <linux/videodev2.h>
#include <linux/wait.h>
#include <linux/clk.h>
+#include <linux/ktime.h>
#include <linux/reset.h>
#include <media/v4l2-ctrls.h>
@@ -268,6 +269,8 @@ struct hantro_ctx {
struct hantro_postproc_ctx postproc;
bool need_postproc;
+ ktime_t start_time;
+
/* Specific for particular codec modes. */
union {
struct hantro_h264_dec_hw_ctx h264_dec;
diff --git a/drivers/media/platform/verisilicon/hantro_drv.c b/drivers/media/platform/verisilicon/hantro_drv.c
index 2e81877f640f..3b837ef0f3bc 100644
--- a/drivers/media/platform/verisilicon/hantro_drv.c
+++ b/drivers/media/platform/verisilicon/hantro_drv.c
@@ -21,6 +21,7 @@
#include <linux/videodev2.h>
#include <linux/workqueue.h>
#include <media/v4l2-event.h>
+#include <media/v4l2-stats.h>
#include <media/v4l2-mem2mem.h>
#include <media/videobuf2-core.h>
#include <media/videobuf2-vmalloc.h>
@@ -90,6 +91,9 @@ static void hantro_job_finish(struct hantro_dev *vpu,
struct hantro_ctx *ctx,
enum vb2_buffer_state result)
{
+ v4l2_stats_update_hw_usage(&ctx->fh.stats,
+ ktime_to_ns(ktime_sub(ktime_get(), ctx->start_time)));
+
pm_runtime_put_autosuspend(vpu->dev);
clk_bulk_disable(vpu->variant->num_clocks, vpu->clocks);
@@ -186,6 +190,8 @@ static void device_run(void *priv)
v4l2_m2m_buf_copy_metadata(src, dst);
+ ctx->start_time = ktime_get();
+
if (ctx->codec_ops->run(ctx))
goto err_cancel_job;
@@ -664,6 +670,9 @@ static int hantro_open(struct file *filp)
v4l2_fh_init(&ctx->fh, vdev);
v4l2_fh_add(&ctx->fh, filp);
+ v4l2_stats_set_media_dev_type(&ctx->fh.stats,
+ ctx->is_encoder ? MEDIA_DEV_TYPE_V4L2_STATELESS_ENCODER
+ : MEDIA_DEV_TYPE_V4L2_STATELESS_DECODER);
hantro_reset_fmts(ctx);
@@ -701,10 +710,20 @@ static int hantro_release(struct file *filp)
return 0;
}
+static void hantro_show_fdinfo(struct seq_file *m, struct file *f)
+{
+ struct hantro_ctx *ctx = file_to_ctx(f);
+ struct hantro_dev *vpu = ctx->dev;
+
+ v4l2_stats_show(&ctx->fh.stats, m);
+ v4l2_stats_show_clock(m, vpu->clocks[0].clk);
+}
+
static const struct v4l2_file_operations hantro_fops = {
.owner = THIS_MODULE,
.open = hantro_open,
.release = hantro_release,
+ .show_fdinfo = hantro_show_fdinfo,
.poll = v4l2_m2m_fop_poll,
.unlocked_ioctl = video_ioctl2,
.mmap = v4l2_m2m_fop_mmap,
--
2.54.0
^ permalink raw reply related
* [PATCH v2 5/5] media: rkvdec: Add per-context fdinfo usage stats
From: Detlev Casanova @ 2026-06-17 18:11 UTC (permalink / raw)
To: Mauro Carvalho Chehab, Nicolas Dufresne, Benjamin Gaignard,
Philipp Zabel, Ezequiel Garcia, Heiko Stuebner
Cc: linux-media, linux-kernel, linux-rockchip, kernel,
Detlev Casanova, linux-arm-kernel
In-Reply-To: <20260617-v4l2-add-fdinfo-v2-0-d298e98ce06a@collabora.com>
Add per-file-descriptor hardware utilization tracking to the rkvdec
stateless codec driver, exposed via v4l2_stats.
Update the v4l2_stats instance each time a job completes with the
time it took in ns.
This enables userspace monitoring tools to compute per-process decoder
and encoder utilization. The current and max frequency keys report the
same value today since the driver lacks devfreq support, but will
diverge once DVFS is added, allowing userspace to approximate true
capacity utilization without any fdinfo code changes. A future series
can add hardware cycle counter support (via media-cycles) to v4l2_stats
for exact utilization under DVFS, with no changes to the existing uAPI.
Signed-off-by: Detlev Casanova <detlev.casanova@collabora.com>
---
drivers/media/platform/rockchip/rkvdec/rkvdec.c | 19 +++++++++++++++++++
drivers/media/platform/rockchip/rkvdec/rkvdec.h | 1 +
2 files changed, 20 insertions(+)
diff --git a/drivers/media/platform/rockchip/rkvdec/rkvdec.c b/drivers/media/platform/rockchip/rkvdec/rkvdec.c
index 1d1e9bfef8e9..929171232ccf 100644
--- a/drivers/media/platform/rockchip/rkvdec/rkvdec.c
+++ b/drivers/media/platform/rockchip/rkvdec/rkvdec.c
@@ -25,6 +25,7 @@
#include <linux/workqueue.h>
#include <media/v4l2-event.h>
#include <media/v4l2-mem2mem.h>
+#include <media/v4l2-stats.h>
#include <media/videobuf2-core.h>
#include <media/videobuf2-vmalloc.h>
@@ -1094,6 +1095,9 @@ static void rkvdec_job_finish(struct rkvdec_ctx *ctx,
{
struct rkvdec_dev *rkvdec = ctx->dev;
+ v4l2_stats_update_hw_usage(&ctx->fh.stats,
+ ktime_to_ns(ktime_sub(ktime_get(), ctx->start_time)));
+
pm_runtime_put_autosuspend(rkvdec->dev);
rkvdec_job_finish_no_pm(ctx, result);
}
@@ -1174,6 +1178,8 @@ static void rkvdec_device_run(void *priv)
return;
}
+ ctx->start_time = ktime_get();
+
ret = desc->ops->run(ctx);
if (ret)
rkvdec_job_finish(ctx, VB2_BUF_STATE_ERROR);
@@ -1304,6 +1310,8 @@ static int rkvdec_open(struct file *filp)
v4l2_fh_add(&ctx->fh, filp);
+ v4l2_stats_set_media_dev_type(&ctx->fh.stats, MEDIA_DEV_TYPE_V4L2_STATELESS_DECODER);
+
return 0;
err_cleanup_m2m_ctx:
@@ -1327,10 +1335,21 @@ static int rkvdec_release(struct file *filp)
return 0;
}
+static void rkvdec_show_fdinfo(struct seq_file *m, struct file *file)
+{
+ struct rkvdec_ctx *ctx = file_to_rkvdec_ctx(file);
+ struct rkvdec_dev *rkvdec = ctx->dev;
+
+ v4l2_stats_show(&ctx->fh.stats, m);
+
+ v4l2_stats_show_clock(m, rkvdec->axi_clk);
+}
+
static const struct v4l2_file_operations rkvdec_fops = {
.owner = THIS_MODULE,
.open = rkvdec_open,
.release = rkvdec_release,
+ .show_fdinfo = rkvdec_show_fdinfo,
.poll = v4l2_m2m_fop_poll,
.unlocked_ioctl = video_ioctl2,
.mmap = v4l2_m2m_fop_mmap,
diff --git a/drivers/media/platform/rockchip/rkvdec/rkvdec.h b/drivers/media/platform/rockchip/rkvdec/rkvdec.h
index a24be6638b6b..590e213bd800 100644
--- a/drivers/media/platform/rockchip/rkvdec/rkvdec.h
+++ b/drivers/media/platform/rockchip/rkvdec/rkvdec.h
@@ -157,6 +157,7 @@ struct rkvdec_ctx {
void *priv;
u8 has_sps_st_rps: 1;
u8 has_sps_lt_rps: 1;
+ ktime_t start_time;
};
static inline struct rkvdec_ctx *file_to_rkvdec_ctx(struct file *filp)
--
2.54.0
^ permalink raw reply related
* [PATCH v2 3/5] media: v4l2-core: Add v4l2-stats interface
From: Detlev Casanova @ 2026-06-17 18:10 UTC (permalink / raw)
To: Mauro Carvalho Chehab, Nicolas Dufresne, Benjamin Gaignard,
Philipp Zabel, Ezequiel Garcia, Heiko Stuebner
Cc: linux-media, linux-kernel, linux-rockchip, kernel,
Detlev Casanova, linux-arm-kernel
In-Reply-To: <20260617-v4l2-add-fdinfo-v2-0-d298e98ce06a@collabora.com>
Provide helpers for media drivers to set fdinfo data and print the
key:value pairs in a standard way.
User drivers can set stats values with helpers like:
- v4l2_stats_update_hw_usage
- v4l2_stats_set_media_dev_type
And also call the show helpers from their show_fdinfo callback with:
- v4l2_stats_show -- Shows the values set previously
- v4l2_stats_show_clock -- Shows the main clock state.
The show_clock helper is used instead of updating a clock value in
v4l2_stats for the following reasons:
- Clocks are at the device level, this is not a per-fd information
- This avoids having clock references in v4l2-core
- Drivers can use different approaches to manage clocks
(e.g.: bulk_data or not: A set helper wouldn't please all drivers)
- Arguably, clocks could be exposed elsewhere (like a debugfs), but we
want something close to what DRM does and centralizing information has
its advantages for userspace tooling.
In DRM the key:value pair format for clocks is documented and each driver
can write them directly based on that.
In this case, provide a helper and document the format.
Signed-off-by: Detlev Casanova <detlev.casanova@collabora.com>
---
drivers/media/v4l2-core/Makefile | 2 +-
drivers/media/v4l2-core/v4l2-dev.c | 2 ++
drivers/media/v4l2-core/v4l2-fh.c | 3 ++
drivers/media/v4l2-core/v4l2-stats.c | 65 ++++++++++++++++++++++++++++++++++++
include/media/v4l2-fh.h | 2 ++
include/media/v4l2-stats.h | 44 ++++++++++++++++++++++++
6 files changed, 117 insertions(+), 1 deletion(-)
diff --git a/drivers/media/v4l2-core/Makefile b/drivers/media/v4l2-core/Makefile
index 329f0eadce99..20e1ab74ac09 100644
--- a/drivers/media/v4l2-core/Makefile
+++ b/drivers/media/v4l2-core/Makefile
@@ -9,7 +9,7 @@ ccflags-y += -I$(srctree)/drivers/media/tuners
tuner-objs := tuner-core.o
videodev-objs := v4l2-dev.o v4l2-ioctl.o v4l2-device.o v4l2-fh.o \
- v4l2-event.o v4l2-subdev.o v4l2-common.o \
+ v4l2-event.o v4l2-subdev.o v4l2-common.o v4l2-stats.o \
v4l2-ctrls-core.o v4l2-ctrls-api.o \
v4l2-ctrls-request.o v4l2-ctrls-defs.o
diff --git a/drivers/media/v4l2-core/v4l2-dev.c b/drivers/media/v4l2-core/v4l2-dev.c
index 3878fa2ff73e..3e7a6876dffd 100644
--- a/drivers/media/v4l2-core/v4l2-dev.c
+++ b/drivers/media/v4l2-core/v4l2-dev.c
@@ -486,6 +486,8 @@ static void v4l2_show_fdinfo(struct seq_file *m, struct file *filp)
{
struct video_device *vdev = video_devdata(filp);
+ seq_printf(m, "media-driver:\t%s\n", vdev->v4l2_dev->name);
+
if (vdev->fops->show_fdinfo)
vdev->fops->show_fdinfo(m, filp);
}
diff --git a/drivers/media/v4l2-core/v4l2-fh.c b/drivers/media/v4l2-core/v4l2-fh.c
index b184bed8aca9..1b655672c718 100644
--- a/drivers/media/v4l2-core/v4l2-fh.c
+++ b/drivers/media/v4l2-core/v4l2-fh.c
@@ -17,6 +17,7 @@
#include <media/v4l2-event.h>
#include <media/v4l2-ioctl.h>
#include <media/v4l2-mc.h>
+#include <media/v4l2-stats.h>
void v4l2_fh_init(struct v4l2_fh *fh, struct video_device *vdev)
{
@@ -38,6 +39,7 @@ void v4l2_fh_init(struct v4l2_fh *fh, struct video_device *vdev)
INIT_LIST_HEAD(&fh->subscribed);
fh->sequence = -1;
mutex_init(&fh->subscribe_lock);
+ v4l2_stats_init(&fh->stats);
}
EXPORT_SYMBOL_GPL(v4l2_fh_init);
@@ -88,6 +90,7 @@ void v4l2_fh_exit(struct v4l2_fh *fh)
v4l2_event_unsubscribe_all(fh);
mutex_destroy(&fh->subscribe_lock);
fh->vdev = NULL;
+ v4l2_stats_exit(&fh->stats);
}
EXPORT_SYMBOL_GPL(v4l2_fh_exit);
diff --git a/drivers/media/v4l2-core/v4l2-stats.c b/drivers/media/v4l2-core/v4l2-stats.c
new file mode 100644
index 000000000000..93e64ef2e7bb
--- /dev/null
+++ b/drivers/media/v4l2-core/v4l2-stats.c
@@ -0,0 +1,65 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * v4l2-stats.c
+ *
+ * V4L2 statistics management.
+ *
+ * Maintain a per-file handle list of statistics about the hardware and handle
+ * exposing it in the fdinfo.
+ *
+ * Copyright (C) 2026 Collabora.
+ *
+ * Contact: Detlev Casanova <detlev.casanova@collabora.com>
+ */
+
+#include <linux/types.h>
+#include <linux/seq_file.h>
+#include <linux/clk.h>
+#include <media/v4l2-stats.h>
+
+static const char * const dev_type_name[] = {
+ [MEDIA_DEV_TYPE_V4L2] = "media",
+ [MEDIA_DEV_TYPE_V4L2_STATELESS_ENCODER] = "encoder",
+ [MEDIA_DEV_TYPE_V4L2_STATELESS_DECODER] = "decoder",
+};
+
+void v4l2_stats_init(struct v4l2_stats *stats)
+{
+ stats->hw_usage_time = 0;
+ stats->media_dev_type = MEDIA_DEV_TYPE_V4L2;
+}
+
+void v4l2_stats_exit(struct v4l2_stats *stats)
+{
+}
+
+void v4l2_stats_update_hw_usage(struct v4l2_stats *stats, u64 usage_time)
+{
+ stats->hw_usage_time += usage_time;
+}
+EXPORT_SYMBOL_GPL(v4l2_stats_update_hw_usage);
+
+void v4l2_stats_set_media_dev_type(struct v4l2_stats *stats, enum v4l2_media_dev_type type)
+{
+ if (type >= MEDIA_DEV_TYPE_COUNT)
+ return;
+
+ stats->media_dev_type = type;
+}
+EXPORT_SYMBOL_GPL(v4l2_stats_set_media_dev_type);
+
+void v4l2_stats_show(struct v4l2_stats *stats, struct seq_file *m)
+{
+ seq_printf(m, "media-type:\t%s\n", dev_type_name[stats->media_dev_type]);
+ seq_printf(m, "media-engine-usage:\t%llu ns\n", stats->hw_usage_time);
+}
+EXPORT_SYMBOL_GPL(v4l2_stats_show);
+
+void v4l2_stats_show_clock(struct seq_file *m, struct clk *clk)
+{
+ seq_printf(m, "media-maxfreq:\t%lu Hz\n",
+ clk_get_rate(clk));
+ seq_printf(m, "media-curfreq:\t%lu Hz\n",
+ clk_get_rate(clk));
+}
+EXPORT_SYMBOL_GPL(v4l2_stats_show_clock);
diff --git a/include/media/v4l2-fh.h b/include/media/v4l2-fh.h
index aad4b3689d7e..ae6688722bee 100644
--- a/include/media/v4l2-fh.h
+++ b/include/media/v4l2-fh.h
@@ -17,6 +17,7 @@
#include <linux/kconfig.h>
#include <linux/list.h>
#include <linux/videodev2.h>
+#include <media/v4l2-stats.h>
struct video_device;
struct v4l2_ctrl_handler;
@@ -43,6 +44,7 @@ struct v4l2_fh {
struct list_head list;
struct video_device *vdev;
struct v4l2_ctrl_handler *ctrl_handler;
+ struct v4l2_stats stats;
enum v4l2_priority prio;
/* Events */
diff --git a/include/media/v4l2-stats.h b/include/media/v4l2-stats.h
new file mode 100644
index 000000000000..d580933c4181
--- /dev/null
+++ b/include/media/v4l2-stats.h
@@ -0,0 +1,44 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * v4l2-stats.h
+ *
+ * V4L2 statistics management.
+ *
+ * Maintain a per-file handle list of statistics about the hardware and handle
+ * exposing it in the fdinfo.
+ *
+ * Copyright (C) 2026 Collabora.
+ *
+ * Contact: Detlev Casanova <detlev.casanova@collabora.com>
+ */
+#ifndef V4L2_STATS_H
+#define V4L2_STATS_H
+
+#include <linux/types.h>
+
+struct clk;
+struct seq_file;
+
+enum v4l2_media_dev_type {
+ MEDIA_DEV_TYPE_V4L2 = 0,
+ MEDIA_DEV_TYPE_V4L2_STATELESS_ENCODER,
+ MEDIA_DEV_TYPE_V4L2_STATELESS_DECODER,
+
+ MEDIA_DEV_TYPE_COUNT,
+};
+
+struct v4l2_stats {
+ u64 hw_usage_time;
+ enum v4l2_media_dev_type media_dev_type;
+};
+
+void v4l2_stats_init(struct v4l2_stats *stats);
+void v4l2_stats_exit(struct v4l2_stats *stats);
+
+void v4l2_stats_update_hw_usage(struct v4l2_stats *stats, u64 usage_time);
+void v4l2_stats_set_media_dev_type(struct v4l2_stats *stats, enum v4l2_media_dev_type type);
+
+void v4l2_stats_show(struct v4l2_stats *stats, struct seq_file *m);
+void v4l2_stats_show_clock(struct seq_file *m, struct clk *clk);
+
+#endif /* V4L2_STATS_H */
--
2.54.0
^ permalink raw reply related
* [PATCH v2 0/5] media: Add fdinfo support for v4l2 drivers
From: Detlev Casanova @ 2026-06-17 18:10 UTC (permalink / raw)
To: Mauro Carvalho Chehab, Nicolas Dufresne, Benjamin Gaignard,
Philipp Zabel, Ezequiel Garcia, Heiko Stuebner
Cc: linux-media, linux-kernel, linux-rockchip, kernel,
Detlev Casanova, linux-arm-kernel, Christopher Healy
fdinfo is useful to poll information from the driver.
Unlike the ftrace interface, it lets userspace tools get a snapshot of
the state of the driver at their own pace, instead of getting events for
each driver status change.
This works better to get information like HW usage time or clock
frequencies, as well as memory usage.
This patch set focuses on mem2mem drivers that are per-frame based and
an implementation is proposed for the Verisilicon Hantro and Rockchip
rkvdec drivers, limited to main clock frequency and HW usage time.
To ease support in drivers, a v4l2_stats struct is added.
It stores statistics information and provides helper functions to write
the fdinfo file in a standard way.
An example of usage of this from userspace is implemented in v4l2top:
https://github.com/cazou/v4l2top (Check the upstream branch)
checkpatch.pl warning: The 2 arguments in the show_fdinfo callback
definition are kept unnamed to match with the rest of the struct
definition.
Signed-off-by: Detlev Casanova <detlev.casanova@collabora.com>
---
Changes in v2:
- Simplify key/value pairs by removing repeated <eng> suffix
- Add media type support
- Add v4l2_stats helpers
- Add support in rkvdec too
- Link to v1: https://patch.msgid.link/20260612-v4l2-add-fdinfo-v1-0-723211abc861@collabora.com
To: Mauro Carvalho Chehab <mchehab@kernel.org>
To: Nicolas Dufresne <nicolas.dufresne@collabora.com>
To: Benjamin Gaignard <benjamin.gaignard@collabora.com>
To: Philipp Zabel <p.zabel@pengutronix.de>
To: Detlev Casanova <detlev.casanova@collabora.com>
To: Ezequiel Garcia <ezequiel@vanguardiasur.com.ar>
To: Heiko Stuebner <heiko@sntech.de>
Cc: kernel@collabora.com
Cc: linux-media@vger.kernel.org
Cc: linux-kernel@vger.kernel.org
Cc: linux-rockchip@lists.infradead.org
Cc: linux-arm-kernel@lists.infradead.org
---
Christopher Healy (2):
docs: media: add documentation for media client usage stats
media: hantro: add per-context fdinfo usage stats
Detlev Casanova (3):
media: v4l2: Add callback for show_fdinfo
media: v4l2-core: Add v4l2-stats interface
media: rkvdec: Add per-context fdinfo usage stats
.../userspace-api/media/drivers/index.rst | 1 +
.../media/drivers/media-usage-stats.rst | 85 ++++++++++++++++++++++
drivers/media/platform/rockchip/rkvdec/rkvdec.c | 19 +++++
drivers/media/platform/rockchip/rkvdec/rkvdec.h | 1 +
drivers/media/platform/verisilicon/hantro.h | 3 +
drivers/media/platform/verisilicon/hantro_drv.c | 19 +++++
drivers/media/v4l2-core/Makefile | 2 +-
drivers/media/v4l2-core/v4l2-dev.c | 12 +++
drivers/media/v4l2-core/v4l2-fh.c | 3 +
drivers/media/v4l2-core/v4l2-stats.c | 65 +++++++++++++++++
include/media/v4l2-dev.h | 1 +
include/media/v4l2-fh.h | 2 +
include/media/v4l2-stats.h | 44 +++++++++++
13 files changed, 256 insertions(+), 1 deletion(-)
---
base-commit: 66affa37cfac0aec061cc4bcf4a065b0c52f7e19
change-id: 20260610-v4l2-add-fdinfo-a790fceab329
Best regards,
--
Detlev Casanova <detlev.casanova@collabora.com>
^ permalink raw reply
* [PATCH v2 2/5] docs: media: add documentation for media client usage stats
From: Detlev Casanova @ 2026-06-17 18:10 UTC (permalink / raw)
To: Mauro Carvalho Chehab, Nicolas Dufresne, Benjamin Gaignard,
Philipp Zabel, Ezequiel Garcia, Heiko Stuebner
Cc: linux-media, linux-kernel, linux-rockchip, kernel,
Detlev Casanova, linux-arm-kernel, Christopher Healy
In-Reply-To: <20260617-v4l2-add-fdinfo-v2-0-d298e98ce06a@collabora.com>
From: Christopher Healy <healych@amazon.com>
Document the media fdinfo interface for per-file-descriptor usage
statistics exposed by stateless V4L2 codec drivers via
/proc/<pid>/fdinfo/<fd>.
This interface is designed for stateless (request API based) codec
devices where the kernel driver has per-job visibility into hardware
execution. Stateful codecs cannot support all of this because their
firmware manages job scheduling opaquely.
The specification defines media- prefixed keys for engine utilization
time, and operating frequency, following the same conventions as the DRM
fdinfo mechanism documented in drm-usage-stats.rst.
More fields can be added later.
Signed-off-by: Christopher Healy <healych@amazon.com>
Signed-off-by: Detlev Casanova <detlev.casanova@collabora.com>
---
.../userspace-api/media/drivers/index.rst | 1 +
.../media/drivers/media-usage-stats.rst | 85 ++++++++++++++++++++++
2 files changed, 86 insertions(+)
diff --git a/Documentation/userspace-api/media/drivers/index.rst b/Documentation/userspace-api/media/drivers/index.rst
index 02967c9b18d6..61879738836c 100644
--- a/Documentation/userspace-api/media/drivers/index.rst
+++ b/Documentation/userspace-api/media/drivers/index.rst
@@ -34,6 +34,7 @@ For more details see the file COPYING in the source distribution of Linux.
imx-uapi
mali-c55
max2175
+ media-usage-stats
npcm-video
omap3isp-uapi
thp7312
diff --git a/Documentation/userspace-api/media/drivers/media-usage-stats.rst b/Documentation/userspace-api/media/drivers/media-usage-stats.rst
new file mode 100644
index 000000000000..d3dc07002f62
--- /dev/null
+++ b/Documentation/userspace-api/media/drivers/media-usage-stats.rst
@@ -0,0 +1,85 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+.. _media-usage-stats:
+
+==========================
+Media client usage stats
+==========================
+
+Stateless V4L2 codec drivers can optionally expose per-file-descriptor usage
+statistics via ``/proc/<pid>/fdinfo/<fd>``. This is analogous to the DRM fdinfo
+mechanism documented in :ref:`drm-client-usage-stats`, but uses the ``media-``
+key prefix for V4L2 media devices.
+
+This interface is specific to stateless (request API based) codec devices,
+including both decoders and encoders. With stateless codecs, the kernel driver
+explicitly submits each frame to the hardware and receives a completion
+interrupt, providing a clean per-job boundary that can be attributed to the
+submitting file descriptor.
+
+Stateful codec devices cannot support this interface because their firmware
+manages job scheduling internally. The kernel driver submits bitstream data
+but has no visibility into per-frame hardware execution timing.
+
+Implementation
+==============
+
+The V4L2 core provides the plumbing: drivers implement the ``show_fdinfo``
+callback in ``struct v4l2_file_operations``, and the core wires it into the
+kernel ``struct file_operations`` so that ``/proc/<pid>/fdinfo/<fd>`` output
+includes the driver-provided keys.
+
+File format specification
+=========================
+
+- File shall contain one key value pair per one line of text.
+- Colon character (``:``) must be used to delimit keys and values.
+- All standardised keys shall be prefixed with ``media-``.
+- Driver-specific keys shall be prefixed with ``driver_name-``.
+
+Mandatory keys
+--------------
+
+- media-driver: <valstr>
+
+ String shall contain the name of the media driver.
+
+- media-type: <valstr>
+
+ String shall identify the type of media engine exposed through this file
+ descriptor. Standard values are ``decoder`` and ``encoder``.
+
+Utilization keys
+----------------
+
+- media-engine-usage: <uint> ns
+
+ Time in nanoseconds that the hardware engine spent busy processing work
+ belonging to this file descriptor. The engine being measured is identified
+ by the ``media-type`` key.
+
+ Values are not required to be constantly monotonic if it makes the driver
+ implementation easier, but are required to catch up with the previously
+ reported larger value within a reasonable period.
+
+Frequency keys
+--------------
+
+- media-maxfreq: <uint> Hz
+
+ Maximum operating frequency of the main engine clock.
+
+- media-curfreq: <uint> Hz
+
+ Current operating frequency of the main engine clock.
+
+Example output
+==============
+
+::
+
+ media-driver: hantro-vpu
+ media-type: decoder
+ media-engine-usage: 123456789 ns
+ media-maxfreq: 600000000 Hz
+ media-curfreq: 600000000 Hz
--
2.54.0
^ permalink raw reply related
* [PATCH v2 1/5] media: v4l2: Add callback for show_fdinfo
From: Detlev Casanova @ 2026-06-17 18:10 UTC (permalink / raw)
To: Mauro Carvalho Chehab, Nicolas Dufresne, Benjamin Gaignard,
Philipp Zabel, Ezequiel Garcia, Heiko Stuebner
Cc: linux-media, linux-kernel, linux-rockchip, kernel,
Detlev Casanova, linux-arm-kernel
In-Reply-To: <20260617-v4l2-add-fdinfo-v2-0-d298e98ce06a@collabora.com>
Allow v4l2 drivers to add information in the fdinfo file matching the
opened /dev/videoX file.
Signed-off-by: Detlev Casanova <detlev.casanova@collabora.com>
---
drivers/media/v4l2-core/v4l2-dev.c | 10 ++++++++++
include/media/v4l2-dev.h | 1 +
2 files changed, 11 insertions(+)
diff --git a/drivers/media/v4l2-core/v4l2-dev.c b/drivers/media/v4l2-core/v4l2-dev.c
index 6ce623a1245a..3878fa2ff73e 100644
--- a/drivers/media/v4l2-core/v4l2-dev.c
+++ b/drivers/media/v4l2-core/v4l2-dev.c
@@ -481,6 +481,15 @@ static int v4l2_release(struct inode *inode, struct file *filp)
return ret;
}
+/* Override for the show_fdinfo function */
+static void v4l2_show_fdinfo(struct seq_file *m, struct file *filp)
+{
+ struct video_device *vdev = video_devdata(filp);
+
+ if (vdev->fops->show_fdinfo)
+ vdev->fops->show_fdinfo(m, filp);
+}
+
static const struct file_operations v4l2_fops = {
.owner = THIS_MODULE,
.read = v4l2_read,
@@ -494,6 +503,7 @@ static const struct file_operations v4l2_fops = {
#endif
.release = v4l2_release,
.poll = v4l2_poll,
+ .show_fdinfo = v4l2_show_fdinfo,
};
/**
diff --git a/include/media/v4l2-dev.h b/include/media/v4l2-dev.h
index 2e0f6d2e6a78..1635ab186f21 100644
--- a/include/media/v4l2-dev.h
+++ b/include/media/v4l2-dev.h
@@ -212,6 +212,7 @@ struct v4l2_file_operations {
int (*mmap) (struct file *, struct vm_area_struct *);
int (*open) (struct file *);
int (*release) (struct file *);
+ void (*show_fdinfo)(struct seq_file *, struct file *);
};
/*
--
2.54.0
^ permalink raw reply related
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