* [PATCH v2 0/2] clk: samsung: exynos990: Fix PERIS gate clock parents and add TMU_SUB
From: Denzeel Oliva @ 2026-06-13 5:19 UTC (permalink / raw)
To: Krzysztof Kozlowski, Sylwester Nawrocki, Chanwoo Choi,
Peter Griffin, Alim Akhtar, Michael Turquette, Stephen Boyd,
Brian Masney, Rob Herring, Conor Dooley
Cc: linux-samsung-soc, linux-clk, devicetree, linux-arm-kernel,
linux-kernel, Denzeel Oliva
Fix PERIS CMU gate clock parent mismatches and add the missing
TMU_SUB_PCLK clock.
Split into dt-bindings (clock ID) and driver (parent fixes) as
required by checkpatch.
Changes in v2:
- Split dt-bindings header change into separate patch (1/2)
- Driver fix now only touches clk-exynos990.c (2/2)
- Add proper cover letter
v1: TODO-add-lore-link
Signed-off-by: Denzeel Oliva <wachiturroxd150@gmail.com>
---
Denzeel Oliva (2):
dt-bindings: clock: exynos990: Add CLK_GOUT_PERIS_TMU_SUB_PCLK
clk: samsung: exynos990: Fix PERIS gate clock parents
drivers/clk/samsung/clk-exynos990.c | 24 ++++++++++++++----------
include/dt-bindings/clock/samsung,exynos990.h | 1 +
2 files changed, 15 insertions(+), 10 deletions(-)
---
base-commit: c425609d6ac4012c8bbf01ec2e10e801b1923a7b
change-id: 20260613-exynos990-peris-fix-v2-619c3a30b36c
Best regards,
--
Denzeel Oliva <wachiturroxd150@gmail.com>
^ permalink raw reply
* [PATCH v2 1/2] dt-bindings: clock: exynos990: Add CLK_GOUT_PERIS_TMU_SUB_PCLK
From: Denzeel Oliva @ 2026-06-13 5:19 UTC (permalink / raw)
To: Krzysztof Kozlowski, Sylwester Nawrocki, Chanwoo Choi,
Peter Griffin, Alim Akhtar, Michael Turquette, Stephen Boyd,
Brian Masney, Rob Herring, Conor Dooley
Cc: linux-samsung-soc, linux-clk, devicetree, linux-arm-kernel,
linux-kernel, Denzeel Oliva
In-Reply-To: <20260613-exynos990-peris-fix-v2-v2-0-3dff7ade75b3@gmail.com>
Add the missing TMU_SUB_PCLK clock ID for the Exynos990 PERIS CMU.
Signed-off-by: Denzeel Oliva <wachiturroxd150@gmail.com>
---
include/dt-bindings/clock/samsung,exynos990.h | 1 +
1 file changed, 1 insertion(+)
diff --git a/include/dt-bindings/clock/samsung,exynos990.h b/include/dt-bindings/clock/samsung,exynos990.h
index 47540307cb52..c06f591d9d90 100644
--- a/include/dt-bindings/clock/samsung,exynos990.h
+++ b/include/dt-bindings/clock/samsung,exynos990.h
@@ -434,5 +434,6 @@
#define CLK_GOUT_PERIS_TMU_TOP_PCLK 17
#define CLK_GOUT_PERIS_OTP_CON_BIRA_OSCCLK 18
#define CLK_GOUT_PERIS_OTP_CON_TOP_OSCCLK 19
+#define CLK_GOUT_PERIS_TMU_SUB_PCLK 20
#endif
--
2.54.0
^ permalink raw reply related
* [PATCH v2 2/2] clk: samsung: exynos990: Fix PERIS gate clock parents
From: Denzeel Oliva @ 2026-06-13 5:19 UTC (permalink / raw)
To: Krzysztof Kozlowski, Sylwester Nawrocki, Chanwoo Choi,
Peter Griffin, Alim Akhtar, Michael Turquette, Stephen Boyd,
Brian Masney, Rob Herring, Conor Dooley
Cc: linux-samsung-soc, linux-clk, devicetree, linux-arm-kernel,
linux-kernel, Denzeel Oliva
In-Reply-To: <20260613-exynos990-peris-fix-v2-v2-0-3dff7ade75b3@gmail.com>
Correct eight PERIS gate clock parents to match the hardware clock
tree, reorder the GIC mux parents, and add the missing TMU_SUB_PCLK
gate.
Signed-off-by: Denzeel Oliva <wachiturroxd150@gmail.com>
---
drivers/clk/samsung/clk-exynos990.c | 24 ++++++++++++++----------
1 file changed, 14 insertions(+), 10 deletions(-)
diff --git a/drivers/clk/samsung/clk-exynos990.c b/drivers/clk/samsung/clk-exynos990.c
index 4385c3b76dd6..df5928833b23 100644
--- a/drivers/clk/samsung/clk-exynos990.c
+++ b/drivers/clk/samsung/clk-exynos990.c
@@ -21,7 +21,7 @@
#define CLKS_NR_HSI0 (CLK_GOUT_HSI0_LHS_ACEL_D_HSI0_CLK + 1)
#define CLKS_NR_PERIC0 (CLK_GOUT_PERIC0_SYSREG_PCLK + 1)
#define CLKS_NR_PERIC1 (CLK_GOUT_PERIC1_XIU_P_ACLK + 1)
-#define CLKS_NR_PERIS (CLK_GOUT_PERIS_OTP_CON_TOP_OSCCLK + 1)
+#define CLKS_NR_PERIS (CLK_GOUT_PERIS_TMU_SUB_PCLK + 1)
/* ---- CMU_TOP ------------------------------------------------------------- */
@@ -2551,7 +2551,7 @@ static const unsigned long peris_clk_regs[] __initconst = {
/* Parent clock list for CMU_PERIS muxes */
PNAME(mout_peris_bus_user_p) = { "oscclk", "mout_cmu_peris_bus" };
-PNAME(mout_peris_clk_peris_gic_p) = { "oscclk", "mout_peris_bus_user" };
+PNAME(mout_peris_clk_peris_gic_p) = { "mout_peris_bus_user", "oscclk" };
static const struct samsung_mux_clock peris_mux_clks[] __initconst = {
MUX(CLK_MOUT_PERIS_BUS_USER, "mout_peris_bus_user",
@@ -2584,15 +2584,15 @@ static const struct samsung_gate_clock peris_gate_clks[] __initconst = {
CLK_CON_GAT_GOUT_BLK_PERIS_UID_RSTNSYNC_CLK_PERIS_BUSP_IPCLKPORT_CLK,
21, 0, 0),
GATE(CLK_GOUT_PERIS_CLK_PERIS_OSCCLK_CLK,
- "gout_peris_clk_peris_oscclk_clk", "mout_peris_bus_user",
+ "gout_peris_clk_peris_oscclk_clk", "oscclk",
CLK_CON_GAT_CLK_BLK_PERIS_UID_RSTNSYNC_CLK_PERIS_OSCCLK_IPCLKPORT_CLK,
21, 0, 0),
GATE(CLK_GOUT_PERIS_CLK_PERIS_GIC_CLK,
- "gout_peris_clk_peris_gic_clk", "mout_peris_bus_user",
+ "gout_peris_clk_peris_gic_clk", "mout_peris_clk_peris_gic",
CLK_CON_GAT_GOUT_BLK_PERIS_UID_RSTNSYNC_CLK_PERIS_GIC_IPCLKPORT_CLK,
21, 0, 0),
GATE(CLK_GOUT_PERIS_AD_AXI_P_PERIS_ACLKM,
- "gout_peris_ad_axi_p_peris_aclkm", "mout_peris_bus_user",
+ "gout_peris_ad_axi_p_peris_aclkm", "mout_peris_clk_peris_gic",
CLK_CON_GAT_GOUT_BLK_PERIS_UID_AD_AXI_P_PERIS_IPCLKPORT_ACLKM,
21, CLK_IGNORE_UNUSED, 0),
GATE(CLK_GOUT_PERIS_OTP_CON_BIRA_PCLK,
@@ -2600,27 +2600,31 @@ static const struct samsung_gate_clock peris_gate_clks[] __initconst = {
CLK_CON_GAT_GOUT_BLK_PERIS_UID_OTP_CON_BIRA_IPCLKPORT_PCLK,
21, 0, 0),
GATE(CLK_GOUT_PERIS_GIC_CLK,
- "gout_peris_gic_clk", "mout_peris_bus_user",
+ "gout_peris_gic_clk", "mout_peris_clk_peris_gic",
CLK_CON_GAT_GOUT_BLK_PERIS_UID_GIC_IPCLKPORT_CLK,
21, CLK_IS_CRITICAL, 0),
GATE(CLK_GOUT_PERIS_LHM_AXI_P_PERIS_CLK,
- "gout_peris_lhm_axi_p_peris_clk", "oscclk",
+ "gout_peris_lhm_axi_p_peris_clk", "mout_peris_bus_user",
CLK_CON_GAT_GOUT_BLK_PERIS_UID_LHM_AXI_P_PERIS_IPCLKPORT_I_CLK,
21, CLK_IGNORE_UNUSED, 0),
GATE(CLK_GOUT_PERIS_MCT_PCLK,
- "gout_peris_mct_pclk", "mout_peris_clk_peris_gic",
+ "gout_peris_mct_pclk", "mout_peris_bus_user",
CLK_CON_GAT_GOUT_BLK_PERIS_UID_MCT_IPCLKPORT_PCLK,
21, 0, 0),
GATE(CLK_GOUT_PERIS_OTP_CON_TOP_PCLK,
- "gout_peris_otp_con_top_pclk", "mout_peris_clk_peris_gic",
+ "gout_peris_otp_con_top_pclk", "mout_peris_bus_user",
CLK_CON_GAT_GOUT_BLK_PERIS_UID_OTP_CON_TOP_IPCLKPORT_PCLK,
21, 0, 0),
GATE(CLK_GOUT_PERIS_D_TZPC_PERIS_PCLK,
"gout_peris_d_tzpc_peris_pclk", "mout_peris_bus_user",
CLK_CON_GAT_GOUT_BLK_PERIS_UID_D_TZPC_PERIS_IPCLKPORT_PCLK,
21, 0, 0),
+ GATE(CLK_GOUT_PERIS_TMU_SUB_PCLK,
+ "gout_peris_tmu_sub_pclk", "mout_peris_bus_user",
+ CLK_CON_GAT_GOUT_BLK_PERIS_UID_TMU_SUB_IPCLKPORT_PCLK,
+ 21, 0, 0),
GATE(CLK_GOUT_PERIS_TMU_TOP_PCLK,
- "gout_peris_tmu_top_pclk", "mout_peris_clk_peris_gic",
+ "gout_peris_tmu_top_pclk", "mout_peris_bus_user",
CLK_CON_GAT_GOUT_BLK_PERIS_UID_TMU_TOP_IPCLKPORT_PCLK,
21, 0, 0),
GATE(CLK_GOUT_PERIS_OTP_CON_BIRA_OSCCLK,
--
2.54.0
^ permalink raw reply related
* Re: [PATCH v7 1/3] dt-bindings: mmc: sdhci-msm: Add ICE phandle
From: Neeraj Soni @ 2026-06-13 5:21 UTC (permalink / raw)
To: Krzysztof Kozlowski, Kuldeep Singh, ulf.hansson, robh, krzk+dt,
conor+dt, andersson, konradybcio
Cc: linux-mmc, devicetree, linux-kernel, Abel Vesa, Abhinaba Rakshit
In-Reply-To: <1a66f1a6-840b-4de4-8e65-a3456b654044@oss.qualcomm.com>
On 6/9/2026 5:19 PM, Krzysztof Kozlowski wrote:
> On 09/06/2026 10:18, Neeraj Soni wrote:
>>
>>
>> On 6/8/2026 11:40 AM, Kuldeep Singh wrote:
>>> On 08-06-2026 09:46, Neeraj Soni wrote:
>>>> Starting with sc7280(kodiak), the ICE will have its own device-tree node.
>>>> So add the qcom,ice property to reference it.
>>>>
>>>> To avoid double-modeling, when qcom,ice is present, disallow an embedded
>>>> ICE register region in the SDHCI node. Older SoCs without ICE remain
>>>> valid as no additional requirement is imposed.
>>>>
>>>> Co-developed-by: Abel Vesa <abel.vesa@linaro.org>
>>>> Signed-off-by: Abel Vesa <abel.vesa@linaro.org>
>>>> Co-developed-by: Abhinaba Rakshit <abhinaba.rakshit@oss.qualcomm.com>
>>>> Signed-off-by: Abhinaba Rakshit <abhinaba.rakshit@oss.qualcomm.com>
>>>> Reviewed-by: Kuldeep Singh <kuldeep.singh@oss.qualcomm.com>
>>>> Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@oss.qualcomm.com>
>>>> Link: https://lore.kernel.org/r/20260310113557.348502-2-neeraj.soni@oss.qualcomm.com
>>>> Signed-off-by: Neeraj Soni <neeraj.soni@oss.qualcomm.com>
>>>
>>> Link should go below "---" to specify previous discussions.
>>>
>>> Usually maintainers add link of patchset being merged here while merging
>>> changes in their tree but authors don't add it here.
>>>
>> Do not see any such restrictions here https://www.kernel.org/doc/html/latest/process/submitting-patches.html
>
> What do you provide that Link for? What does it bring?
>
Kuleep highlighted a concern with the usage of "Link:" tag. The link i
provided guides on posting patches to upstream linux. Wanted to highlight
what i folloed and I did not find any specific comment/line in the guide
which prohibits author to use "Link:" tag in trailer section. If there
are guidelines otherwise please let me know and i will correct and post
new patch.
> Best regards,
> Krzysztof
>
Regards
Neeraj
^ permalink raw reply
* Re: [PATCH 3/5] iio: adc: ti-ads1262: Add GPIO controller support
From: Kurt Borja @ 2026-06-13 6:23 UTC (permalink / raw)
To: Kurt Borja, Jonathan Cameron, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Linus Walleij, Bartosz Golaszewski
Cc: David Lechner, Nuno Sá, Andy Shevchenko, linux-iio,
devicetree, linux-kernel, linux-gpio
In-Reply-To: <20260612-ads126x-v1-3-894c788d03ed@gmail.com>
On Fri Jun 12, 2026 at 5:46 PM -05, Kurt Borja wrote:
> Add support for the GPIO controller capability found in both TI ADS1262
> and ADS1263 ADCs.
>
> Eight analog input pins can be programmed as GPIO. This configuration
> does not prevent the pins from being used as analog inputs at the same
> time, so no considerations were taken in that regard.
>
> Signed-off-by: Kurt Borja <kuurtb@gmail.com>
After going through Sashiko's feedback I realized this patch wasn't
properly tested and the gpiochip callbacks were carelessly implemented.
I'll do better for the next version and I apologize in advance for the
time lost.
--
Thanks,
~ Kurt
^ permalink raw reply
* Re: [PATCH v6 0/7] Add support for MT6392 PMIC
From: Luca Leonardo Scorcia @ 2026-06-13 6:46 UTC (permalink / raw)
To: linux-mediatek
Cc: Dmitry Torokhov, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Sen Chu, Sean Wang, Macpaul Lin, Lee Jones, Matthias Brugger,
AngeloGioacchino Del Regno, Linus Walleij, Julien Massot,
Louis-Alexis Eyraud, Val Packett, Fabien Parent, Akari Tsuyukusa,
Chen Zhong, linux-input, devicetree, linux-kernel, linux-pm,
linux-arm-kernel, linux-gpio
In-Reply-To: <20260612200717.361018-1-l.scorcia@gmail.com>
Please ignore this patch set. As correctly described by sashiko-bot,
the binding with no regulator node would not be usable, even if it
passed dtbs_check. I need to complete work on that and then resubmit.
Sorry about the confusion.
Il giorno ven 12 giu 2026 alle ore 22:26 Luca Leonardo Scorcia
<l.scorcia@gmail.com> ha scritto:
>
> The MediaTek MT6392 PMIC is usually found on devices powered by
> the MT8516/MT8167 SoC and is yet another MT6323/MT6397 variant.
>
> This series is mostly based around patches submitted a couple
> years ago by Fabien Parent and not merged and from Val Packett's
> submission from Jan 2025 that included extra cleanups, fixes, and a
> new dtsi file similar to ones that exist for other PMICs. Some
> comments weren't addressed and the series was ultimately not merged.
>
> These patches only enable three functions: keys, pinctrl and RTC.
> Regulators and speaker amp will follow later as I still need to further
> improve those two, but getting the main PMIC in will make the series
> easier to review.
>
> I added a handful of device tree improvements to fix some dtbs_check
> errors, added support for the pinctrl device and addressed the comments
> from last year's reviews.
>
> Please note that patch 0005 depends on patch 0004 as they both need the
> registers.h file, but they belong to different driver areas. I'm not sure
> if I'm supposed to squash them even if they belong to different driver
> areas of if it's fine like this. Any advice is welcome.
>
> The series has been tested on Xiaomi Mi Smart Clock X04G and on the
> Lenovo Smart Clock 2.
>
> Changes in v6:
> - Dropped the regulators driver for the moment
> - Explained the FCHR key name origin in the commit message
> - Introduced the MFD_CELL_* macro in the sub-devices definitions.
> A separate, independent commit introduced MFD_CELL_* to all the
> subdevices in the mt6397-core.c file for consistency
> - Replaced of_device_get_match_data with device_get_match_data
> - Removed the mfd_match_data enum in favor of the preexisting
> chip_id enum
> - Adjusted the error message if the device is unsupported
>
> Changes in v5 [5]:
> - Double checked regulator driver with data sheet and Android sources.
> The data sheet I have misses a lot of register descriptions, but
> Android sources have been helpful to fill the gaps
> - Reintroduced the required attribute for the regulator compatible
> in the bindings
> - Fixed the missing reference to the MT6392 schema
> - Fixed casts/unused vars reported by kernel test robot
> - Removed Reviewed-by tags from the regulator patches as they have been
> modified in this version
>
> Changes in v4 [4]:
> - Dropped usage of the regulator compatible
> - Fixed commit messages text to properly reference the target subsystem
> - Added supply rails to the regulator
> - Reworked the regulator schema and PMIC dtsi. Now all supplies are
> documented and the schema no longer includes voltage information
> - Removed redundant ldo- / buck- prefixes
> - Renamed the pinfunc header to mediatek,mt6392-pinfunc.h
> - Modified the MFD driver to use a simple identifier in the of_match
> data properties
>
> Changes in v3 [3]:
> - Added pinctrl device
> - Changed mt6397-rtc fallback to mt6323-rtc
> - Added schema for regulators
> - Fixed checkpatch issues
>
> Changes in v2 [2]:
> - Replaced explicit compatibles with fallbacks
>
> Initial version: [1]
>
> [1] https://lore.kernel.org/linux-mediatek/cover.1771865014.git.l.scorcia@gmail.com/
> [2] https://lore.kernel.org/linux-mediatek/20260306120521.163654-1-l.scorcia@gmail.com/
> [3] https://lore.kernel.org/linux-mediatek/20260317184507.523060-1-l.scorcia@gmail.com/
> [4] https://lore.kernel.org/linux-mediatek/20260330083429.359819-1-l.scorcia@gmail.com/
> [5] https://lore.kernel.org/linux-mediatek/20260420213529.1645560-1-l.scorcia@gmail.com/
>
> Fabien Parent (3):
> dt-bindings: mfd: mt6397: Add MT6392 PMIC
> dt-bindings: input: mtk-pmic-keys: Add MT6392 PMIC keys
> mfd: mt6397: Add support for MT6392 PMIC
>
> Luca Leonardo Scorcia (2):
> mfd: mt6397: Use MFD_CELL_* to describe sub-devices
> pinctrl: mediatek: mt6397: Add MediaTek MT6392
>
> Val Packett (2):
> input: keyboard: mtk-pmic-keys: Add MT6392 support
> arm64: dts: mediatek: Add MediaTek MT6392 PMIC dtsi
>
> .../bindings/input/mediatek,pmic-keys.yaml | 1 +
> .../bindings/mfd/mediatek,mt6397.yaml | 8 +
> arch/arm64/boot/dts/mediatek/mt6392.dtsi | 41 ++
> drivers/input/keyboard/mtk-pmic-keys.c | 17 +
> drivers/mfd/mt6397-core.c | 294 +++++------
> drivers/mfd/mt6397-irq.c | 8 +
> drivers/pinctrl/mediatek/pinctrl-mt6397.c | 37 +-
> drivers/pinctrl/mediatek/pinctrl-mtk-mt6392.h | 64 +++
> include/linux/mfd/mt6392/core.h | 43 ++
> include/linux/mfd/mt6392/registers.h | 488 ++++++++++++++++++
> include/linux/mfd/mt6397/core.h | 1 +
> 11 files changed, 840 insertions(+), 162 deletions(-)
> create mode 100644 arch/arm64/boot/dts/mediatek/mt6392.dtsi
> create mode 100644 drivers/pinctrl/mediatek/pinctrl-mtk-mt6392.h
> create mode 100644 include/linux/mfd/mt6392/core.h
> create mode 100644 include/linux/mfd/mt6392/registers.h
>
> --
> 2.43.0
>
--
Luca Leonardo Scorcia
l.scorcia@gmail.com
^ permalink raw reply
* [RFC PATCH v4 0/9] accel: rocket: Add RK3568 NPU support
From: MidG971 @ 2026-06-13 7:01 UTC (permalink / raw)
To: tomeu, ogabbay, heiko, robh, krzk+dt, conor+dt, ulf.hansson
Cc: dri-devel, linux-rockchip, devicetree, linux-arm-kernel, linux-pm,
iommu, linux-kernel, xxm, chaoyi.chen, finley.xiao, diederik,
jonas, Midgy BALON
From: Midgy BALON <midgy971@gmail.com>
RFC, not for merge. End-to-end inference does not produce correct output
yet (see Status), so per the v2 discussion this is a request for design
feedback. It probes, attaches, and submits cleanly on a stock v7.1-rc6
tree; what remains is one hardware-internal issue.
The RK3568 has a single NVDLA-derived NPU core, the same IP family as the
RK3588 NPU the driver already supports; the register layout matches. The
RK3568 differences are a 32-bit NPU AXI/IOMMU (vs 40-bit) and explicit
PVTPLL/PMU bring-up to power and de-idle the NPU before it is reachable.
Patches:
1-2 rocket: per-SoC data struct, then derive DMA width and core count
from match data (refactors, no functional change); patch 2 also
bounds-checks the per-SoC cores array.
3 rocket: RK3568 SoC data; start the PVTPLL compute clock via SCMI.
Powering on and de-idling the NPU NoC are left to the power domain.
4 rocket: reset the NPU before detaching the IOMMU on a job timeout
(the detach otherwise stalls a wedged AXI master and WARNs).
5 rocket: keep the IOMMU domain attached across jobs instead of
re-attaching per job (the per-job rk_iommu handshake on the idle
NPU MMU is slow and noisy); also drop the domain on reset and stop
the scheduler before IOMMU teardown.
6 dt-bindings: add the RK3568 NPU compatible; require rockchip,pmu
for RK3568.
7-8 arm64 dts: add the NPU and its IOMMU, and enable them on ROCK 3B.
9 pmdomain: give the RK3568 NPU power domain a regulator so genpd
owns vdd_npu via domain-supply (Suggested-by Chaoyi Chen).
Dependencies. This series no longer touches the IOMMU driver; two
in-flight Rockchip IOMMU changes are relevant but not part of it:
- Simon Xue's "iommu/rockchip: Drop global rk_ops in favor of
per-device ops" [1]. On boards with more than 4 GiB of RAM the NPU
MMU's DTE must stay below 4 GiB (its DTE address is 32-bit), so the
NPU IOMMU is described with the "rockchip,iommu" compatible, whose ops
allocate the page tables with GFP_DMA32; the SoC's other IOMMUs use
the "rockchip,rk3568-iommu" (40-bit) ops. The driver keeps a single
global ops pointer, so two ops on one SoC trip its coexistence check;
this series therefore sits on top of Simon's per-device-ops change,
which Rockchip (Chaoyi Chen) confirmed is the intended way to give the
NPU MMU its 32-bit DTE.
- "iommu/rockchip: disable fetch dte time limit" [2] (Simon Xue / Sven
Pueschel, in the iommu tree), which sets AUTO_GATING bit 31. v3 carried
a local AUTO_GATING patch; that unconditional fix has since been merged,
so this series drops its IOMMU patch. The bit is a no-op on this
hardware in any case (the page walk completes on its reset value).
Power bring-up. The NPU is brought up through the power-domain layer (no
driver hack): the NPU power-domain keeps its clocks but drops the pm_qos
phandle (qos_npu sits behind the gated NPU NoC, so genpd's power-off QoS
save faults reading it), and vdd_npu is wired as the domain's
domain-supply with the domain marked need_regulator (patch 9), so genpd
brings the rail up before it de-idles the NoC at power-on. The PMU de-idle
then ACKs without PVTPLL running; PVTPLL is only needed for compute.
Status. On v7.1-rc6 the driver probes, creates /dev/accel/accel0,
attaches an IOMMU domain, and submits jobs; the program controller
fetches and broadcasts the command list. Inference output is still
wrong. The kernel side (this series) appears complete; what remains is
mesa/Teflon userspace, which still emits RK3588-tuned config (to be
filed on mesa-dev), and the hardware: with corrected config the NPU
reads the full input and weight tensors (per its DMA counters) but the
MAC/output stage never completes and the job times out, leaving the
output at the buffer's zero-point. It is not in the command list (a
byte-exact replay of the vendor's command list behaves the same).
Pointers from anyone with RK3568 NPU experience welcome.
Known residual. On the first IOMMU attach the NPU MMU is idle with paging
already enabled; the rk_iommu stall/reset handshake does not complete in
that state and logs one burst of timeouts before the (kept) domain
settles. It is harmless here because the job times out regardless, but it
points at an idle-MMU reconfiguration corner the rk_iommu code does not
handle on this block.
[1] https://lore.kernel.org/linux-rockchip/20260310105303.128859-1-xxm@rock-chips.com/
[2] https://lore.kernel.org/all/20260428-spu-iommudtefix-v2-1-f592f579e508@pengutronix.de/
Changes since v3:
- Dropped the local AUTO_GATING patch: the correct fix (set AUTO_GATING
bit 31, "disable fetch dte time limit") has since been merged upstream
[2], so the series no longer touches the IOMMU driver.
- vdd_npu: new pmdomain patch (9) gives the RK3568 NPU domain a regulator
(need_regulator) and the board wires domain-supply, dropping the
regulator-always-on workaround (Suggested-by Chaoyi Chen). It relies on
the in-tree pmdomain default-off-if-need_regulator handling. The
"Failed to create device link ... <pmic>" line at pmdomain probe is a
pre-existing fw_devlink cyclic-dependency warning (the single
power-controller provides every domain, including the one the I2C PMIC
needs), seen the same way on RK3588; it is harmless here beyond a few
wasted EPROBE_DEFER retries, and a proper fix belongs in the
power-controller driver, not this series.
- rk356x dts: also assign the CRU CLK_NPU so the NPU AXI bus clock comes
up at 200 MHz instead of the 12 MHz boot default; order the NPU/IOMMU
nodes by unit address.
- rocket RK3568: fetch the SCMI/PVTPLL clock by name (the v3 bulk index
resolved to the wrong clock); drop the redundant driver PMU de-idle
writes (handled by the power domain).
- rocket: clear the attached IOMMU domain on reset; unwind through
rocket_core_fini() on noc_init failure; stop the scheduler before the
IOMMU teardown.
- rocket: bounds-check the cores array against the per-SoC core count.
- Binding: require rockchip,pmu on RK3568.
- Dependency framing: confirmed by Rockchip as v2 + 32-bit DTE via
Simon's per-device-ops series (was framed as v1 in v3).
Midgy BALON (9):
accel: rocket: Introduce per-SoC rocket_soc_data
accel: rocket: Derive DMA width and core count from match data
accel: rocket: Add RK3568 SoC support
accel: rocket: Reset the NPU before detaching the IOMMU on timeout
accel: rocket: Keep the IOMMU domain attached across jobs
dt-bindings: npu: rockchip,rk3588-rknn-core: Add RK3568
arm64: dts: rockchip: rk356x: Add the NPU and its IOMMU
arm64: dts: rockchip: rk3568-rock-3b: Enable the NPU
pmdomain: rockchip: Add a regulator to the RK3568 NPU power domain
.../npu/rockchip,rk3588-rknn-core.yaml | 27 +++++++++-
.../boot/dts/rockchip/rk3568-rock-3b.dts | 18 ++++++-
arch/arm64/boot/dts/rockchip/rk356x-base.dtsi | 38 ++++++++++++++
drivers/accel/rocket/rocket_core.c | 30 ++++++++++-
drivers/accel/rocket/rocket_core.h | 19 +++++++
drivers/accel/rocket/rocket_device.c | 15 ++----
drivers/accel/rocket/rocket_device.h | 3 +-
drivers/accel/rocket/rocket_drv.c | 50 ++++++++++++++++++-
drivers/accel/rocket/rocket_job.c | 45 ++++++++++++++---
drivers/pmdomain/rockchip/pm-domains.c | 36 +++++++++----
10 files changed, 245 insertions(+), 36 deletions(-)
base-commit: e43ffb69e0438cddd72aaa30898b4dc446f664f8
--
2.39.5
^ permalink raw reply
* [RFC PATCH v4 1/9] accel: rocket: Introduce per-SoC rocket_soc_data
From: MidG971 @ 2026-06-13 7:01 UTC (permalink / raw)
To: tomeu, ogabbay, heiko, robh, krzk+dt, conor+dt, ulf.hansson
Cc: dri-devel, linux-rockchip, devicetree, linux-arm-kernel, linux-pm,
iommu, linux-kernel, xxm, chaoyi.chen, finley.xiao, diederik,
jonas, Midgy BALON
In-Reply-To: <20260613070116.438906-1-midgy971@gmail.com>
From: Midgy BALON <midgy971@gmail.com>
Add a per-SoC data structure carried in the OF match table, currently
holding only the NPU AXI address width, and use it for the per-core DMA
mask instead of a hardcoded 40-bit value. No functional change: the
RK3588 AXI master is 40-bit. This prepares for SoCs with a narrower
address width.
Signed-off-by: Midgy BALON <midgy971@gmail.com>
---
drivers/accel/rocket/rocket_core.c | 7 ++++++-
drivers/accel/rocket/rocket_core.h | 11 +++++++++++
drivers/accel/rocket/rocket_drv.c | 6 +++++-
3 files changed, 22 insertions(+), 2 deletions(-)
diff --git a/drivers/accel/rocket/rocket_core.c b/drivers/accel/rocket/rocket_core.c
index b3b2fa9ba645a..09c445af7de73 100644
--- a/drivers/accel/rocket/rocket_core.c
+++ b/drivers/accel/rocket/rocket_core.c
@@ -7,6 +7,7 @@
#include <linux/dma-mapping.h>
#include <linux/err.h>
#include <linux/iommu.h>
+#include <linux/of.h>
#include <linux/platform_device.h>
#include <linux/pm_runtime.h>
#include <linux/reset.h>
@@ -21,6 +22,10 @@ int rocket_core_init(struct rocket_core *core)
u32 version;
int err = 0;
+ core->soc_data = of_device_get_match_data(dev);
+ if (!core->soc_data)
+ return dev_err_probe(dev, -EINVAL, "missing SoC match data\n");
+
core->resets[0].id = "srst_a";
core->resets[1].id = "srst_h";
err = devm_reset_control_bulk_get_exclusive(&pdev->dev, ARRAY_SIZE(core->resets),
@@ -52,7 +57,7 @@ int rocket_core_init(struct rocket_core *core)
dma_set_max_seg_size(dev, UINT_MAX);
- err = dma_set_mask_and_coherent(dev, DMA_BIT_MASK(40));
+ err = dma_set_mask_and_coherent(dev, DMA_BIT_MASK(core->soc_data->dma_bits));
if (err)
return err;
diff --git a/drivers/accel/rocket/rocket_core.h b/drivers/accel/rocket/rocket_core.h
index f6d7382854ca9..8ee105a0be40e 100644
--- a/drivers/accel/rocket/rocket_core.h
+++ b/drivers/accel/rocket/rocket_core.h
@@ -12,6 +12,16 @@
#include "rocket_registers.h"
+struct rocket_core;
+
+/**
+ * struct rocket_soc_data - per-SoC configuration data
+ * @dma_bits: Physical address width reachable by the NPU's AXI master.
+ */
+struct rocket_soc_data {
+ unsigned int dma_bits;
+};
+
#define rocket_pc_readl(core, reg) \
readl((core)->pc_iomem + (REG_PC_##reg))
#define rocket_pc_writel(core, reg, value) \
@@ -31,6 +41,7 @@ struct rocket_core {
struct device *dev;
struct rocket_device *rdev;
unsigned int index;
+ const struct rocket_soc_data *soc_data;
int irq;
void __iomem *pc_iomem;
diff --git a/drivers/accel/rocket/rocket_drv.c b/drivers/accel/rocket/rocket_drv.c
index 8bbbce594883e..384c38e13acce 100644
--- a/drivers/accel/rocket/rocket_drv.c
+++ b/drivers/accel/rocket/rocket_drv.c
@@ -213,8 +213,12 @@ static void rocket_remove(struct platform_device *pdev)
}
}
+static const struct rocket_soc_data rk3588_soc_data = {
+ .dma_bits = 40,
+};
+
static const struct of_device_id dt_match[] = {
- { .compatible = "rockchip,rk3588-rknn-core" },
+ { .compatible = "rockchip,rk3588-rknn-core", .data = &rk3588_soc_data },
{}
};
MODULE_DEVICE_TABLE(of, dt_match);
--
2.39.5
^ permalink raw reply related
* [RFC PATCH v4 2/9] accel: rocket: Derive DMA width and core count from match data
From: MidG971 @ 2026-06-13 7:01 UTC (permalink / raw)
To: tomeu, ogabbay, heiko, robh, krzk+dt, conor+dt, ulf.hansson
Cc: dri-devel, linux-rockchip, devicetree, linux-arm-kernel, linux-pm,
iommu, linux-kernel, xxm, chaoyi.chen, finley.xiao, diederik,
jonas, Midgy BALON
In-Reply-To: <20260613070116.438906-1-midgy971@gmail.com>
From: Midgy BALON <midgy971@gmail.com>
The probe already has the per-SoC match data, which now records the core
count and DMA width. Use it for the cores array allocation and the
device DMA mask instead of re-scanning the device tree for available core
nodes.
While at it, reject a device tree that declares more NPU core nodes than
the SoC has, so the fixed-size cores array can never be overrun.
Signed-off-by: Midgy BALON <midgy971@gmail.com>
---
drivers/accel/rocket/rocket_core.h | 2 ++
drivers/accel/rocket/rocket_device.c | 15 +++++----------
drivers/accel/rocket/rocket_device.h | 3 ++-
drivers/accel/rocket/rocket_drv.c | 13 ++++++++++++-
4 files changed, 21 insertions(+), 12 deletions(-)
diff --git a/drivers/accel/rocket/rocket_core.h b/drivers/accel/rocket/rocket_core.h
index 8ee105a0be40e..d6421251670dc 100644
--- a/drivers/accel/rocket/rocket_core.h
+++ b/drivers/accel/rocket/rocket_core.h
@@ -16,9 +16,11 @@ struct rocket_core;
/**
* struct rocket_soc_data - per-SoC configuration data
+ * @num_cores: Number of NPU cores in this SoC.
* @dma_bits: Physical address width reachable by the NPU's AXI master.
*/
struct rocket_soc_data {
+ unsigned int num_cores;
unsigned int dma_bits;
};
diff --git a/drivers/accel/rocket/rocket_device.c b/drivers/accel/rocket/rocket_device.c
index 46e6ee1e72c5f..6186f4faa3a2a 100644
--- a/drivers/accel/rocket/rocket_device.c
+++ b/drivers/accel/rocket/rocket_device.c
@@ -6,18 +6,16 @@
#include <linux/clk.h>
#include <linux/dma-mapping.h>
#include <linux/platform_device.h>
-#include <linux/of.h>
#include "rocket_device.h"
struct rocket_device *rocket_device_init(struct platform_device *pdev,
- const struct drm_driver *rocket_drm_driver)
+ const struct drm_driver *rocket_drm_driver,
+ const struct rocket_soc_data *soc_data)
{
struct device *dev = &pdev->dev;
- struct device_node *core_node;
struct rocket_device *rdev;
struct drm_device *ddev;
- unsigned int num_cores = 0;
int err;
rdev = devm_drm_dev_alloc(dev, rocket_drm_driver, struct rocket_device, ddev);
@@ -27,17 +25,14 @@ struct rocket_device *rocket_device_init(struct platform_device *pdev,
ddev = &rdev->ddev;
dev_set_drvdata(dev, rdev);
- for_each_compatible_node(core_node, NULL, "rockchip,rk3588-rknn-core")
- if (of_device_is_available(core_node))
- num_cores++;
-
- rdev->cores = devm_kcalloc(dev, num_cores, sizeof(*rdev->cores), GFP_KERNEL);
+ rdev->cores = devm_kcalloc(dev, soc_data->num_cores, sizeof(*rdev->cores),
+ GFP_KERNEL);
if (!rdev->cores)
return ERR_PTR(-ENOMEM);
dma_set_max_seg_size(dev, UINT_MAX);
- err = dma_set_mask_and_coherent(dev, DMA_BIT_MASK(40));
+ err = dma_set_mask_and_coherent(dev, DMA_BIT_MASK(soc_data->dma_bits));
if (err)
return ERR_PTR(err);
diff --git a/drivers/accel/rocket/rocket_device.h b/drivers/accel/rocket/rocket_device.h
index ce662abc01d3d..2f74e078974e3 100644
--- a/drivers/accel/rocket/rocket_device.h
+++ b/drivers/accel/rocket/rocket_device.h
@@ -22,7 +22,8 @@ struct rocket_device {
};
struct rocket_device *rocket_device_init(struct platform_device *pdev,
- const struct drm_driver *rocket_drm_driver);
+ const struct drm_driver *rocket_drm_driver,
+ const struct rocket_soc_data *soc_data);
void rocket_device_fini(struct rocket_device *rdev);
#define to_rocket_device(drm_dev) \
((struct rocket_device *)(container_of((drm_dev), struct rocket_device, ddev)))
diff --git a/drivers/accel/rocket/rocket_drv.c b/drivers/accel/rocket/rocket_drv.c
index 384c38e13acce..f0beed2d522c7 100644
--- a/drivers/accel/rocket/rocket_drv.c
+++ b/drivers/accel/rocket/rocket_drv.c
@@ -159,11 +159,15 @@ static const struct drm_driver rocket_drm_driver = {
static int rocket_probe(struct platform_device *pdev)
{
+ const struct rocket_soc_data *soc_data = of_device_get_match_data(&pdev->dev);
int ret;
+ if (!soc_data)
+ return -EINVAL;
+
if (rdev == NULL) {
/* First core probing, initialize DRM device. */
- rdev = rocket_device_init(drm_dev, &rocket_drm_driver);
+ rdev = rocket_device_init(drm_dev, &rocket_drm_driver, soc_data);
if (IS_ERR(rdev)) {
dev_err(&pdev->dev, "failed to initialize rocket device\n");
return PTR_ERR(rdev);
@@ -172,6 +176,12 @@ static int rocket_probe(struct platform_device *pdev)
unsigned int core = rdev->num_cores;
+ if (core >= soc_data->num_cores) {
+ dev_err(&pdev->dev, "too many NPU core nodes (max %u)\n",
+ soc_data->num_cores);
+ return -EINVAL;
+ }
+
dev_set_drvdata(&pdev->dev, rdev);
rdev->cores[core].rdev = rdev;
@@ -214,6 +224,7 @@ static void rocket_remove(struct platform_device *pdev)
}
static const struct rocket_soc_data rk3588_soc_data = {
+ .num_cores = 3,
.dma_bits = 40,
};
--
2.39.5
^ permalink raw reply related
* [RFC PATCH v4 3/9] accel: rocket: Add RK3568 SoC support
From: MidG971 @ 2026-06-13 7:01 UTC (permalink / raw)
To: tomeu, ogabbay, heiko, robh, krzk+dt, conor+dt, ulf.hansson
Cc: dri-devel, linux-rockchip, devicetree, linux-arm-kernel, linux-pm,
iommu, linux-kernel, xxm, chaoyi.chen, finley.xiao, diederik,
jonas, Midgy BALON
In-Reply-To: <20260613070116.438906-1-midgy971@gmail.com>
From: Midgy BALON <midgy971@gmail.com>
The RK3568 has a single core of the same NVDLA-derived NPU IP as the
RK3588, with a 32-bit AXI master. Add rk3568_soc_data and its
compatible.
Unlike the RK3588, the RK3568 NPU's compute clock is a PVTPLL managed by
TF-A via SCMI; start it from an noc_init callback with a real rate change
(an intermediate rate defeats the clock framework's unchanged-rate
shortcut). Powering on and de-idling the NPU NoC are left to the power
domain (genpd), which performs them when the IOMMU supplier is resumed,
so the driver does not poke the PMU directly.
If noc_init fails, unwind through rocket_core_fini() so the core is torn
down completely rather than leaking the runtime-PM and IOMMU state.
Signed-off-by: Midgy BALON <midgy971@gmail.com>
---
drivers/accel/rocket/rocket_core.c | 9 +++++++++
drivers/accel/rocket/rocket_core.h | 3 +++
drivers/accel/rocket/rocket_drv.c | 31 ++++++++++++++++++++++++++++++
3 files changed, 43 insertions(+)
diff --git a/drivers/accel/rocket/rocket_core.c b/drivers/accel/rocket/rocket_core.c
index 09c445af7de73..779e951596a15 100644
--- a/drivers/accel/rocket/rocket_core.c
+++ b/drivers/accel/rocket/rocket_core.c
@@ -88,6 +88,15 @@ int rocket_core_init(struct rocket_core *core)
return err;
}
+ if (core->soc_data->noc_init) {
+ err = core->soc_data->noc_init(core);
+ if (err) {
+ pm_runtime_put_sync(dev);
+ rocket_core_fini(core);
+ return err;
+ }
+ }
+
version = rocket_pc_readl(core, VERSION);
version += rocket_pc_readl(core, VERSION_NUM) & 0xffff;
diff --git a/drivers/accel/rocket/rocket_core.h b/drivers/accel/rocket/rocket_core.h
index d6421251670dc..5a145ba8c5a92 100644
--- a/drivers/accel/rocket/rocket_core.h
+++ b/drivers/accel/rocket/rocket_core.h
@@ -18,10 +18,13 @@ struct rocket_core;
* struct rocket_soc_data - per-SoC configuration data
* @num_cores: Number of NPU cores in this SoC.
* @dma_bits: Physical address width reachable by the NPU's AXI master.
+ * @noc_init: Optional callback to bring up the NPU before it is reachable.
+ * Used on RK3568 to start the PVTPLL compute clock via SCMI.
*/
struct rocket_soc_data {
unsigned int num_cores;
unsigned int dma_bits;
+ int (*noc_init)(struct rocket_core *core);
};
#define rocket_pc_readl(core, reg) \
diff --git a/drivers/accel/rocket/rocket_drv.c b/drivers/accel/rocket/rocket_drv.c
index f0beed2d522c7..86484110ad6f0 100644
--- a/drivers/accel/rocket/rocket_drv.c
+++ b/drivers/accel/rocket/rocket_drv.c
@@ -10,6 +10,7 @@
#include <linux/err.h>
#include <linux/iommu.h>
#include <linux/of.h>
+#include <linux/of_clk.h>
#include <linux/platform_device.h>
#include <linux/pm_runtime.h>
@@ -223,12 +224,42 @@ static void rocket_remove(struct platform_device *pdev)
}
}
+/*
+ * The NPU compute clock is a PVTPLL managed by TF-A via SCMI; spin it up
+ * with a real rate change (an intermediate rate defeats the clock
+ * framework's unchanged-rate shortcut). Powering on and de-idling the NPU
+ * NoC are handled by the power domain (genpd) before the NPU is accessed.
+ */
+static int rk3568_noc_init(struct rocket_core *core)
+{
+ struct clk *npu_clk;
+
+ npu_clk = of_clk_get_by_name(core->dev->of_node, "npu");
+ if (IS_ERR(npu_clk))
+ return dev_err_probe(core->dev, PTR_ERR(npu_clk),
+ "failed to get the NPU SCMI clock\n");
+
+ if (clk_set_rate(npu_clk, 600000000UL) ||
+ clk_set_rate(npu_clk, 1000000000UL))
+ dev_warn(core->dev, "failed to set the NPU compute clock rate\n");
+ clk_put(npu_clk);
+
+ return 0;
+}
+
+static const struct rocket_soc_data rk3568_soc_data = {
+ .num_cores = 1,
+ .dma_bits = 32,
+ .noc_init = rk3568_noc_init,
+};
+
static const struct rocket_soc_data rk3588_soc_data = {
.num_cores = 3,
.dma_bits = 40,
};
static const struct of_device_id dt_match[] = {
+ { .compatible = "rockchip,rk3568-rknn-core", .data = &rk3568_soc_data },
{ .compatible = "rockchip,rk3588-rknn-core", .data = &rk3588_soc_data },
{}
};
--
2.39.5
^ permalink raw reply related
* [RFC PATCH v4 4/9] accel: rocket: Reset the NPU before detaching the IOMMU on timeout
From: MidG971 @ 2026-06-13 7:01 UTC (permalink / raw)
To: tomeu, ogabbay, heiko, robh, krzk+dt, conor+dt, ulf.hansson
Cc: dri-devel, linux-rockchip, devicetree, linux-arm-kernel, linux-pm,
iommu, linux-kernel, xxm, chaoyi.chen, finley.xiao, diederik,
jonas, Midgy BALON
In-Reply-To: <20260613070116.438906-1-midgy971@gmail.com>
From: Midgy BALON <midgy971@gmail.com>
On a job timeout the NPU AXI master can be left wedged with
outstanding transactions. rocket_reset() detached the IOMMU group
before resetting the hardware, so iommu_detach_group() ->
__iommu_group_set_core_domain() asked the rk_iommu to stall and wait
for the in-flight transactions to drain. They never did, the stall
request timed out (-ETIMEDOUT) and the IOMMU core WARNed:
WARNING: drivers/iommu/iommu.c:157 __iommu_group_set_core_domain
iommu_detach_group
rocket_reset
rocket_job_timedout
Assert the core reset first: it quiesces the AXI master so the
following IOMMU detach completes cleanly. Move the detach after
rocket_core_reset() and out of the job_lock (it does not touch
in_flight_job).
Signed-off-by: Midgy BALON <midgy971@gmail.com>
---
drivers/accel/rocket/rocket_job.c | 12 +++++++++---
1 file changed, 9 insertions(+), 3 deletions(-)
diff --git a/drivers/accel/rocket/rocket_job.c b/drivers/accel/rocket/rocket_job.c
index ac51bff39833f..e25234261536b 100644
--- a/drivers/accel/rocket/rocket_job.c
+++ b/drivers/accel/rocket/rocket_job.c
@@ -364,14 +364,20 @@ rocket_reset(struct rocket_core *core, struct drm_sched_job *bad)
if (core->in_flight_job)
pm_runtime_put_noidle(core->dev);
- iommu_detach_group(NULL, core->iommu_group);
-
core->in_flight_job = NULL;
}
- /* Proceed with reset now. */
+ /*
+ * Reset the NPU hardware before detaching the IOMMU. A timed-out job
+ * leaves the NPU AXI master wedged; detaching the IOMMU then issues a
+ * stall request that never drains and times out (warning in the IOMMU
+ * core). Asserting the core reset first quiesces the master so the
+ * detach completes cleanly.
+ */
rocket_core_reset(core);
+ iommu_detach_group(NULL, core->iommu_group);
+
/* NPU has been reset, we can clear the reset pending bit. */
atomic_set(&core->reset.pending, 0);
--
2.39.5
^ permalink raw reply related
* [RFC PATCH v4 5/9] accel: rocket: Keep the IOMMU domain attached across jobs
From: MidG971 @ 2026-06-13 7:01 UTC (permalink / raw)
To: tomeu, ogabbay, heiko, robh, krzk+dt, conor+dt, ulf.hansson
Cc: dri-devel, linux-rockchip, devicetree, linux-arm-kernel, linux-pm,
iommu, linux-kernel, xxm, chaoyi.chen, finley.xiao, diederik,
jonas, Midgy BALON
In-Reply-To: <20260613070116.438906-1-midgy971@gmail.com>
From: Midgy BALON <midgy971@gmail.com>
rocket attached the job's IOMMU domain in rocket_job_run() and
detached it again on every completion and reset. Each attach/detach
toggles the rk_iommu stall/force-reset/paging handshake, and on
RK3568 the NPU MMU is idle between jobs, so that handshake times out
and logs a burst of "stall/paging request timed out" errors for
every job.
Attach the per-context domain once and keep it: track the attached
domain in the core, swap it only when a job from a different context
runs, and detach it at core teardown. A reference on the attached
domain is held so it outlives the job that first attached it and is
released on swap/teardown.
Because a hardware reset (on job timeout) wipes the IOMMU page-table
base register, drop the attached domain after rocket_core_reset() so
the next job re-attaches and reprograms it. Also tear down the
scheduler before detaching the IOMMU in rocket_core_fini(), so an
in-flight job can no longer reach the domain being detached.
Signed-off-by: Midgy BALON <midgy971@gmail.com>
---
drivers/accel/rocket/rocket_core.c | 14 +++++++++++-
drivers/accel/rocket/rocket_core.h | 3 +++
drivers/accel/rocket/rocket_job.c | 35 +++++++++++++++++++++++++-----
3 files changed, 46 insertions(+), 6 deletions(-)
diff --git a/drivers/accel/rocket/rocket_core.c b/drivers/accel/rocket/rocket_core.c
index 779e951596a15..6c128f585cff4 100644
--- a/drivers/accel/rocket/rocket_core.c
+++ b/drivers/accel/rocket/rocket_core.c
@@ -13,6 +13,7 @@
#include <linux/reset.h>
#include "rocket_core.h"
+#include "rocket_drv.h"
#include "rocket_job.h"
int rocket_core_init(struct rocket_core *core)
@@ -112,9 +113,20 @@ void rocket_core_fini(struct rocket_core *core)
{
pm_runtime_dont_use_autosuspend(core->dev);
pm_runtime_disable(core->dev);
+
+ /*
+ * Stop the scheduler before tearing down the IOMMU so an in-flight
+ * job can no longer touch the (about to be detached) domain.
+ */
+ rocket_job_fini(core);
+
+ if (core->attached_domain) {
+ iommu_detach_group(NULL, core->iommu_group);
+ rocket_iommu_domain_put(core->attached_domain);
+ core->attached_domain = NULL;
+ }
iommu_group_put(core->iommu_group);
core->iommu_group = NULL;
- rocket_job_fini(core);
}
void rocket_core_reset(struct rocket_core *core)
diff --git a/drivers/accel/rocket/rocket_core.h b/drivers/accel/rocket/rocket_core.h
index 5a145ba8c5a92..78791ecb32e75 100644
--- a/drivers/accel/rocket/rocket_core.h
+++ b/drivers/accel/rocket/rocket_core.h
@@ -42,6 +42,8 @@ struct rocket_soc_data {
#define rocket_core_writel(core, reg, value) \
writel(value, (core)->core_iomem + (REG_CORE_##reg) - REG_CORE_S_STATUS)
+struct rocket_iommu_domain;
+
struct rocket_core {
struct device *dev;
struct rocket_device *rdev;
@@ -56,6 +58,7 @@ struct rocket_core {
struct reset_control_bulk_data resets[2];
struct iommu_group *iommu_group;
+ struct rocket_iommu_domain *attached_domain;
struct mutex job_lock;
struct rocket_job *in_flight_job;
diff --git a/drivers/accel/rocket/rocket_job.c b/drivers/accel/rocket/rocket_job.c
index e25234261536b..368b2ebead1b3 100644
--- a/drivers/accel/rocket/rocket_job.c
+++ b/drivers/accel/rocket/rocket_job.c
@@ -9,6 +9,7 @@
#include <drm/rocket_accel.h>
#include <linux/interrupt.h>
#include <linux/iommu.h>
+#include <linux/kref.h>
#include <linux/platform_device.h>
#include <linux/pm_runtime.h>
@@ -314,9 +315,26 @@ static struct dma_fence *rocket_job_run(struct drm_sched_job *sched_job)
if (ret < 0)
return fence;
- ret = iommu_attach_group(job->domain->domain, core->iommu_group);
- if (ret < 0)
- return fence;
+ /*
+ * Attach the job's IOMMU domain only when it differs from the one
+ * already attached. Re-attaching per job toggles the rk_iommu
+ * stall/reset handshake on an idle NPU MMU, which is slow and
+ * noisy; keep the domain attached across jobs instead.
+ */
+ if (core->attached_domain != job->domain) {
+ if (core->attached_domain) {
+ iommu_detach_group(NULL, core->iommu_group);
+ rocket_iommu_domain_put(core->attached_domain);
+ core->attached_domain = NULL;
+ }
+
+ ret = iommu_attach_group(job->domain->domain, core->iommu_group);
+ if (ret < 0)
+ return fence;
+
+ kref_get(&job->domain->kref);
+ core->attached_domain = job->domain;
+ }
scoped_guard(mutex, &core->job_lock) {
core->in_flight_job = job;
@@ -340,7 +358,6 @@ static void rocket_job_handle_irq(struct rocket_core *core)
return;
}
- iommu_detach_group(NULL, iommu_group_get(core->dev));
dma_fence_signal(core->in_flight_job->done_fence);
pm_runtime_put_autosuspend(core->dev);
core->in_flight_job = NULL;
@@ -376,7 +393,15 @@ rocket_reset(struct rocket_core *core, struct drm_sched_job *bad)
*/
rocket_core_reset(core);
- iommu_detach_group(NULL, core->iommu_group);
+ /*
+ * The reset wipes the IOMMU page-table base, so drop the attached
+ * domain to force the next job to re-attach and reprogram it.
+ */
+ if (core->attached_domain) {
+ iommu_detach_group(NULL, core->iommu_group);
+ rocket_iommu_domain_put(core->attached_domain);
+ core->attached_domain = NULL;
+ }
/* NPU has been reset, we can clear the reset pending bit. */
atomic_set(&core->reset.pending, 0);
--
2.39.5
^ permalink raw reply related
* [RFC PATCH v4 6/9] dt-bindings: npu: rockchip,rk3588-rknn-core: Add RK3568
From: MidG971 @ 2026-06-13 7:01 UTC (permalink / raw)
To: tomeu, ogabbay, heiko, robh, krzk+dt, conor+dt, ulf.hansson
Cc: dri-devel, linux-rockchip, devicetree, linux-arm-kernel, linux-pm,
iommu, linux-kernel, xxm, chaoyi.chen, finley.xiao, diederik,
jonas, Midgy BALON
In-Reply-To: <20260613070116.438906-1-midgy971@gmail.com>
From: Midgy BALON <midgy971@gmail.com>
The RK3568 carries a single core of the same NVDLA-derived NPU IP as the
RK3588. Add its compatible.
On RK3568 the NPU NoC bus-idle and power gating are controlled through the
system PMU rather than a dedicated register block, so add a rockchip,pmu
phandle to that syscon. The RK3568 NPU has no dedicated SRAM rail, so
sram-supply is required only on RK3588.
Signed-off-by: Midgy BALON <midgy971@gmail.com>
---
.../npu/rockchip,rk3588-rknn-core.yaml | 27 ++++++++++++++++++-
1 file changed, 26 insertions(+), 1 deletion(-)
diff --git a/Documentation/devicetree/bindings/npu/rockchip,rk3588-rknn-core.yaml b/Documentation/devicetree/bindings/npu/rockchip,rk3588-rknn-core.yaml
index caca2a4903cd1..e0b948ac47d45 100644
--- a/Documentation/devicetree/bindings/npu/rockchip,rk3588-rknn-core.yaml
+++ b/Documentation/devicetree/bindings/npu/rockchip,rk3588-rknn-core.yaml
@@ -21,6 +21,7 @@ properties:
compatible:
enum:
+ - rockchip,rk3568-rknn-core
- rockchip,rk3588-rknn-core
reg:
@@ -50,6 +51,13 @@ properties:
npu-supply: true
+ rockchip,pmu:
+ $ref: /schemas/types.yaml#/definitions/phandle
+ description:
+ Phandle to the PMU syscon. On RK3568 the NPU's NoC bus-idle and
+ power gating are controlled through the PMU; this points to that
+ syscon so those registers can be reached.
+
power-domains:
maxItems: 1
@@ -75,7 +83,24 @@ required:
- resets
- reset-names
- npu-supply
- - sram-supply
+
+allOf:
+ - if:
+ properties:
+ compatible:
+ contains:
+ const: rockchip,rk3588-rknn-core
+ then:
+ required:
+ - sram-supply
+ - if:
+ properties:
+ compatible:
+ contains:
+ const: rockchip,rk3568-rknn-core
+ then:
+ required:
+ - rockchip,pmu
additionalProperties: false
--
2.39.5
^ permalink raw reply related
* [RFC PATCH v4 7/9] arm64: dts: rockchip: rk356x: Add the NPU and its IOMMU
From: MidG971 @ 2026-06-13 7:01 UTC (permalink / raw)
To: tomeu, ogabbay, heiko, robh, krzk+dt, conor+dt, ulf.hansson
Cc: dri-devel, linux-rockchip, devicetree, linux-arm-kernel, linux-pm,
iommu, linux-kernel, xxm, chaoyi.chen, finley.xiao, diederik,
jonas, Midgy BALON
In-Reply-To: <20260613070116.438906-1-midgy971@gmail.com>
From: Midgy BALON <midgy971@gmail.com>
The RK3568 has an NVDLA-derived NPU at fde40000 with its own IOMMU at
fde4b000. Add both nodes (disabled by default) and the NPU power-domain
child under the PMU power-controller, and point rockchip,pmu at the PMU
syscon that controls the NPU NoC bus-idle.
Besides the SCMI compute clock, assign the CRU CLK_NPU so the NPU AXI
bus clock comes up at 200 MHz rather than the 12 MHz boot default.
The power-domain deliberately carries no pm_qos: qos_npu sits behind the
NPU NoC, which is gated until the NPU is brought up, so a genpd power-off
QoS save would fault reading it.
Signed-off-by: Midgy BALON <midgy971@gmail.com>
---
arch/arm64/boot/dts/rockchip/rk356x-base.dtsi | 38 +++++++++++++++++++
1 file changed, 38 insertions(+)
diff --git a/arch/arm64/boot/dts/rockchip/rk356x-base.dtsi b/arch/arm64/boot/dts/rockchip/rk356x-base.dtsi
index 64bdd8b7754b5..313db59c1aed8 100644
--- a/arch/arm64/boot/dts/rockchip/rk356x-base.dtsi
+++ b/arch/arm64/boot/dts/rockchip/rk356x-base.dtsi
@@ -512,6 +512,13 @@ power-domain@RK3568_PD_GPU {
#power-domain-cells = <0>;
};
+ pd_npu: power-domain@RK3568_PD_NPU {
+ reg = <RK3568_PD_NPU>;
+ clocks = <&cru ACLK_NPU_PRE>,
+ <&cru HCLK_NPU_PRE>;
+ #power-domain-cells = <0>;
+ };
+
/* These power domains are grouped by VD_LOGIC */
power-domain@RK3568_PD_VI {
reg = <RK3568_PD_VI>;
@@ -572,6 +579,37 @@ power-domain@RK3568_PD_RKVENC {
};
};
+ rknn_core_0: npu@fde40000 {
+ compatible = "rockchip,rk3568-rknn-core";
+ reg = <0x0 0xfde40000 0x0 0x1000>,
+ <0x0 0xfde41000 0x0 0x1000>,
+ <0x0 0xfde43000 0x0 0x1000>;
+ reg-names = "pc", "cna", "core";
+ interrupts = <GIC_SPI 151 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&cru ACLK_NPU>, <&cru HCLK_NPU>,
+ <&scmi_clk SCMI_CLK_NPU>, <&cru PCLK_NPU_PRE>;
+ clock-names = "aclk", "hclk", "npu", "pclk";
+ assigned-clocks = <&scmi_clk SCMI_CLK_NPU>, <&cru CLK_NPU>;
+ assigned-clock-rates = <200000000>, <600000000>;
+ resets = <&cru SRST_A_NPU>, <&cru SRST_H_NPU>;
+ reset-names = "srst_a", "srst_h";
+ power-domains = <&power RK3568_PD_NPU>;
+ rockchip,pmu = <&pmu>;
+ iommus = <&rknn_mmu_0>;
+ status = "disabled";
+ };
+
+ rknn_mmu_0: iommu@fde4b000 {
+ compatible = "rockchip,iommu";
+ reg = <0x0 0xfde4b000 0x0 0x40>;
+ interrupts = <GIC_SPI 151 IRQ_TYPE_LEVEL_HIGH>;
+ clock-names = "aclk", "iface";
+ clocks = <&cru ACLK_NPU>, <&cru HCLK_NPU>;
+ power-domains = <&power RK3568_PD_NPU>;
+ #iommu-cells = <0>;
+ status = "disabled";
+ };
+
gpu: gpu@fde60000 {
compatible = "rockchip,rk3568-mali", "arm,mali-bifrost";
reg = <0x0 0xfde60000 0x0 0x4000>;
--
2.39.5
^ permalink raw reply related
* [RFC PATCH v4 8/9] arm64: dts: rockchip: rk3568-rock-3b: Enable the NPU
From: MidG971 @ 2026-06-13 7:01 UTC (permalink / raw)
To: tomeu, ogabbay, heiko, robh, krzk+dt, conor+dt, ulf.hansson
Cc: dri-devel, linux-rockchip, devicetree, linux-arm-kernel, linux-pm,
iommu, linux-kernel, xxm, chaoyi.chen, finley.xiao, diederik,
jonas, Midgy BALON
In-Reply-To: <20260613070116.438906-1-midgy971@gmail.com>
From: Midgy BALON <midgy971@gmail.com>
Enable the NPU and its IOMMU on ROCK 3B and wire vdd_npu as the NPU
power domain's domain-supply, so genpd brings the rail up and down with
the domain (the domain is marked need_regulator). The PVTPLL compute
clock is brought up later by the driver.
The rail is no longer kept always-on, so pin it to 1000 mV (the NPU's
1 GHz operating voltage; the driver runs a fixed compute rate with no
devfreq voltage scaling) and mark it boot-on, so it is up before the
power domain de-idles the NPU NoC at power-on.
Signed-off-by: Midgy BALON <midgy971@gmail.com>
---
.../arm64/boot/dts/rockchip/rk3568-rock-3b.dts | 18 ++++++++++++++++--
1 file changed, 16 insertions(+), 2 deletions(-)
diff --git a/arch/arm64/boot/dts/rockchip/rk3568-rock-3b.dts b/arch/arm64/boot/dts/rockchip/rk3568-rock-3b.dts
index 69001e453732e..d3f9776c2bdc3 100644
--- a/arch/arm64/boot/dts/rockchip/rk3568-rock-3b.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3568-rock-3b.dts
@@ -330,9 +330,10 @@ regulator-state-mem {
vdd_npu: DCDC_REG4 {
regulator-name = "vdd_npu";
+ regulator-boot-on;
regulator-initial-mode = <0x2>;
- regulator-min-microvolt = <500000>;
- regulator-max-microvolt = <1350000>;
+ regulator-min-microvolt = <1000000>;
+ regulator-max-microvolt = <1000000>;
regulator-ramp-delay = <6001>;
regulator-state-mem {
@@ -787,3 +788,16 @@ vp0_out_hdmi: endpoint@ROCKCHIP_VOP2_EP_HDMI0 {
remote-endpoint = <&hdmi_in_vp0>;
};
};
+
+&pd_npu {
+ domain-supply = <&vdd_npu>;
+};
+
+&rknn_core_0 {
+ npu-supply = <&vdd_npu>;
+ status = "okay";
+};
+
+&rknn_mmu_0 {
+ status = "okay";
+};
--
2.39.5
^ permalink raw reply related
* [RFC PATCH v4 9/9] pmdomain: rockchip: Add a regulator to the RK3568 NPU power domain
From: MidG971 @ 2026-06-13 7:01 UTC (permalink / raw)
To: tomeu, ogabbay, heiko, robh, krzk+dt, conor+dt, ulf.hansson
Cc: dri-devel, linux-rockchip, devicetree, linux-arm-kernel, linux-pm,
iommu, linux-kernel, xxm, chaoyi.chen, finley.xiao, diederik,
jonas, Midgy BALON
In-Reply-To: <20260613070116.438906-1-midgy971@gmail.com>
From: Midgy BALON <midgy971@gmail.com>
The RK3568 NPU rail (vdd_npu) needs to be enabled before the domain is
powered on and disabled after it is powered off. Give DOMAIN_RK3568 a
regulator parameter (like DOMAIN_RK3588 already has) so the NPU domain
can set need_regulator, letting genpd manage the rail wired up as the
domain's domain-supply instead of marking it always-on in DT.
Suggested-by: Chaoyi Chen <chaoyi.chen@rock-chips.com>
Signed-off-by: Midgy BALON <midgy971@gmail.com>
---
drivers/pmdomain/rockchip/pm-domains.c | 36 ++++++++++++++++++--------
1 file changed, 25 insertions(+), 11 deletions(-)
diff --git a/drivers/pmdomain/rockchip/pm-domains.c b/drivers/pmdomain/rockchip/pm-domains.c
index 490bbb1d1d8e8..19db307e3811d 100644
--- a/drivers/pmdomain/rockchip/pm-domains.c
+++ b/drivers/pmdomain/rockchip/pm-domains.c
@@ -138,6 +138,20 @@ struct rockchip_pmu {
.active_wakeup = wakeup, \
}
+#define DOMAIN_M_R(_name, pwr, status, req, idle, ack, wakeup, regulator) \
+{ \
+ .name = _name, \
+ .pwr_w_mask = (pwr) << 16, \
+ .pwr_mask = (pwr), \
+ .status_mask = (status), \
+ .req_w_mask = (req) << 16, \
+ .req_mask = (req), \
+ .idle_mask = (idle), \
+ .ack_mask = (ack), \
+ .active_wakeup = wakeup, \
+ .need_regulator = regulator, \
+}
+
#define DOMAIN_M_G(_name, pwr, status, req, idle, ack, g_mask, wakeup, keepon) \
{ \
.name = _name, \
@@ -241,8 +255,8 @@ struct rockchip_pmu {
#define DOMAIN_RK3562(name, pwr, req, g_mask, mem, wakeup) \
DOMAIN_M_G_SD(name, pwr, pwr, req, req, req, g_mask, mem, wakeup, false)
-#define DOMAIN_RK3568(name, pwr, req, wakeup) \
- DOMAIN_M(name, pwr, pwr, req, req, req, wakeup)
+#define DOMAIN_RK3568(name, pwr, req, wakeup, regulator) \
+ DOMAIN_M_R(name, pwr, pwr, req, req, req, wakeup, regulator)
#define DOMAIN_RK3576(name, p_offset, pwr, status, r_status, r_offset, req, idle, g_mask, wakeup) \
DOMAIN_M_O_R_G(name, p_offset, pwr, status, 0, r_status, r_status, r_offset, req, idle, idle, g_mask, wakeup)
@@ -1274,15 +1288,15 @@ static const struct rockchip_domain_info rk3562_pm_domains[] = {
};
static const struct rockchip_domain_info rk3568_pm_domains[] = {
- [RK3568_PD_NPU] = DOMAIN_RK3568("npu", BIT(1), BIT(2), false),
- [RK3568_PD_GPU] = DOMAIN_RK3568("gpu", BIT(0), BIT(1), false),
- [RK3568_PD_VI] = DOMAIN_RK3568("vi", BIT(6), BIT(3), false),
- [RK3568_PD_VO] = DOMAIN_RK3568("vo", BIT(7), BIT(4), false),
- [RK3568_PD_RGA] = DOMAIN_RK3568("rga", BIT(5), BIT(5), false),
- [RK3568_PD_VPU] = DOMAIN_RK3568("vpu", BIT(2), BIT(6), false),
- [RK3568_PD_RKVDEC] = DOMAIN_RK3568("vdec", BIT(4), BIT(8), false),
- [RK3568_PD_RKVENC] = DOMAIN_RK3568("venc", BIT(3), BIT(7), false),
- [RK3568_PD_PIPE] = DOMAIN_RK3568("pipe", BIT(8), BIT(11), false),
+ [RK3568_PD_NPU] = DOMAIN_RK3568("npu", BIT(1), BIT(2), false, true),
+ [RK3568_PD_GPU] = DOMAIN_RK3568("gpu", BIT(0), BIT(1), false, false),
+ [RK3568_PD_VI] = DOMAIN_RK3568("vi", BIT(6), BIT(3), false, false),
+ [RK3568_PD_VO] = DOMAIN_RK3568("vo", BIT(7), BIT(4), false, false),
+ [RK3568_PD_RGA] = DOMAIN_RK3568("rga", BIT(5), BIT(5), false, false),
+ [RK3568_PD_VPU] = DOMAIN_RK3568("vpu", BIT(2), BIT(6), false, false),
+ [RK3568_PD_RKVDEC] = DOMAIN_RK3568("vdec", BIT(4), BIT(8), false, false),
+ [RK3568_PD_RKVENC] = DOMAIN_RK3568("venc", BIT(3), BIT(7), false, false),
+ [RK3568_PD_PIPE] = DOMAIN_RK3568("pipe", BIT(8), BIT(11), false, false),
};
static const struct rockchip_domain_info rk3576_pm_domains[] = {
--
2.39.5
^ permalink raw reply related
* [PATCH] dt-bindings: pwm: st,pwm: convert to DT schema
From: Charan Pedumuru @ 2026-06-13 7:04 UTC (permalink / raw)
To: Uwe Kleine-König, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Pal Singh
Cc: linux-pwm, devicetree, linux-kernel, Charan Pedumuru
Convert STMicroelectronics STiH41x PWM/Capture controller binding
to DT schema.
Signed-off-by: Charan Pedumuru <charan.pedumuru@gmail.com>
---
Documentation/devicetree/bindings/pwm/pwm-st.txt | 43 -----------
Documentation/devicetree/bindings/pwm/st,pwm.yaml | 90 +++++++++++++++++++++++
2 files changed, 90 insertions(+), 43 deletions(-)
diff --git a/Documentation/devicetree/bindings/pwm/pwm-st.txt b/Documentation/devicetree/bindings/pwm/pwm-st.txt
deleted file mode 100644
index 19fce774cafa..000000000000
--- a/Documentation/devicetree/bindings/pwm/pwm-st.txt
+++ /dev/null
@@ -1,43 +0,0 @@
-STMicroelectronics PWM driver bindings
---------------------------------------
-
-Required parameters:
-- compatible : "st,pwm"
-- #pwm-cells : Number of cells used to specify a PWM. First cell
- specifies the per-chip index of the PWM to use and the
- second cell is the period in nanoseconds - fixed to 2
- for STiH41x.
-- reg : Physical base address and length of the controller's
- registers.
-- pinctrl-names: Set to "default".
-- pinctrl-0: List of phandles pointing to pin configuration nodes
- for PWM module.
- For Pinctrl properties, please refer to [1].
-- clock-names: Valid entries are "pwm" and/or "capture".
-- clocks: phandle of the clock used by the PWM module.
- For Clk properties, please refer to [2].
-- interrupts: IRQ for the Capture device
-
-Optional properties:
-- st,pwm-num-chan: Number of available PWM channels. Default is 0.
-- st,capture-num-chan: Number of available Capture channels. Default is 0.
-
-[1] Documentation/devicetree/bindings/pinctrl/pinctrl-bindings.txt
-[2] Documentation/devicetree/bindings/clock/clock-bindings.txt
-
-Example:
-
-pwm1: pwm@fe510000 {
- compatible = "st,pwm";
- reg = <0xfe510000 0x68>;
- #pwm-cells = <2>;
- pinctrl-names = "default";
- pinctrl-0 = <&pinctrl_pwm1_chan0_default
- &pinctrl_pwm1_chan1_default
- &pinctrl_pwm1_chan2_default
- &pinctrl_pwm1_chan3_default>;
- clocks = <&clk_sysin>;
- clock-names = "pwm";
- st,pwm-num-chan = <4>;
- st,capture-num-chan = <2>;
-};
diff --git a/Documentation/devicetree/bindings/pwm/st,pwm.yaml b/Documentation/devicetree/bindings/pwm/st,pwm.yaml
new file mode 100644
index 000000000000..2c10f54b5caf
--- /dev/null
+++ b/Documentation/devicetree/bindings/pwm/st,pwm.yaml
@@ -0,0 +1,90 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/pwm/st,pwm.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: STMicroelectronics STiH41x PWM/Capture controller
+
+maintainers:
+ - Ajit Pal Singh <ajitpal.singh@st.com>
+
+description:
+ The STiH41x PWM controller supports both PWM output and input capture
+ functionality. It provides multiple PWM output channels for generating
+ variable duty-cycle waveforms, and multiple input capture channels for
+ measuring external signal periods and pulse widths. PWM output channels
+ and input capture channels are configured independently via
+ st,pwm-num-chan and st,capture-num-chan respectively.
+
+allOf:
+ - $ref: pwm.yaml#
+
+properties:
+ compatible:
+ const: st,pwm
+
+ reg:
+ maxItems: 1
+
+ "#pwm-cells":
+ const: 2
+
+ pinctrl-names:
+ const: default
+
+ clock-names:
+ items:
+ enum: [pwm, capture]
+ minItems: 1
+ maxItems: 2
+
+ clocks:
+ minItems: 1
+ maxItems: 2
+
+ interrupts:
+ description: IRQ line for the capture device.
+ maxItems: 1
+
+ st,pwm-num-chan:
+ $ref: /schemas/types.yaml#/definitions/uint32
+ description: Number of available PWM output channels.
+ minimum: 0
+ maximum: 4
+ default: 0
+
+ st,capture-num-chan:
+ $ref: /schemas/types.yaml#/definitions/uint32
+ description: Number of available input capture channels.
+ minimum: 0
+ maximum: 4
+ default: 0
+
+required:
+ - reg
+ - compatible
+ - "#pwm-cells"
+ - pinctrl-names
+ - clock-names
+ - clocks
+
+unevaluatedProperties: false
+
+examples:
+ - |
+ pwm@fe510000 {
+ compatible = "st,pwm";
+ reg = <0xfe510000 0x68>;
+ #pwm-cells = <2>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_pwm1_chan0_default
+ &pinctrl_pwm1_chan1_default
+ &pinctrl_pwm1_chan2_default
+ &pinctrl_pwm1_chan3_default>;
+ clocks = <&clk_sysin>;
+ clock-names = "pwm";
+ st,pwm-num-chan = <4>;
+ st,capture-num-chan = <2>;
+ };
+...
---
base-commit: c425609d6ac4012c8bbf01ec2e10e801b1923a7b
change-id: 20260613-st-pwm-1feade6cfea3
Best regards,
--
Charan Pedumuru <charan.pedumuru@gmail.com>
^ permalink raw reply related
* Re: [RFC PATCH v4 7/9] arm64: dts: rockchip: rk356x: Add the NPU and its IOMMU
From: sashiko-bot @ 2026-06-13 7:09 UTC (permalink / raw)
To: MidG971; +Cc: robh, conor+dt, devicetree, dri-devel
In-Reply-To: <20260613070116.438906-8-midgy971@gmail.com>
Thank you for your contribution! Sashiko AI review found 2 potential issue(s) to consider:
- [High] Incorrect IOMMU compatible string 'rockchip,iommu' is used for the RK3568 NPU IOMMU, which will cause translation faults.
- [High] The assigned clock rates for the NPU AXI bus and compute core are swapped, severely overclocking the AXI bus.
--
commit a304190b5b1e8ffa602c7c5d7dbdfed3a2c3dcae
Author: Midgy BALON <midgy971@gmail.com>
Subject: arm64: dts: rockchip: rk356x: Add the NPU and its IOMMU
This patch adds the device tree nodes for the NVDLA-derived NPU and its
associated IOMMU on the RK3568 SoC. It configures the clocks, resets, power
domains, and assigns the PMU syscon to manage the NPU NoC bus-idle. The
configuration also intends to bring up the NPU AXI bus clock at 200 MHz.
> diff --git a/arch/arm64/boot/dts/rockchip/rk356x-base.dtsi b/arch/arm64/boot/dts/rockchip/rk356x-base.dtsi
> index 64bdd8b7754b5..313db59c1aed8 100644
> --- a/arch/arm64/boot/dts/rockchip/rk356x-base.dtsi
> +++ b/arch/arm64/boot/dts/rockchip/rk356x-base.dtsi
[ ... ]
> @@ -572,6 +579,37 @@ power-domain@RK3568_PD_RKVENC {
> };
> };
>
> + rknn_core_0: npu@fde40000 {
> + compatible = "rockchip,rk3568-rknn-core";
> + reg = <0x0 0xfde40000 0x0 0x1000>,
> + <0x0 0xfde41000 0x0 0x1000>,
> + <0x0 0xfde43000 0x0 0x1000>;
> + reg-names = "pc", "cna", "core";
> + interrupts = <GIC_SPI 151 IRQ_TYPE_LEVEL_HIGH>;
> + clocks = <&cru ACLK_NPU>, <&cru HCLK_NPU>,
> + <&scmi_clk SCMI_CLK_NPU>, <&cru PCLK_NPU_PRE>;
> + clock-names = "aclk", "hclk", "npu", "pclk";
> + assigned-clocks = <&scmi_clk SCMI_CLK_NPU>, <&cru CLK_NPU>;
> + assigned-clock-rates = <200000000>, <600000000>;
[Severity: High]
Will this configuration inadvertently overclock the AXI bus?
The commit message states the intent to assign the CRU CLK_NPU so the NPU
AXI bus clock comes up at 200 MHz. However, based on the positional mapping
of assigned-clocks to assigned-clock-rates, this assigns 200 MHz to the SCMI
compute core and 600 MHz to CLK_NPU.
Should the values in assigned-clock-rates be swapped to match the order
in assigned-clocks to prevent bus hangs?
> + resets = <&cru SRST_A_NPU>, <&cru SRST_H_NPU>;
> + reset-names = "srst_a", "srst_h";
> + power-domains = <&power RK3568_PD_NPU>;
> + rockchip,pmu = <&pmu>;
> + iommus = <&rknn_mmu_0>;
> + status = "disabled";
> + };
> +
> + rknn_mmu_0: iommu@fde4b000 {
> + compatible = "rockchip,iommu";
[Severity: High]
Does this compatible string correctly identify the v2 IOMMU hardware
present on the RK3568?
Using rockchip,iommu binds to the v1 hardware operations in the Rockchip
IOMMU driver. Because the RK3568 features a v2 IOMMU, configuring it with
v1 driver operations could result in incorrect page table programming and
translation faults when the NPU attempts DMA.
Other IOMMU nodes in rk356x-base.dtsi use rockchip,rk3568-iommu. Should
this node use that compatible string instead?
> + reg = <0x0 0xfde4b000 0x0 0x40>;
> + interrupts = <GIC_SPI 151 IRQ_TYPE_LEVEL_HIGH>;
> + clock-names = "aclk", "iface";
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260613070116.438906-1-midgy971@gmail.com?part=7
^ permalink raw reply
* Re: [PATCH v3 0/2] dt-bindings: mmc: st,sdhci: convert STMicroelectronics SDHCI-ST MMC/SD Controller controller binding to YAML
From: Charan Pedumuru @ 2026-06-13 7:09 UTC (permalink / raw)
To: Ulf Hansson
Cc: Ulf Hansson, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Peter Griffin, Patrice Chotard, linux-mmc, devicetree,
linux-kernel, linux-arm-kernel
In-Reply-To: <CAPx+jO9woUB9VGUx+ebWD9oOhqCwzXL9=41MEesnWS15Nyr66g@mail.gmail.com>
On 29-05-2026 17:40, Ulf Hansson wrote:
> On Fri, May 8, 2026 at 7:23 PM Charan Pedumuru
> <charan.pedumuru@gmail.com> wrote:
>>
>> This patch series converts the legacy text-based Device Tree binding for
>> STMicroelectronics SDHCI-ST MMC/SD controller to DT schema (YAML) format.
>>
>> Note:
>> The patch "dt-bindings: mmc: st,sdhci: convert to DT schema"
>> depends on the patch "arm: dts: st: align node patterns with established
>> convention". If the DT schema patch is applied before the DTS
>> cleanup patch, `dtbs_check` will fail due to the presence of the removed
>> properties in the existing DTS.
>>
>> Signed-off-by: Charan Pedumuru <charan.pedumuru@gmail.com>
>
> The series looks good to me, but awaiting and ack from some of the dt
> maintainers before applying.
Yeah, but until now they is no response from anyone.
>
> As the change in patch2 for arch/arm/boot/dts/st/stih407-family.dtsi
> doesn't seem to cause any conflict from soc maintainer trees point of
> view, I can pick this up too when applying.
Sure.
>
> Kind regards
> Uffe
>
>
>> ---
>> Changes in v3:
>> - st,sdhci: Edit description of reg property. Modify reg-names. Add
>> "minItems" for clocks and clock-names properties.
>> - Modify the commit message to match with the updated changes.
>> - Link to v2: https://patch.msgid.link/20260503-st-mmc-v2-0-11ae3216d2ce@gmail.com
>>
>> Changes in v2:
>> - Fix node name in DTS for the MMC to match with the estableshed convention.
>> - st,sdhci: drop unnecessary properties, modify "reg", "reg-names" and
>> "clock-names" properties, include an allOf with $ref to mmc-controller.
>> - Link to v1: https://patch.msgid.link/20260409-st-mmc-v1-1-4c54321c3535@gmail.com
>>
>> ---
>> Charan Pedumuru (2):
>> arm: dts: st: align node patterns with established convention
>> dt-bindings: mmc: st,sdhci: convert to DT schema
>>
>> Documentation/devicetree/bindings/mmc/sdhci-st.txt | 110 ---------------------
>> .../devicetree/bindings/mmc/st,sdhci.yaml | 91 +++++++++++++++++
>> arch/arm/boot/dts/st/stih407-family.dtsi | 4 +-
>> 3 files changed, 93 insertions(+), 112 deletions(-)
>> ---
>> base-commit: cf2cd8efd046c561191b8541d32a8bfe845bf06b
>> change-id: 20260327-st-mmc-c906ad95ff83
>>
>> Best regards,
>> --
>> Charan Pedumuru <charan.pedumuru@gmail.com>
--
Best Regards,
Charan.
^ permalink raw reply
* Re: [RFC PATCH v4 2/9] accel: rocket: Derive DMA width and core count from match data
From: sashiko-bot @ 2026-06-13 7:09 UTC (permalink / raw)
To: MidG971; +Cc: conor+dt, dri-devel, devicetree, robh
In-Reply-To: <20260613070116.438906-3-midgy971@gmail.com>
Thank you for your contribution! Sashiko AI review found 6 potential issue(s) to consider:
New issues:
- [High] The bounds check for the 'cores' array uses the current node's match data rather than the allocated capacity, allowing an out-of-bounds write if the device tree has mixed compatible strings.
Pre-existing issues:
- [High] If `rocket_device_init()` fails, the global `rdev` pointer is left containing an `ERR_PTR`, causing a kernel panic on subsequent core probes.
- [High] Global DRM device and core arrays are allocated using `devm_` helpers tied to the first probed core's lifecycle, causing a Use-After-Free when that core is unbound.
- [High] Removing and re-probing NPU cores out of order corrupts the 'cores' array because 'num_cores' is incorrectly used as both an active count and the array index.
- [High] Missing locking around the global `rdev` initialization and `rdev->num_cores` access allows concurrent probes to corrupt device tracking and leak allocations.
- [High] The DRM device is registered before its hardware cores are fully initialized, allowing userspace to trigger a NULL pointer dereference.
--
commit a4289515ae9af5aaa001a280a8b52c1288f26e24
Author: Midgy BALON <midgy971@gmail.com>
One line subject: accel: rocket: Derive DMA width and core count from match data
The probe already has the per-SoC match data, which now records the core
count and DMA width. This patch uses it for the cores array allocation and
the device DMA mask instead of re-scanning the device tree for available
core nodes. It also rejects a device tree that declares more NPU core nodes
than the SoC has to prevent overrun.
> diff --git a/drivers/accel/rocket/rocket_device.c b/drivers/accel/rocket/rocket_device.c
> index 46e6ee1e72c5f..6186f4faa3a2a 100644
> --- a/drivers/accel/rocket/rocket_device.c
> +++ b/drivers/accel/rocket/rocket_device.c
> @@ -6,18 +6,16 @@
> #include <linux/clk.h>
> #include <linux/dma-mapping.h>
> #include <linux/platform_device.h>
> -#include <linux/of.h>
>
> #include "rocket_device.h"
>
> struct rocket_device *rocket_device_init(struct platform_device *pdev,
> - const struct drm_driver *rocket_drm_driver)
> + const struct drm_driver *rocket_drm_driver,
> + const struct rocket_soc_data *soc_data)
> {
> struct device *dev = &pdev->dev;
> - struct device_node *core_node;
> struct rocket_device *rdev;
> struct drm_device *ddev;
> - unsigned int num_cores = 0;
> int err;
>
> rdev = devm_drm_dev_alloc(dev, rocket_drm_driver, struct rocket_device, ddev);
> @@ -27,17 +25,14 @@ struct rocket_device *rocket_device_init(struct platform_device *pdev,
> ddev = &rdev->ddev;
> dev_set_drvdata(dev, rdev);
>
> - for_each_compatible_node(core_node, NULL, "rockchip,rk3588-rknn-core")
> - if (of_device_is_available(core_node))
> - num_cores++;
> -
> - rdev->cores = devm_kcalloc(dev, num_cores, sizeof(*rdev->cores), GFP_KERNEL);
> + rdev->cores = devm_kcalloc(dev, soc_data->num_cores, sizeof(*rdev->cores),
> + GFP_KERNEL);
[Severity: High]
This is a pre-existing issue, but does using devres tied to the first
probed core's lifecycle cause a use-after-free when that core is unbound?
If userspace unbinds this first core via sysfs, rocket_remove() decrements
num_cores but does not explicitly clean up the DRM device because other
cores are still bound. Upon returning from remove, the driver core
automatically frees all devres tied to the first core's device. This
would destroy the global rdev memory, causing a use-after-free when any
remaining cores attempt to access it.
[Severity: High]
This is a pre-existing issue, but does registering the DRM device
before its hardware cores are fully initialized allow userspace to
trigger a NULL pointer dereference?
In rocket_device_init(), the driver calls drm_dev_register() to expose
the character device to userspace. This occurs before the caller,
rocket_probe(), populates rdev->cores[0].dev and initializes the hardware.
If userspace opens the device during this small timing window,
rocket_open() is called and invokes:
rocket_iommu_domain_create(rdev->cores[0].dev);
Since the device pointer is still NULL, this would attempt to dereference
a NULL device pointer in the IOMMU subsystem, crashing the system.
[ ... ]
> diff --git a/drivers/accel/rocket/rocket_drv.c b/drivers/accel/rocket/rocket_drv.c
> index 384c38e13acce..f0beed2d522c7 100644
> --- a/drivers/accel/rocket/rocket_drv.c
> +++ b/drivers/accel/rocket/rocket_drv.c
> @@ -159,11 +159,15 @@ static const struct drm_driver rocket_drm_driver = {
>
> static int rocket_probe(struct platform_device *pdev)
> {
> + const struct rocket_soc_data *soc_data = of_device_get_match_data(&pdev->dev);
> int ret;
>
> + if (!soc_data)
> + return -EINVAL;
> +
> if (rdev == NULL) {
[Severity: High]
This is a pre-existing issue, but does the lack of locking around the global
rdev initialization allow concurrent probes to corrupt device tracking
and leak memory?
If concurrent probes occur (for example, via asynchronous probing or
concurrent sysfs binds), multiple threads can pass this if check,
causing multiple DRM device allocations. They can also read the same
num_cores value, leading both threads to overwrite the same index in the
rdev->cores array.
> /* First core probing, initialize DRM device. */
> - rdev = rocket_device_init(drm_dev, &rocket_drm_driver);
> + rdev = rocket_device_init(drm_dev, &rocket_drm_driver, soc_data);
> if (IS_ERR(rdev)) {
> dev_err(&pdev->dev, "failed to initialize rocket device\n");
> return PTR_ERR(rdev);
[Severity: High]
This is a pre-existing issue, but does this error path leave the global
rdev pointer containing an ERR_PTR?
If rocket_device_init() fails, it returns an error pointer which is
assigned to the global rdev. The function then returns the error but fails
to reset rdev to NULL.
When the next core probes, the (rdev == NULL) check is bypassed, and the
driver immediately dereferences the error pointer when reading
rdev->num_cores:
unsigned int core = rdev->num_cores;
Could this lead to a reproducible kernel panic?
> @@ -172,6 +176,12 @@ static int rocket_probe(struct platform_device *pdev)
>
> unsigned int core = rdev->num_cores;
>
> + if (core >= soc_data->num_cores) {
[Severity: High]
Does this bounds check use the current node's capacity rather than the
array's actual allocated size?
The array rdev->cores is permanently allocated using soc_data->num_cores
from the first probed device in rocket_device_init(). However, this bounds
check evaluates against the soc_data of the current probing device.
If a device tree or overlay declares a node with a smaller num_cores
followed by one with a larger num_cores, the check will pass for an index
that exceeds the initial allocation size. Will this cause a direct
out-of-bounds write into the rdev->cores array, corrupting kernel memory?
> + dev_err(&pdev->dev, "too many NPU core nodes (max %u)\n",
> + soc_data->num_cores);
> + return -EINVAL;
> + }
> +
> dev_set_drvdata(&pdev->dev, rdev);
>
> rdev->cores[core].rdev = rdev;
[Severity: High]
This is a pre-existing issue, but does removing and re-probing NPU cores
out of order corrupt the cores array?
When a core is removed, rocket_remove() decrements rdev->num_cores
without shifting the remaining cores in the array to close the gap:
rdev->num_cores--;
If cores are removed out of order, active cores are left at indices equal
to or greater than the new num_cores. The driver later uses num_cores as its
search bound, making those trailing active cores unreachable.
Furthermore, if a new core is probed, it assigns itself to the index
rdev->num_cores, blindly overwriting a still-active core:
rdev->cores[core].rdev = rdev;
Could this cause state corruption and resource leaks?
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260613070116.438906-1-midgy971@gmail.com?part=2
^ permalink raw reply
* Re: [RFC PATCH v4 1/9] accel: rocket: Introduce per-SoC rocket_soc_data
From: sashiko-bot @ 2026-06-13 7:10 UTC (permalink / raw)
To: MidG971; +Cc: robh, conor+dt, dri-devel, devicetree
In-Reply-To: <20260613070116.438906-2-midgy971@gmail.com>
Thank you for your contribution! Sashiko AI review found 4 potential issue(s) to consider:
Pre-existing issues:
- [High] The shared IRQ handler accesses hardware registers without checking if the device is active.
- [High] The runtime suspend callback disables hardware clocks without synchronizing the shared IRQ.
- [High] The global `rdev` pointer is not reset to NULL when initialization fails, causing a kernel panic on subsequent probes.
- [High] Hardware registers are read during probe without ensuring the device resets are explicitly deasserted.
--
commit e068c6d40922642be56ef8ce61fd76a8d5727d7c
Author: Midgy BALON <midgy971@gmail.com>
accel: rocket: Introduce per-SoC rocket_soc_data
Add a per-SoC data structure carried in the OF match table, currently
holding only the NPU AXI address width, and use it for the per-core DMA
mask instead of a hardcoded 40-bit value.
> diff --git a/drivers/accel/rocket/rocket_core.c b/drivers/accel/rocket/rocket_core.c
> index b3b2fa9ba645a..09c445af7de73 100644
> --- a/drivers/accel/rocket/rocket_core.c
> +++ b/drivers/accel/rocket/rocket_core.c
> @@ -21,6 +22,10 @@ int rocket_core_init(struct rocket_core *core)
> u32 version;
> int err = 0;
>
> + core->soc_data = of_device_get_match_data(dev);
> + if (!core->soc_data)
> + return dev_err_probe(dev, -EINVAL, "missing SoC match data\n");
> +
> core->resets[0].id = "srst_a";
> core->resets[1].id = "srst_h";
> err = devm_reset_control_bulk_get_exclusive(&pdev->dev, ARRAY_SIZE(core->resets),
[Severity: High]
This isn't a bug introduced by this patch, but I noticed hardware registers are
read during probe without ensuring the device resets are explicitly deasserted.
Later in rocket_core_init():
version = rocket_pc_readl(core, VERSION);
If the bootloader leaves the NPU in an asserted reset state, attempting to
read its registers will cause a synchronous external abort. Would it make
sense to deassert the resets before accessing registers here?
[ ... ]
> diff --git a/drivers/accel/rocket/rocket_drv.c b/drivers/accel/rocket/rocket_drv.c
> index 8bbbce594883e..384c38e13acce 100644
> --- a/drivers/accel/rocket/rocket_drv.c
> +++ b/drivers/accel/rocket/rocket_drv.c
[ ... ]
> @@ -213,8 +213,12 @@ static void rocket_remove(struct platform_device *pdev)
> }
> }
[Severity: High]
This is a pre-existing issue, but I noticed the global rdev pointer is not
reset to NULL when initialization fails in rocket_probe() in this file:
rdev = rocket_device_init(drm_dev, &rocket_drm_driver, soc_data);
if (IS_ERR(rdev)) {
...
return PTR_ERR(rdev);
}
If this fails during the first core's probe, an error pointer is assigned to
the global rdev pointer without being cleared. On the next core's probe, the
check for NULL will fail and it will blindly dereference the error pointer.
Could this be addressed by clearing the global pointer on the error path?
[Severity: High]
This is a pre-existing issue, but the runtime suspend callback in this driver
disables hardware clocks without synchronizing the shared IRQ:
rocket_device_runtime_suspend() {
...
clk_bulk_disable_unprepare(ARRAY_SIZE(rdev->cores[core].clks), ...);
...
}
Should this call synchronize_irq() first to avoid a race condition where the
IRQ handler might be executing mid-flight on another CPU while the hardware
is powered down?
[Severity: High]
This is a pre-existing issue, but in drivers/accel/rocket/rocket_job.c, the
shared IRQ handler accesses hardware registers without checking if the device
is active:
rocket_job_irq_handler() {
...
u32 raw_status = rocket_pc_readl(core, INTERRUPT_RAW_STATUS);
...
}
Because the IRQ is registered with IRQF_SHARED, if the handler is invoked by
another device while the NPU is runtime suspended, reading the registers can
result in invalid data (~0u) and spurious interrupts. Should it use
pm_runtime_get_if_active() before reading the status register?
[ ... ]
> static const struct of_device_id dt_match[] = {
> - { .compatible = "rockchip,rk3588-rknn-core" },
> + { .compatible = "rockchip,rk3588-rknn-core", .data = &rk3588_soc_data },
> {}
> };
> MODULE_DEVICE_TABLE(of, dt_match);
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260613070116.438906-1-midgy971@gmail.com?part=1
^ permalink raw reply
* Re: [RFC PATCH v4 6/9] dt-bindings: npu: rockchip,rk3588-rknn-core: Add RK3568
From: sashiko-bot @ 2026-06-13 7:11 UTC (permalink / raw)
To: MidG971; +Cc: conor+dt, robh, devicetree, dri-devel
In-Reply-To: <20260613070116.438906-7-midgy971@gmail.com>
Thank you for your contribution! Sashiko AI review found 5 potential issue(s) to consider:
Pre-existing issues:
- [Critical] Double free of `rjob->tasks` leading to memory corruption triggerable from userspace.
- [Critical] Unconditional dereference of a NULL `job->domain` triggering a kernel panic on early job submission failure.
- [High] Permanent PM runtime reference count leak when `iommu_attach_group()` fails.
- [High] Zero-initialized clock IDs cause the framework to fetch the same clock repeatedly, violating hardware constraints.
- [Medium] Premature DRM device registration exposes an incomplete state to userspace.
--
commit d0d76b931ac773e3e176353cdb3ac9c590c43dc3
Author: Midgy BALON <midgy971@gmail.com>
dt-bindings: npu: rockchip, rk3588-rknn-core: Add RK3568
The RK3568 carries a single core of the same NVDLA-derived NPU IP as the
RK3588. Add its compatible.
> diff --git a/Documentation/devicetree/bindings/npu/rockchip,rk3588-rknn-core.yaml b/Documentation/devicetree/bindings/npu/rockchip,rk3588-rknn-core.yaml
> index caca2a4903cd1..e0b948ac47d45 100644
> --- a/Documentation/devicetree/bindings/npu/rockchip,rk3588-rknn-core.yaml
> +++ b/Documentation/devicetree/bindings/npu/rockchip,rk3588-rknn-core.yaml
[ ... ]
drivers/accel/rocket/rocket_device.c:rocket_device_init() {
...
err = drm_dev_register(ddev, 0);
...
}
drivers/accel/rocket/rocket_drv.c:rocket_probe() {
...
rdev->cores[core].dev = &pdev->dev;
...
}
[Severity: Medium]
This is a pre-existing issue, but does this premature registration expose an
incomplete state to userspace?
drm_dev_register() is called in rocket_device_init() before rocket_probe()
assigns rdev->cores[0].dev.
As a result, the device node is briefly visible to userspace while its core
structures remain partially uninitialized.
If userspace attempts to open the DRM device during this window, rocket_open()
passes the NULL rdev->cores[0].dev to rocket_iommu_domain_create().
While the IOMMU framework safely catches the NULL device and returns -ENODEV,
this still causes a spurious open() failure for userspace applications relying
on udev events.
drivers/accel/rocket/rocket_job.c:rocket_job_run() {
...
ret = pm_runtime_get_sync(core->dev);
if (ret < 0)
return fence;
...
ret = iommu_attach_group(job->domain->domain, core->iommu_group);
if (ret < 0)
return fence;
...
}
[Severity: High]
This is a pre-existing issue, but does this cause a permanent PM runtime
reference count leak when iommu_attach_group() fails?
In rocket_job_run(), pm_runtime_get_sync() increments the PM usage count to wake
up the NPU.
If the subsequent iommu_attach_group() fails, the driver returns the allocated
fence and exits early without calling pm_runtime_put().
Because the driver exits before assigning core->in_flight_job, the subsequent
timeout handler rocket_reset() will also skip the manual
pm_runtime_put_noidle().
This causes a permanent PM runtime reference count leak, preventing the NPU
hardware from ever entering runtime suspend.
drivers/accel/rocket/rocket_core.c:rocket_core_init() {
...
err = devm_clk_bulk_get(dev, ARRAY_SIZE(core->clks), core->clks);
...
}
[Severity: High]
This is a pre-existing issue, but do these zero-initialized clock IDs cause the
framework to fetch the same clock repeatedly?
In rocket_core_init(), the driver declares an array of clk_bulk_data but never
initializes the .id fields, leaving them implicitly NULL.
When devm_clk_bulk_get() is called, the clock framework handles the NULL IDs by
returning the first clock defined in the device tree for the device on all four
iterations.
Consequently, rocket_device_runtime_resume() enables the exact same clock four
times, while the remaining required clocks are left disabled.
This violates physical hardware state requirements and causes unclocked NPU
register accesses.
drivers/accel/rocket/rocket_job.c:rocket_copy_tasks() {
...
fail:
kvfree(rjob->tasks);
return ret;
}
drivers/accel/rocket/rocket_job.c:rocket_job_cleanup() {
...
kvfree(job->tasks);
...
}
[Severity: Critical]
This is a pre-existing issue, but does this lead to a double free of rjob->tasks
that can be triggered from userspace?
In rocket_copy_tasks(), if copy_from_user() fails, kvfree(rjob->tasks) is
called, but the pointer rjob->tasks is not cleared.
The function returns an error to rocket_ioctl_submit_job(), which jumps to
out_cleanup_job and invokes rocket_job_put().
When the reference count drops, rocket_job_cleanup() is executed,
unconditionally calling kvfree(job->tasks) again on the already freed memory
block.
Since the IOCTL input is fully controlled by userspace, an unprivileged attacker
can trigger a double free by submitting an invalid task pointer.
drivers/accel/rocket/rocket_job.c:rocket_ioctl_submit_job() {
...
rjob = kzalloc_obj(*rjob);
...
ret = rocket_copy_tasks(dev, file, job, rjob);
if (ret)
goto out_cleanup_job;
...
}
drivers/accel/rocket/rocket_drv.c:rocket_iommu_domain_put() {
...
kref_put(&domain->kref, rocket_iommu_domain_destroy);
...
}
[Severity: Critical]
This is a pre-existing issue, but does this unconditionally dereference a NULL
job->domain, triggering a kernel panic on early job submission failure?
In rocket_ioctl_submit_job(), rjob is allocated via kzalloc_obj(), leaving
rjob->domain initialized to NULL.
If a failure occurs before the domain is assigned, such as an invalid task
pointer in rocket_copy_tasks() or a bad BO handle in drm_gem_objects_lookup(),
the driver jumps to the cleanup path.
The cleanup handler, rocket_job_cleanup(), unconditionally passes the NULL
domain to rocket_iommu_domain_put(), which invokes kref_put(&domain->kref, ...).
Computing &domain->kref yields an offset address, and refcount_dec_and_test()
immediately dereferences this invalid address, resulting in a kernel panic that
can be triggered by unprivileged userspace.
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260613070116.438906-1-midgy971@gmail.com?part=6
^ permalink raw reply
* Re: [RFC PATCH v4 3/9] accel: rocket: Add RK3568 SoC support
From: sashiko-bot @ 2026-06-13 7:11 UTC (permalink / raw)
To: MidG971; +Cc: conor+dt, robh, dri-devel, devicetree
In-Reply-To: <20260613070116.438906-4-midgy971@gmail.com>
Thank you for your contribution! Sashiko AI review found 5 potential issue(s) to consider:
New issues:
- [High] `pm_runtime_put_sync()` fails to suspend the device synchronously due to active autosuspend, leaking runtime PM state when `noc_init` fails.
- [High] `rk3568_noc_init()` ignores `clk_set_rate()` failures and incorrectly uses short-circuiting logic, allowing initialization to proceed with an inactive compute clock.
- [High] The RK3568 NPU compute clock (PVTPLL) is not restarted during runtime resume, leading to a hardware hang.
Pre-existing issues:
- [High] Uninitialized bulk clock IDs cause the driver to silently fail at managing the NPU's actual clocks, fetching the identical default clock repeatedly.
- [High] `devm_drm_dev_alloc()` memory is leaked on probe deferral because it is allocated on a global facade device.
--
commit 18b5e0abd4d8cdab9122360b8a9bd630b4573645
Author: Midgy BALON <midgy971@gmail.com>
accel: rocket: Add RK3568 SoC support
The RK3568 has a single core of the same NVDLA-derived NPU IP as the
RK3588, with a 32-bit AXI master. Add rk3568_soc_data and its
compatible.
Unlike the RK3588, the RK3568 NPU's compute clock is a PVTPLL managed by
TF-A via SCMI; start it from an noc_init callback with a real rate change
(an intermediate rate defeats the clock framework's unchanged-rate
shortcut). Powering on and de-idling the NPU NoC are left to the power
domain (genpd), which performs them when the IOMMU supplier is resumed,
so the driver does not poke the PMU directly.
If noc_init fails, unwind through rocket_core_fini() so the core is torn
down completely rather than leaking the runtime-PM and IOMMU state.
> diff --git a/drivers/accel/rocket/rocket_core.c b/drivers/accel/rocket/rocket_core.c
> index 09c445af7de73..779e951596a15 100644
> --- a/drivers/accel/rocket/rocket_core.c
> +++ b/drivers/accel/rocket/rocket_core.c
> @@ -88,6 +88,15 @@ int rocket_core_init(struct rocket_core *core)
> return err;
> }
>
> + if (core->soc_data->noc_init) {
> + err = core->soc_data->noc_init(core);
> + if (err) {
> + pm_runtime_put_sync(dev);
[Severity: High]
Does this error path leak the runtime PM state?
Since rocket_core_init() enables autosuspend via pm_runtime_use_autosuspend(),
calling pm_runtime_put_sync() behaves asynchronously and schedules an
autosuspend timer instead of suspending immediately.
Then rocket_core_fini() calls pm_runtime_disable() which cancels pending
timers without suspending the device. Does this leave the device permanently
in the RPM_ACTIVE state and keep the power domain powered on?
> + rocket_core_fini(core);
> + return err;
> + }
> + }
> +
> version = rocket_pc_readl(core, VERSION);
> version += rocket_pc_readl(core, VERSION_NUM) & 0xffff;
[ ... ]
> diff --git a/drivers/accel/rocket/rocket_drv.c b/drivers/accel/rocket/rocket_drv.c
> index f0beed2d522c7..86484110ad6f0 100644
> --- a/drivers/accel/rocket/rocket_drv.c
> +++ b/drivers/accel/rocket/rocket_drv.c
[ ... ]
> @@ -223,12 +224,42 @@ static void rocket_remove(struct platform_device *pdev)
> }
> }
>
> +/*
> + * The NPU compute clock is a PVTPLL managed by TF-A via SCMI; spin it up
> + * with a real rate change (an intermediate rate defeats the clock
> + * framework's unchanged-rate shortcut). Powering on and de-idling the NPU
> + * NoC are handled by the power domain (genpd) before the NPU is accessed.
> + */
> +static int rk3568_noc_init(struct rocket_core *core)
> +{
> + struct clk *npu_clk;
> +
> + npu_clk = of_clk_get_by_name(core->dev->of_node, "npu");
> + if (IS_ERR(npu_clk))
> + return dev_err_probe(core->dev, PTR_ERR(npu_clk),
> + "failed to get the NPU SCMI clock\n");
> +
> + if (clk_set_rate(npu_clk, 600000000UL) ||
> + clk_set_rate(npu_clk, 1000000000UL))
[Severity: High]
Does this logical OR prevent the second rate change from executing if the
first one fails?
If clk_set_rate() fails for the first call, the short-circuiting logic will
prevent the second clk_set_rate() from running.
> + dev_warn(core->dev, "failed to set the NPU compute clock rate\n");
> + clk_put(npu_clk);
> +
> + return 0;
[Severity: High]
Should this return an error code if the clock rate fails to set?
Returning 0 here allows initialization to proceed even if the compute clock
is inactive. When rocket_core_init() subsequently reads the NPU VERSION
register over the AXI bus, will this cause a system hang due to the
inactive clock?
> +}
[Severity: High]
This isn't a bug introduced by this patch, but does rocket_core_init() fail
to properly initialize the bulk clock IDs?
When rdev->cores is allocated with devm_kcalloc(), the core->clks array is
initialized with NULL pointers for the .id fields.
When rocket_core_init() later fetches the clocks:
err = devm_clk_bulk_get(dev, ARRAY_SIZE(core->clks), core->clks);
With NULL .id strings, clk_get() will repeatedly fetch the first clock listed
in the device tree's clocks property for all elements. Does this leave the
other NPU clocks unmanaged and potentially disabled, leading to AXI bus
hangs?
[Severity: High]
This isn't a bug introduced by this patch, but is there a memory leak in the
probe deferral path for devm_drm_dev_alloc()?
In rocket_device_init(), rdev is allocated on the global drm_dev:
rdev = devm_drm_dev_alloc(drm_dev->dev, ...);
If rocket_core_init() fails (e.g. returning -EPROBE_DEFER), rocket_probe()
clears the rdev pointer but the devm resources are tied to the static global
drm_dev which is never removed.
When probe is retried, does this result in allocating a new struct
rocket_device and leaking the previous allocation permanently?
[Severity: High]
Does the driver fail to restart the NPU compute clock during runtime resume?
During runtime suspend, the NPU power domain (DOMAIN_RK3568) is powered off
and the PVTPLL loses state.
On runtime resume, rocket_device_runtime_resume() enables the bulk clocks:
err = clk_bulk_prepare_enable(ARRAY_SIZE(rdev->cores[core].clks),
rdev->cores[core].clks);
But it doesn't re-apply the rate-change sequence used in rk3568_noc_init() to
force TF-A to spin the clock up. Will this cause the hardware to hang on the
next NPU access because the compute clock remains off?
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260613070116.438906-1-midgy971@gmail.com?part=3
^ permalink raw reply
* Re: [RFC PATCH v4 5/9] accel: rocket: Keep the IOMMU domain attached across jobs
From: sashiko-bot @ 2026-06-13 7:12 UTC (permalink / raw)
To: MidG971; +Cc: conor+dt, dri-devel, devicetree, robh
In-Reply-To: <20260613070116.438906-6-midgy971@gmail.com>
Thank you for your contribution! Sashiko AI review found 3 potential issue(s) to consider:
New issues:
- [High] rocket_core_fini() tears down the IOMMU domain without quiescing the hardware, causing IOMMU faults and wedged hardware.
Pre-existing issues:
- [High] Error paths in rocket_job_run() leak the PM runtime usage counter and return an unsignaled fence, causing permanent power drain and spurious timeouts.
- [High] Job timeout recovery leaves the NPU permanently powered on due to pm_runtime_put_noidle().
--
commit 629253998abe2060bd2b43f469323132b5743d36
Author: Midgy BALON <midgy971@gmail.com>
Subject: accel: rocket: Keep the IOMMU domain attached across jobs
This commit attaches the IOMMU domain once per context instead of toggling
it on every job to avoid hardware stall timeouts. The domain is released on
context swap, core reset, or core teardown.
> diff --git a/drivers/accel/rocket/rocket_core.c b/drivers/accel/rocket/rocket_core.c
> index 779e951596a15..6c128f585cff4 100644
> --- a/drivers/accel/rocket/rocket_core.c
> +++ b/drivers/accel/rocket/rocket_core.c
[ ... ]
> @@ -112,9 +113,20 @@ void rocket_core_fini(struct rocket_core *core)
> {
> pm_runtime_dont_use_autosuspend(core->dev);
> pm_runtime_disable(core->dev);
> +
> + /*
> + * Stop the scheduler before tearing down the IOMMU so an in-flight
> + * job can no longer touch the (about to be detached) domain.
> + */
> + rocket_job_fini(core);
> +
> + if (core->attached_domain) {
> + iommu_detach_group(NULL, core->iommu_group);
[Severity: High]
Does this detach the IOMMU page tables while the hardware is still active?
Calling drm_sched_fini() inside rocket_job_fini() only stops the software
scheduling thread, but it doesn't wait for the currently executing job on
the hardware to complete or reset the AXI master. Detaching the group while
the NPU is still executing could cause memory translation faults and wedge
the hardware.
Should the hardware be explicitly quiesced, for example by calling
rocket_core_reset(), before the IOMMU is detached here?
> + rocket_iommu_domain_put(core->attached_domain);
> + core->attached_domain = NULL;
> + }
> iommu_group_put(core->iommu_group);
> core->iommu_group = NULL;
> - rocket_job_fini(core);
> }
>
> void rocket_core_reset(struct rocket_core *core)
> diff --git a/drivers/accel/rocket/rocket_job.c b/drivers/accel/rocket/rocket_job.c
> index e25234261536b..368b2ebead1b3 100644
> --- a/drivers/accel/rocket/rocket_job.c
> +++ b/drivers/accel/rocket/rocket_job.c
[ ... ]
> @@ -314,9 +315,26 @@ static struct dma_fence *rocket_job_run(struct drm_sched_job *sched_job)
> if (ret < 0)
> return fence;
>
> - ret = iommu_attach_group(job->domain->domain, core->iommu_group);
> - if (ret < 0)
> - return fence;
[Severity: High]
This isn't a bug introduced by this patch, but does the pm_runtime_get_sync
error path just above this leak the PM runtime usage counter?
In rocket_job_run(), the code does:
ret = pm_runtime_get_sync(core->dev);
if (ret < 0)
return fence;
If pm_runtime_get_sync() fails, returning without calling
pm_runtime_put_noidle() leaves the counter elevated.
> + /*
> + * Attach the job's IOMMU domain only when it differs from the one
> + * already attached. Re-attaching per job toggles the rk_iommu
> + * stall/reset handshake on an idle NPU MMU, which is slow and
> + * noisy; keep the domain attached across jobs instead.
> + */
> + if (core->attached_domain != job->domain) {
> + if (core->attached_domain) {
> + iommu_detach_group(NULL, core->iommu_group);
> + rocket_iommu_domain_put(core->attached_domain);
> + core->attached_domain = NULL;
> + }
> +
> + ret = iommu_attach_group(job->domain->domain, core->iommu_group);
> + if (ret < 0)
> + return fence;
[Severity: High]
This is a pre-existing issue, but does this error path leak the PM runtime
reference acquired earlier in this function?
Since the in_flight_job isn't set yet when returning the fence here, the
subsequent timeout handler won't clean this up, preventing the device from
ever entering low power states.
> +
> + kref_get(&job->domain->kref);
> + core->attached_domain = job->domain;
> + }
>
> scoped_guard(mutex, &core->job_lock) {
> core->in_flight_job = job;
[ ... ]
> @@ -376,7 +393,15 @@ rocket_reset(struct rocket_core *core, struct drm_sched_job *bad)
[Severity: High]
This isn't a bug introduced by this patch, but does job timeout recovery
leave the NPU permanently powered on?
Earlier in rocket_reset(), the usage counter is decremented:
scoped_guard(mutex, &core->job_lock) {
if (core->in_flight_job)
pm_runtime_put_noidle(core->dev);
core->in_flight_job = NULL;
}
Because pm_runtime_put_noidle() does not invoke an idle check or queue an
auto-suspend, doesn't the device remain in the RPM_ACTIVE state and stay
physically powered on indefinitely? Should pm_runtime_put_autosuspend() be
used here instead?
> */
> rocket_core_reset(core);
>
> - iommu_detach_group(NULL, core->iommu_group);
> + /*
> + * The reset wipes the IOMMU page-table base, so drop the attached
> + * domain to force the next job to re-attach and reprogram it.
> + */
> + if (core->attached_domain) {
> + iommu_detach_group(NULL, core->iommu_group);
> + rocket_iommu_domain_put(core->attached_domain);
> + core->attached_domain = NULL;
> + }
>
> /* NPU has been reset, we can clear the reset pending bit. */
> atomic_set(&core->reset.pending, 0);
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260613070116.438906-1-midgy971@gmail.com?part=5
^ permalink raw reply
* Re: [PATCH] dt-bindings: pwm: st,pwm: convert to DT schema
From: sashiko-bot @ 2026-06-13 7:13 UTC (permalink / raw)
To: Charan Pedumuru; +Cc: conor+dt, devicetree, robh
In-Reply-To: <20260613-st-pwm-v1-1-458c2c89709a@gmail.com>
Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [Medium] The `interrupts` property is unconditionally required by the driver but omitted from the YAML schema's required list.
--
commit b16a62dff3236ec8b123a99775f6c90dbfd9912f
Author: Charan Pedumuru <charan.pedumuru@gmail.com>
dt-bindings: pwm: st,pwm: convert to DT schema
Convert STMicroelectronics STiH41x PWM/Capture controller binding
to DT schema.
> diff --git a/Documentation/devicetree/bindings/pwm/pwm-st.txt b/Documentation/devicetree/bindings/pwm/pwm-st.txt
> deleted file mode 100644
> index 19fce774cafad..0000000000000
> --- a/Documentation/devicetree/bindings/pwm/pwm-st.txt
> +++ /dev/null
[ ... ]
> -Required parameters:
[ ... ]
> -- interrupts: IRQ for the Capture device
[ ... ]
> diff --git a/Documentation/devicetree/bindings/pwm/st,pwm.yaml b/Documentation/devicetree/bindings/pwm/st,pwm.yaml
> new file mode 100644
> index 0000000000000..2c10f54b5caf3
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/pwm/st,pwm.yaml
[ ... ]
> +required:
> + - reg
> + - compatible
> + - "#pwm-cells"
> + - pinctrl-names
> + - clock-names
> + - clocks
[Severity: Medium]
Should interrupts be included in this required list?
The original text binding listed interrupts under the required parameters,
and the driver unconditionally requests it during probe:
drivers/pwm/pwm-sti.c:sti_pwm_probe() {
...
irq = platform_get_irq(pdev, 0);
if (irq < 0)
return irq;
ret = devm_request_irq(&pdev->dev, irq, sti_pwm_interrupt, 0,
pdev->name, pc);
...
}
Without interrupts in the required list, incomplete device trees will pass
schema validation but fail deterministically at runtime.
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260613-st-pwm-v1-1-458c2c89709a@gmail.com?part=1
^ 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