Devicetree
 help / color / mirror / Atom feed
* [PATCH v2 5/9] arm64: dts: imx8ulp-evk: Add gpio-keys node for power button
From: Peng Fan (OSS) @ 2026-07-20 14:12 UTC (permalink / raw)
  To: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Frank Li,
	Sascha Hauer, Pengutronix Kernel Team, Fabio Estevam
  Cc: devicetree, imx, linux-arm-kernel, linux-kernel, Peng Fan
In-Reply-To: <20260720-imx8ulp-dts-v2-0-d05c67676f53@nxp.com>

From: Peng Fan <peng.fan@nxp.com>

Add a gpio-keys node for the power-on button, report it as KEY_POWER to
user space.

Signed-off-by: Peng Fan <peng.fan@nxp.com>
---
 arch/arm64/boot/dts/freescale/imx8ulp-9x9-evk.dts | 18 ++++++++++++++++++
 arch/arm64/boot/dts/freescale/imx8ulp-evk.dts     | 19 +++++++++++++++++++
 2 files changed, 37 insertions(+)

diff --git a/arch/arm64/boot/dts/freescale/imx8ulp-9x9-evk.dts b/arch/arm64/boot/dts/freescale/imx8ulp-9x9-evk.dts
index 5497e3d78136f..af8f0d6087f71 100644
--- a/arch/arm64/boot/dts/freescale/imx8ulp-9x9-evk.dts
+++ b/arch/arm64/boot/dts/freescale/imx8ulp-9x9-evk.dts
@@ -10,6 +10,18 @@
 / {
 	model = "NXP i.MX8ULP EVK9";
 	compatible = "fsl,imx8ulp-9x9-evk", "fsl,imx8ulp";
+
+	gpio-keys {
+		compatible = "gpio-keys";
+		pinctrl-names = "default";
+		pinctrl-0 = <&pinctrl_gpio_keys>;
+
+		button-power-on {
+			label = "PowerOn";
+			gpios = <&gpiof 11 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_POWER>;
+		};
+	};
 };
 
 &btcpu {
@@ -43,6 +55,12 @@ MX8ULP_PAD_PTF10__ENET0_1588_CLKIN      0x43
 	>;
 };
 
+&pinctrl_gpio_keys {
+	fsl,pins = <
+		MX8ULP_PAD_PTF11__PTF11		0x3
+	>;
+};
+
 &pinctrl_usb1 {
 	fsl,pins = <
 		MX8ULP_PAD_PTE16__USB0_ID		0x10003
diff --git a/arch/arm64/boot/dts/freescale/imx8ulp-evk.dts b/arch/arm64/boot/dts/freescale/imx8ulp-evk.dts
index 5dea66c1e7aa0..6a92c5ca9a412 100644
--- a/arch/arm64/boot/dts/freescale/imx8ulp-evk.dts
+++ b/arch/arm64/boot/dts/freescale/imx8ulp-evk.dts
@@ -5,6 +5,7 @@
 
 /dts-v1/;
 
+#include <dt-bindings/input/input.h>
 #include "imx8ulp.dtsi"
 
 / {
@@ -20,6 +21,18 @@ chosen {
 		stdout-path = &lpuart5;
 	};
 
+	gpio-keys {
+		compatible = "gpio-keys";
+		pinctrl-names = "default";
+		pinctrl-0 = <&pinctrl_gpio_keys>;
+
+		button-power-on {
+			label = "PowerOn";
+			gpios = <&gpiof 31 GPIO_ACTIVE_LOW>;
+			linux,code = <KEY_POWER>;
+		};
+	};
+
 	memory@80000000 {
 		device_type = "memory";
 		reg = <0x0 0x80000000 0 0x80000000>;
@@ -323,6 +336,12 @@ MX8ULP_PAD_PTD22__FLEXSPI2_A_DATA4	0x42
 		>;
 	};
 
+	pinctrl_gpio_keys: gpiokeysgrp {
+		fsl,pins = <
+			MX8ULP_PAD_PTF31__PTF31		0x3
+		>;
+	};
+
 	pinctrl_lpuart5: lpuart5grp {
 		fsl,pins = <
 			MX8ULP_PAD_PTF14__LPUART5_TX	0x3

-- 
2.34.1


^ permalink raw reply related

* [PATCH v2 4/9] arm64: dts: imx8ulp: Add assigned clock properties for LPUART nodes
From: Peng Fan (OSS) @ 2026-07-20 14:12 UTC (permalink / raw)
  To: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Frank Li,
	Sascha Hauer, Pengutronix Kernel Team, Fabio Estevam
  Cc: devicetree, imx, linux-arm-kernel, linux-kernel, Peng Fan
In-Reply-To: <20260720-imx8ulp-dts-v2-0-d05c67676f53@nxp.com>

From: Peng Fan <peng.fan@nxp.com>

Add assigned-clocks, assigned-clock-parents and assigned-clock-rates
properties to lpuart4 through lpuart7, so the LPUART input clock is
configured automatically by the clock framework during probe.

Signed-off-by: Peng Fan <peng.fan@nxp.com>
---
 arch/arm64/boot/dts/freescale/imx8ulp.dtsi | 12 ++++++++++++
 1 file changed, 12 insertions(+)

diff --git a/arch/arm64/boot/dts/freescale/imx8ulp.dtsi b/arch/arm64/boot/dts/freescale/imx8ulp.dtsi
index 7d00fe8360948..777b89ed68490 100644
--- a/arch/arm64/boot/dts/freescale/imx8ulp.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx8ulp.dtsi
@@ -413,6 +413,9 @@ lpuart4: serial@29390000 {
 				interrupts = <GIC_SPI 99 IRQ_TYPE_LEVEL_HIGH>;
 				clocks = <&pcc3 IMX8ULP_CLK_LPUART4>;
 				clock-names = "ipg";
+				assigned-clocks = <&pcc3 IMX8ULP_CLK_LPUART4>;
+				assigned-clock-parents = <&cgc1 IMX8ULP_CLK_FROSC_DIV2>;
+				assigned-clock-rates = <48000000>;
 				dmas = <&edma1 55 0 FSL_EDMA_RX>, <&edma1 56 0 0>;
 				dma-names = "rx", "tx";
 				status = "disabled";
@@ -424,6 +427,9 @@ lpuart5: serial@293a0000 {
 				interrupts = <GIC_SPI 100 IRQ_TYPE_LEVEL_HIGH>;
 				clocks = <&pcc3 IMX8ULP_CLK_LPUART5>;
 				clock-names = "ipg";
+				assigned-clocks = <&pcc3 IMX8ULP_CLK_LPUART5>;
+				assigned-clock-parents = <&cgc1 IMX8ULP_CLK_SOSC_DIV2>;
+				assigned-clock-rates = <24000000>;
 				dmas = <&edma1 57 0 FSL_EDMA_RX>, <&edma1 58 0 0>;
 				dma-names = "rx", "tx";
 				status = "disabled";
@@ -529,6 +535,9 @@ lpuart6: serial@29860000 {
 				interrupts = <GIC_SPI 101 IRQ_TYPE_LEVEL_HIGH>;
 				clocks = <&pcc4 IMX8ULP_CLK_LPUART6>;
 				clock-names = "ipg";
+				assigned-clocks = <&pcc4 IMX8ULP_CLK_LPUART6>;
+				assigned-clock-parents = <&cgc1 IMX8ULP_CLK_FROSC_DIV2>;
+				assigned-clock-rates = <48000000>;
 				dmas = <&edma1 59 0 FSL_EDMA_RX>, <&edma1 60 0 0>;
 				dma-names = "rx", "tx";
 				status = "disabled";
@@ -540,6 +549,9 @@ lpuart7: serial@29870000 {
 				interrupts = <GIC_SPI 102 IRQ_TYPE_LEVEL_HIGH>;
 				clocks = <&pcc4 IMX8ULP_CLK_LPUART7>;
 				clock-names = "ipg";
+				assigned-clocks = <&pcc4 IMX8ULP_CLK_LPUART7>;
+				assigned-clock-parents = <&cgc1 IMX8ULP_CLK_FROSC_DIV2>;
+				assigned-clock-rates = <48000000>;
 				dmas = <&edma1 61 0 FSL_EDMA_RX>, <&edma1 62 0 0>;
 				dma-names = "rx", "tx";
 				status = "disabled";

-- 
2.34.1


^ permalink raw reply related

* [PATCH v2 3/9] arm64: dts: imx8ulp: Correct SRAM node address and size to cover full SSRAM P2
From: Peng Fan (OSS) @ 2026-07-20 14:12 UTC (permalink / raw)
  To: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Frank Li,
	Sascha Hauer, Pengutronix Kernel Team, Fabio Estevam
  Cc: devicetree, imx, linux-arm-kernel, linux-kernel, Peng Fan
In-Reply-To: <20260720-imx8ulp-dts-v2-0-d05c67676f53@nxp.com>

From: Peng Fan <peng.fan@nxp.com>

The SSRAM P2 partition starts at 0x22010000 with a size of 64 KB.
The previous node only mapped the last 4 KB (0x2201f000, 0x1000) which
was used for the SCMI shared memory buffer. Update the base address and
size to cover the full P2 region so it can also serve as a general
purpose SRAM pool.

Signed-off-by: Peng Fan <peng.fan@nxp.com>
---
 arch/arm64/boot/dts/freescale/imx8ulp.dtsi | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/arch/arm64/boot/dts/freescale/imx8ulp.dtsi b/arch/arm64/boot/dts/freescale/imx8ulp.dtsi
index cb0d73327d86c..7d00fe8360948 100644
--- a/arch/arm64/boot/dts/freescale/imx8ulp.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx8ulp.dtsi
@@ -154,17 +154,17 @@ sosc: clock-sosc {
 		#clock-cells = <0>;
 	};
 
-	sram@2201f000 {
+	sram@22010000 {
 		compatible = "mmio-sram";
-		reg = <0x0 0x2201f000 0x0 0x1000>;
+		reg = <0x0 0x22010000 0x0 0x10000>;
 
 		#address-cells = <1>;
 		#size-cells = <1>;
-		ranges = <0 0x0 0x2201f000 0x1000>;
+		ranges = <0 0x0 0x22010000 0x10000>;
 
-		scmi_buf: scmi-sram-section@0 {
+		scmi_buf: scmi-sram-section@f000 {
 			compatible = "arm,scmi-shmem";
-			reg = <0x0 0x400>;
+			reg = <0xf000 0x400>;
 		};
 	};
 

-- 
2.34.1


^ permalink raw reply related

* [PATCH v2 2/9] arm64: dts: imx8ulp: Add I3C2 controller node
From: Peng Fan (OSS) @ 2026-07-20 14:12 UTC (permalink / raw)
  To: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Frank Li,
	Sascha Hauer, Pengutronix Kernel Team, Fabio Estevam
  Cc: devicetree, imx, linux-arm-kernel, linux-kernel, Peng Fan
In-Reply-To: <20260720-imx8ulp-dts-v2-0-d05c67676f53@nxp.com>

From: Peng Fan <peng.fan@nxp.com>

Add the I3C2 (i3c-master@29360000) node to the imx8ulp device tree using
the Silvaco I3C master IP. Configure PCC3-gated clock with SOSC DIV2 as
parent at 24 MHz for pclk and fast_clk. slow_clk uses a dummy clock.

Signed-off-by: Peng Fan <peng.fan@nxp.com>
---
 arch/arm64/boot/dts/freescale/imx8ulp.dtsi | 16 ++++++++++++++++
 1 file changed, 16 insertions(+)

diff --git a/arch/arm64/boot/dts/freescale/imx8ulp.dtsi b/arch/arm64/boot/dts/freescale/imx8ulp.dtsi
index 1ab4ab270dc2d..cb0d73327d86c 100644
--- a/arch/arm64/boot/dts/freescale/imx8ulp.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx8ulp.dtsi
@@ -361,6 +361,22 @@ tpm5: tpm@29340000 {
 				status = "disabled";
 			};
 
+			i3c2: i3c@29360000 {
+				compatible = "silvaco,i3c-master-v1";
+				reg = <0x29360000 0x10000>;
+				interrupts = <GIC_SPI 96 IRQ_TYPE_LEVEL_HIGH>;
+				#address-cells = <3>;
+				#size-cells = <0>;
+				clocks = <&pcc3 IMX8ULP_CLK_I3C2>,
+					 <&pcc3 IMX8ULP_CLK_I3C2>,
+					 <&cgc1 IMX8ULP_CLK_DUMMY>;
+				clock-names = "pclk", "fast_clk", "slow_clk";
+				assigned-clocks = <&pcc3 IMX8ULP_CLK_I3C2>;
+				assigned-clock-parents = <&cgc1 IMX8ULP_CLK_SOSC_DIV2>;
+				assigned-clock-rates = <24000000>;
+				status = "disabled";
+			};
+
 			lpi2c4: i2c@29370000 {
 				compatible = "fsl,imx8ulp-lpi2c", "fsl,imx7ulp-lpi2c";
 				reg = <0x29370000 0x10000>;

-- 
2.34.1


^ permalink raw reply related

* [PATCH v2 1/9] arm64: dts: imx8ulp: Add DMA channel properties and use eDMA flag macros
From: Peng Fan (OSS) @ 2026-07-20 14:12 UTC (permalink / raw)
  To: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Frank Li,
	Sascha Hauer, Pengutronix Kernel Team, Fabio Estevam
  Cc: devicetree, imx, linux-arm-kernel, linux-kernel, Peng Fan
In-Reply-To: <20260720-imx8ulp-dts-v2-0-d05c67676f53@nxp.com>

From: Peng Fan <peng.fan@nxp.com>

Add DMA channel (dmas/dma-names) properties to peripheral nodes that
were missing them:
- LPI2C: lpi2c4, lpi2c5, lpi2c6, lpi2c7
- LPUART: lpuart4, lpuart5, lpuart6, lpuart7
- LPSPI: lpspi4, lpspi5

Also replace hardcoded numeric DMA direction flags with the proper
FSL_EDMA_RX and FSL_EDMA_MULTI_FIFO macros for SAI (sai4, sai5, sai6,
sai7) and SPDIF nodes.

Signed-off-by: Peng Fan <peng.fan@nxp.com>
---
 arch/arm64/boot/dts/freescale/imx8ulp.dtsi | 32 +++++++++++++++++++++++++-----
 1 file changed, 27 insertions(+), 5 deletions(-)

diff --git a/arch/arm64/boot/dts/freescale/imx8ulp.dtsi b/arch/arm64/boot/dts/freescale/imx8ulp.dtsi
index c6d1bb9edf388..1ab4ab270dc2d 100644
--- a/arch/arm64/boot/dts/freescale/imx8ulp.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx8ulp.dtsi
@@ -4,6 +4,7 @@
  */
 
 #include <dt-bindings/clock/imx8ulp-clock.h>
+#include <dt-bindings/dma/fsl-edma.h>
 #include <dt-bindings/gpio/gpio.h>
 #include <dt-bindings/interrupt-controller/arm-gic.h>
 #include <dt-bindings/power/imx8ulp-power.h>
@@ -370,6 +371,8 @@ lpi2c4: i2c@29370000 {
 				assigned-clocks = <&pcc3 IMX8ULP_CLK_LPI2C4>;
 				assigned-clock-parents = <&cgc1 IMX8ULP_CLK_FROSC_DIV2>;
 				assigned-clock-rates = <48000000>;
+				dmas = <&edma1 46 0 0>, <&edma1 45 0 FSL_EDMA_RX>;
+				dma-names = "tx", "rx";
 				status = "disabled";
 			};
 
@@ -383,6 +386,8 @@ lpi2c5: i2c@29380000 {
 				assigned-clocks = <&pcc3 IMX8ULP_CLK_LPI2C5>;
 				assigned-clock-parents = <&cgc1 IMX8ULP_CLK_FROSC_DIV2>;
 				assigned-clock-rates = <48000000>;
+				dmas = <&edma1 48 0 0>, <&edma1 47 0 FSL_EDMA_RX>;
+				dma-names = "tx", "rx";
 				status = "disabled";
 			};
 
@@ -392,6 +397,8 @@ lpuart4: serial@29390000 {
 				interrupts = <GIC_SPI 99 IRQ_TYPE_LEVEL_HIGH>;
 				clocks = <&pcc3 IMX8ULP_CLK_LPUART4>;
 				clock-names = "ipg";
+				dmas = <&edma1 55 0 FSL_EDMA_RX>, <&edma1 56 0 0>;
+				dma-names = "rx", "tx";
 				status = "disabled";
 			};
 
@@ -401,6 +408,8 @@ lpuart5: serial@293a0000 {
 				interrupts = <GIC_SPI 100 IRQ_TYPE_LEVEL_HIGH>;
 				clocks = <&pcc3 IMX8ULP_CLK_LPUART5>;
 				clock-names = "ipg";
+				dmas = <&edma1 57 0 FSL_EDMA_RX>, <&edma1 58 0 0>;
+				dma-names = "rx", "tx";
 				status = "disabled";
 			};
 
@@ -416,6 +425,8 @@ lpspi4: spi@293b0000 {
 				assigned-clocks = <&pcc3 IMX8ULP_CLK_LPSPI4>;
 				assigned-clock-parents = <&cgc1 IMX8ULP_CLK_FROSC_DIV2>;
 				assigned-clock-rates = <48000000>;
+				dmas = <&edma1 64 0 0>, <&edma1 63 0 FSL_EDMA_RX>;
+				dma-names = "tx", "rx";
 				status = "disabled";
 			};
 
@@ -431,6 +442,8 @@ lpspi5: spi@293c0000 {
 				assigned-clocks = <&pcc3 IMX8ULP_CLK_LPSPI5>;
 				assigned-clock-parents = <&cgc1 IMX8ULP_CLK_FROSC_DIV2>;
 				assigned-clock-rates = <48000000>;
+				dmas = <&edma1 66 0 0>, <&edma1 65 0 FSL_EDMA_RX>;
+				dma-names = "tx", "rx";
 				status = "disabled";
 			};
 		};
@@ -474,6 +487,8 @@ lpi2c6: i2c@29840000 {
 				assigned-clocks = <&pcc4 IMX8ULP_CLK_LPI2C6>;
 				assigned-clock-parents = <&cgc1 IMX8ULP_CLK_FROSC_DIV2>;
 				assigned-clock-rates = <48000000>;
+				dmas = <&edma1 50 0 0>, <&edma1 49 0 FSL_EDMA_RX>;
+				dma-names = "tx", "rx";
 				status = "disabled";
 			};
 
@@ -487,6 +502,8 @@ lpi2c7: i2c@29850000 {
 				assigned-clocks = <&pcc4 IMX8ULP_CLK_LPI2C7>;
 				assigned-clock-parents = <&cgc1 IMX8ULP_CLK_FROSC_DIV2>;
 				assigned-clock-rates = <48000000>;
+				dmas = <&edma1 52 0 0>, <&edma1 51 0 FSL_EDMA_RX>;
+				dma-names = "tx", "rx";
 				status = "disabled";
 			};
 
@@ -496,6 +513,8 @@ lpuart6: serial@29860000 {
 				interrupts = <GIC_SPI 101 IRQ_TYPE_LEVEL_HIGH>;
 				clocks = <&pcc4 IMX8ULP_CLK_LPUART6>;
 				clock-names = "ipg";
+				dmas = <&edma1 59 0 FSL_EDMA_RX>, <&edma1 60 0 0>;
+				dma-names = "rx", "tx";
 				status = "disabled";
 			};
 
@@ -505,6 +524,8 @@ lpuart7: serial@29870000 {
 				interrupts = <GIC_SPI 102 IRQ_TYPE_LEVEL_HIGH>;
 				clocks = <&pcc4 IMX8ULP_CLK_LPUART7>;
 				clock-names = "ipg";
+				dmas = <&edma1 61 0 FSL_EDMA_RX>, <&edma1 62 0 0>;
+				dma-names = "rx", "tx";
 				status = "disabled";
 			};
 
@@ -516,7 +537,7 @@ sai4: sai@29880000 {
 					 <&cgc1 IMX8ULP_CLK_SAI4_SEL>, <&cgc1 IMX8ULP_CLK_DUMMY>,
 					 <&cgc1 IMX8ULP_CLK_DUMMY>;
 				clock-names = "bus", "mclk0", "mclk1", "mclk2", "mclk3";
-				dmas = <&edma1 67 0 1>, <&edma1 68 0 0>;
+				dmas = <&edma1 67 0 FSL_EDMA_RX>, <&edma1 68 0 0>;
 				dma-names = "rx", "tx";
 				#sound-dai-cells = <0>;
 				fsl,dataline = <0 0x03 0x03>;
@@ -531,7 +552,7 @@ sai5: sai@29890000 {
 					 <&cgc1 IMX8ULP_CLK_SAI5_SEL>, <&cgc1 IMX8ULP_CLK_DUMMY>,
 					 <&cgc1 IMX8ULP_CLK_DUMMY>;
 				clock-names = "bus", "mclk0", "mclk1", "mclk2", "mclk3";
-				dmas = <&edma1 69 0 1>, <&edma1 70 0 0>;
+				dmas = <&edma1 69 0 FSL_EDMA_RX>, <&edma1 70 0 0>;
 				dma-names = "rx", "tx";
 				#sound-dai-cells = <0>;
 				fsl,dataline = <0 0x0f 0x0f>;
@@ -814,7 +835,7 @@ sai6: sai@2da90000 {
 					 <&cgc2 IMX8ULP_CLK_SAI6_SEL>, <&cgc1 IMX8ULP_CLK_DUMMY>,
 					 <&cgc1 IMX8ULP_CLK_DUMMY>;
 				clock-names = "bus", "mclk0", "mclk1", "mclk2", "mclk3";
-				dmas = <&edma2 71 0 1>, <&edma2 72 0 0>;
+				dmas = <&edma2 71 0 FSL_EDMA_RX>, <&edma2 72 0 0>;
 				dma-names = "rx", "tx";
 				#sound-dai-cells = <0>;
 				fsl,dataline = <0 0x0f 0x0f>;
@@ -829,7 +850,7 @@ sai7: sai@2daa0000 {
 					 <&cgc2 IMX8ULP_CLK_SAI7_SEL>, <&cgc1 IMX8ULP_CLK_DUMMY>,
 					 <&cgc1 IMX8ULP_CLK_DUMMY>;
 				clock-names = "bus", "mclk0", "mclk1", "mclk2", "mclk3";
-				dmas = <&edma2 73 0 1>, <&edma2 74 0 0>;
+				dmas = <&edma2 73 0 FSL_EDMA_RX>, <&edma2 74 0 0>;
 				dma-names = "rx", "tx";
 				#sound-dai-cells = <0>;
 				fsl,dataline = <0 0x0f 0x0f>;
@@ -855,7 +876,8 @@ spdif: spdif@2dab0000 {
 					      "rxtx3", "rxtx4",
 					      "rxtx5", "rxtx6",
 					      "rxtx7", "spba";
-				dmas = <&edma2 75 0 5>, <&edma2 76 0 4>;
+				dmas = <&edma2 75 0 (FSL_EDMA_RX | FSL_EDMA_MULTI_FIFO)>,
+				       <&edma2 76 0 FSL_EDMA_MULTI_FIFO>;
 				dma-names = "rx", "tx";
 				status = "disabled";
 			};

-- 
2.34.1


^ permalink raw reply related

* [PATCH v2 0/9] arm64: dts: imx8ulp: Device tree updates for i.MX 8ULP EVK boards
From: Peng Fan (OSS) @ 2026-07-20 14:12 UTC (permalink / raw)
  To: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Frank Li,
	Sascha Hauer, Pengutronix Kernel Team, Fabio Estevam
  Cc: devicetree, imx, linux-arm-kernel, linux-kernel, Peng Fan,
	Sherry Sun, Wei Fang

A collection of device tree fixes and additions for the i.MX 8ULP SoC
and its EVK boards:

SoC-level (imx8ulp.dtsi):
- Add DMA channel properties to LPI2C, LPUART and LPSPI nodes and
  replace hardcoded eDMA direction flags with FSL_EDMA_RX /
  FSL_EDMA_MULTI_FIFO macros for SAI and SPDIF nodes.
- Add the I3C2 controller node (Silvaco IP).
- Correct the SRAM node base address and size to cover the full 64 KB
  SSRAM P2 partition instead of only the last 4 KB.
- Add assigned-clock properties to LPUART4-7 so the clock framework
  configures the input clock automatically during probe.

Board-level (imx8ulp-evk.dts):
- Add a gpio-keys node for the power-on button (PTF31).
- Enable LPUART6 with flow control for NXP 88W8987 Bluetooth.
- Enable LPUART7 for the FT4232 PortD serial on proto1B boards.
- Reduce ENET pad drive strength and slew rate on PTE14-17/22/23 to
  fix signal overshoot.

Board-level (imx8ulp-9x9-evk.dts):
- Rename the model string from "EVK9" to "9x9 EVK" to follow the
  i.MX die-size naming convention.

Signed-off-by: Peng Fan <peng.fan@nxp.com>
---
Changes in v2:
- I3C2 patch: update commit message to clarify slow_clk uses a dummy clock.
- SRAM patch: update ranges and scmi-sram-section child offset/name to match new base address.
- LPUART6/7 patches: drop redundant "sleep" pinctrl state.
- DMA patch: fix trailing whitespace on lpuart4/5 dmas lines.
- Link to v1: https://patch.msgid.link/20260715-imx8ulp-dts-v1-0-19651358b599@nxp.com

---
Peng Fan (6):
      arm64: dts: imx8ulp: Add DMA channel properties and use eDMA flag macros
      arm64: dts: imx8ulp: Add I3C2 controller node
      arm64: dts: imx8ulp: Correct SRAM node address and size to cover full SSRAM P2
      arm64: dts: imx8ulp: Add assigned clock properties for LPUART nodes
      arm64: dts: imx8ulp-evk: Add gpio-keys node for power button
      arm64: dts: imx8ulp-9x9-evk: Rename model string to reflect die size

Sherry Sun (2):
      arm64: dts: imx8ulp-evk: Enable LPUART6 for Bluetooth
      arm64: dts: imx8ulp-evk: Enable LPUART7

Wei Fang (1):
      arm64: dts: imx8ulp-evk: Change the values of some PCRs of ENET

 arch/arm64/boot/dts/freescale/imx8ulp-9x9-evk.dts | 37 +++++++++++-
 arch/arm64/boot/dts/freescale/imx8ulp-evk.dts     | 65 +++++++++++++++++++--
 arch/arm64/boot/dts/freescale/imx8ulp.dtsi        | 70 +++++++++++++++++++----
 3 files changed, 155 insertions(+), 17 deletions(-)
---
base-commit: cc2b5f627e8ccbae1188ef2d8be3e451d7f933a5
change-id: 20260715-imx8ulp-dts-69f9bf928d2f

Best regards,
--  
Peng Fan <peng.fan@nxp.com>


^ permalink raw reply

* Re: [PATCH v16 07/12] media: mediatek: jpeg: fix resolution change event handling in decoder
From: sashiko-bot @ 2026-07-20 14:08 UTC (permalink / raw)
  To: Kyrie Wu; +Cc: media-ci, devicetree, conor+dt, robh
In-Reply-To: <20260720133432.1042046-8-kyrie.wu@mediatek.com>

Thank you for your contribution! Sashiko AI review found 2 potential issue(s) to consider:

New issues:
- [High] Data race on V4L2 queue format structures due to unlocked modification from the asynchronous worker thread.

Pre-existing issues:
- [High] Infinite workqueue loop and STREAMOFF deadlock due to missing .job_ready callback in multicore decoder.
--

--- Patch [7]: [PATCH v16 07/12] media: mediatek: jpeg: fix resolution change event handling in decoder ---
commit e12d8cd3e85b476d842a0ea7879755769138198f
Author: Kyrie Wu <kyrie.wu@mediatek.com>

media: mediatek: jpeg: fix resolution change event handling in decoder

This patch refines the handling of resolution change events in the JPEG
decoder worker. It updates queue data before signaling the source change and
adds an early exit condition if already in the source change state.

> --- a/drivers/media/platform/mediatek/jpeg/mtk_jpeg_core.c
> +++ b/drivers/media/platform/mediatek/jpeg/mtk_jpeg_core.c
> @@ -1738,11 +1738,15 @@ static void mtk_jpegdec_worker(struct work_struct *work)
>  
>  	if (mtk_jpeg_check_resolution_change(ctx,
>  					     &jpeg_src_buf->dec_param)) {
> -		mtk_jpeg_queue_src_chg_event(ctx);
> +		mtk_jpeg_set_queue_data(ctx, &jpeg_src_buf->dec_param);

[Severity: High]
Does calling mtk_jpeg_set_queue_data() from the asynchronous worker thread
create a data race?

This function writes directly to the format structures like ctx->out_q and
ctx->cap_q. Standard V4L2 ioctls like VIDIOC_G_FMT and VIDIOC_TRY_FMT read
these exact structures and rely on the video device lock (vdev->lock) for
serialization.

Since the worker executes without acquiring the device lock, could this
cause userspace to read torn or mismatched dimension/size values if
VIDIOC_G_FMT is called concurrently?

>  		ctx->state = MTK_JPEG_SOURCE_CHANGE;
> +		mtk_jpeg_queue_src_chg_event(ctx);
>  		goto getbuf_fail;
>  	}
>  
> +	if (ctx->state == MTK_JPEG_SOURCE_CHANGE)
> +		goto getbuf_fail;

[Severity: High]
This is a pre-existing issue, but does jumping to getbuf_fail while
leaving buffers in the queue cause an infinite workqueue loop and
deadlock during VIDIOC_STREAMOFF?

In getbuf_fail, v4l2_m2m_job_finish() is called without removing the
source or destination buffers from the queue.

Looking at mtk_jpeg_multicore_dec_m2m_ops, it lacks a .job_ready callback:

static const struct v4l2_m2m_ops mtk_jpeg_multicore_dec_m2m_ops = {
	.device_run = mtk_jpeg_multicore_dec_device_run,
};

Because there is no .job_ready callback, the V4L2 M2M core assumes the
context is ready and immediately requeues the job. The worker will instantly
run again, hit this same early exit, and loop infinitely.

Additionally, since the buffers are never marked done or removed, could any
subsequent attempt by userspace to stop streaming deadlock permanently in
vb2_wait_for_all_buffers()?

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260720133432.1042046-1-kyrie.wu@mediatek.com?part=7

^ permalink raw reply

* Re: [PATCH v2 3/3] dt-bindings: leds: backlight: Convert TPS65217 to DT schema
From: Eddie @ 2026-07-20 14:07 UTC (permalink / raw)
  To: Krzysztof Kozlowski
  Cc: Aaro Koskinen, Andreas Kemnade, Conor Dooley, Daniel Thompson,
	devicetree, Dmitry Torokhov, dri-devel, Jingoo Han, Kevin Hilman,
	Krzysztof Kozlowski, Lee Jones, linux-input, linux-kernel,
	linux-leds, linux-omap, Pavel Machek, Rob Herring, Roger Quadros,
	Tony Lindgren, daniel.baluta, simona.toaca, goledhruva,
	m-chawdhry
In-Reply-To: <20260720-huge-sturgeon-from-shambhala-a1bdcf@quoll>

On Mon, Jul 20, 2026 at 09:54, Krzysztof Kozlowski <krzk@kernel.org> wrote:
>
> On Sat, Jul 18, 2026 at 09:56:32PM +0000, Eduard Bostina wrote:
>  +
> > +          regulator-compatible:
> > +            $ref: /schemas/types.yaml#/definitions/string
>
> You should not need this property, it is already in regulator.yaml.

I did not find it in regulator.yaml, or in any other schema, but I
found out that it has been deprecated in 2012 by commit 13511def87b9
("regulator: deprecate regulator-compatible DT property") and was
never carried over during the conversion.

I agree it should not be in a new binding, so I will drop it.

It needs a dts change too, tps65217.dtsi names the children
regulator@0..regulator@6, while the driver matches dcdc1, dcdc2,
dcdc3, ldo1…ldo4. of_regulator_match() looks at regulator-compatible
first and falls back to the node name, so without the property nothing
matches and the regulators stop probing.

So I will rename the nodes to dcdc1..ldo4 and drop
regulator-compatible, reg and the address cells.
I will send that as a separate patch in v3 along with the other fixes.

Thanks,
Eduard

^ permalink raw reply

* Re: [PATCH v16 06/12] media: mediatek: jpeg: fix buffer state update timing
From: sashiko-bot @ 2026-07-20 14:05 UTC (permalink / raw)
  To: Kyrie Wu; +Cc: robh, media-ci, devicetree, conor+dt
In-Reply-To: <20260720133432.1042046-7-kyrie.wu@mediatek.com>

Thank you for your contribution! Sashiko AI review found 3 potential issue(s) to consider:

New issues:
- [High] Moving destination buffer state initialization after scheduling the timeout worker introduces a race condition causing list corruption and a kernel oops.

Pre-existing issues:
- [High] The hardware timeout workers are scheduled before hardware start and completely lack lock synchronization, causing data races, hardware bus faults, and use-after-free vulnerabilities.
- [High] The encoder worker permanently leaks a Runtime PM usage reference when `pm_runtime_get_sync()` fails.
--

--- Patch [6]: [PATCH v16 06/12] media: mediatek: jpeg: fix buffer state update timing ---
commit adfbbc474f76db07fc27613935d0bb09341844c6
Author: Kyrie Wu <kyrie.wu@mediatek.com>

media: mediatek: jpeg: fix buffer state update timing

Update the destination buffer state only after the decoder has selected
a hardware core and resumed its runtime PM state successfully. This avoids
assigning frame tracking data to buffers that will be returned early, such
as when a source resolution change is detected.

> diff --git a/drivers/media/platform/mediatek/jpeg/mtk_jpeg_core.c b/drivers/media/platform/mediatek/jpeg/mtk_jpeg_core.c
> index a5a1f6126af73..e152ebae0f219 100644
> --- a/drivers/media/platform/mediatek/jpeg/mtk_jpeg_core.c
> +++ b/drivers/media/platform/mediatek/jpeg/mtk_jpeg_core.c
[ ... ]
> @@ -1773,6 +1767,9 @@ static void mtk_jpegdec_worker(struct work_struct *work)
>  			      msecs_to_jiffies(MTK_JPEG_HW_TIMEOUT_MSEC));
>  
>  	spin_lock_irqsave(&comp_jpeg[hw_id]->hw_lock, flags);
> +	jpeg_dst_buf = mtk_jpeg_vb2_to_srcbuf(&dst_buf->vb2_buf);
> +	jpeg_dst_buf->curr_ctx = ctx;
> +	jpeg_dst_buf->frame_num = ctx->total_frame_num;

[Severity: High]
Does moving this initialization after schedule_delayed_work() create a race
condition that can corrupt the destination done queue?

If the worker thread is preempted right after calling schedule_delayed_work(),
the timeout worker (mtk_jpegdec_timeout_work) can fire early before
jpeg_dst_buf->frame_num is initialized.

The timeout worker will pass this uninitialized buffer to mtk_jpegdec_put_buf(),
which adds it to ctx->dst_done_queue. Because frame_num is uninitialized,
it won't match ctx->last_done_frame_num and the buffer gets stranded in the
queue.

When the worker thread resumes, it initializes frame_num and starts the
hardware. Upon hardware completion, the IRQ handler will call
mtk_jpegdec_put_buf() again and execute list_add_tail() on the exact same
buffer, corrupting the linked list.

[Severity: High]
This isn't a bug introduced by this patch, but could this delayed work
scheduling cause hardware bus faults or memory corruption?

The timeout worker is armed before the hardware lock is acquired and the
hardware is started. Since the timeout workers (both mtk_jpegdec_timeout_work
and mtk_jpegenc_timeout_work) do not acquire hw_lock, if the main worker is
preempted right after scheduling the work, the timeout worker can fire
concurrently.

It will reset the device, complete the buffers to userspace, and call
pm_runtime_put() to potentially power off the device. When the main worker
resumes, it will write to powered-off registers (causing a bus fault), and
instruct the hardware to DMA into buffers that userspace may have already
freed or reused.

[Severity: High]
This is a pre-existing issue, but is there a Runtime PM reference leak in the
encoder worker's failure path?

In mtk_jpegenc_worker() (not modified in this diff), pm_runtime_get_sync()
increments the device's PM usage counter even if it returns an error. If the
resume operation fails, the code branches to the enc_end error path and
returns without calling pm_runtime_put_noidle(). This leaves the usage
counter elevated and permanently prevents the device from suspending again.

>  	ctx->total_frame_num++;
>  	mtk_jpeg_dec_reset(comp_jpeg[hw_id]->reg_base);
>  	mtk_jpeg_dec_set_config(comp_jpeg[hw_id]->reg_base,

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260720133432.1042046-1-kyrie.wu@mediatek.com?part=6

^ permalink raw reply

* Re: [PATCH v3 phy-next 7/8] soc: fsl: guts: implement the RCW override procedure
From: sashiko-bot @ 2026-07-20 14:03 UTC (permalink / raw)
  To: Vladimir Oltean
  Cc: neil.armstrong, olteanv, linux-phy, vkoul, conor+dt, devicetree,
	robh
In-Reply-To: <20260720133642.136324-8-vladimir.oltean@nxp.com>

Thank you for your contribution! Sashiko AI review found 6 potential issue(s) to consider:

New issues:
- [High] SerDes block index validation incorrectly uses `>=` instead of `>`, rejecting the highest valid SerDes index and breaking configuration.
- [High] SoC-specific GENMASK macros execute undefined behavior via negative shifts when `lane >= 4`.
- [High] Bulk RCW override initialization clobbers active configurations on uninitialized lanes.
- [Medium] Non-atomic read-modify-write on shared state causes lost lane initializations.
- [Medium] Extremely short 1 microsecond timeout for hardware register state reflection causes spurious failures.

Pre-existing issues:
- [High] Dereferencing `soc_dev_attr` on the error path causes a kernel panic.
--

--- Patch [7]: [PATCH v3 phy-next 7/8] soc: fsl: guts: implement the RCW override procedure ---
commit a1f1c62bf1e452bc97a7f348215d8401bd095833
Author: Ioana Ciornei <ioana.ciornei@nxp.com>
soc: fsl: guts: implement the RCW override procedure

This commit adds support for the RCW override procedure to enable runtime
reconfiguration of SerDes lane protocols through the DCFG DCSR space.
It exports functions to notify boot time modes, validate protocol changes,
and execute the RCW procedure on specific SoCs.

> diff --git a/drivers/soc/fsl/guts.c b/drivers/soc/fsl/guts.c
> index b9973ca3a440d..4d49d1b953007 100644
> --- a/drivers/soc/fsl/guts.c
> +++ b/drivers/soc/fsl/guts.c
[ ... ]
> @@ -210,6 +210,13 @@ static int fsl_guts_rcw_rmw(int offset, u32 val, u32 mask)
>  {
>  	u32 rcwcr, rcwsr = fsl_guts_read(&soc.dcfg_ccsr->rcwsr[offset]);
>  
>  	rcwcr = rcwsr & ~mask;
>  	rcwcr |= val;
>  	fsl_guts_write(&soc.dcfg_dcsr->rcwcr[offset], rcwcr);
>  
>  	/* Updates to RCWCR should be visible back in RCWSR */
>  	return read_poll_timeout_atomic(fsl_guts_read, rcwsr, rcwsr == rcwcr,
>  					0, RCW_TIMEOUT_US, false,
>  					&soc.dcfg_ccsr->rcwsr[offset]);
>  }

[Severity: Medium]
Is a 1 microsecond timeout sufficient for cross-domain hardware reflections?

The atomic polling loop strictly uses RCW_TIMEOUT_US set to 1, which might be
too brief for the hardware to propagate the state across clock domains. This
could lead to spurious -ETIMEDOUT failures when configuring SerDes lane modes.

[ ... ]
> +static int
> +fsl_guts_serdes_get_rcw_override(int serdes_idx, int lane,
> +				 enum lynx_lane_mode lane_mode,
> +				 struct fsl_soc_serdes_rcw_override *override)
> +{
> +	const struct fsl_soc_data *soc_data = soc.data;
> +
> +	if (!soc_data)
> +		return -ENODEV;
> +
> +	if (serdes_idx >= soc_data->num_serdes || serdes_idx <= 0)
> +		return -ERANGE;

[Severity: High]
Does this bounds check incorrectly reject the highest valid SerDes index?

If soc_data->num_serdes is 2, a client driver attempting to initialize
serdes_idx 2 will trigger this return path because 2 >= 2 evaluates to true.
Should this use > instead of >= to allow configuring the last SerDes block?

> +
> +	if (lane >= MAX_NUM_LANES || lane < 0)
> +		return -ERANGE;

[Severity: High]
Can this loose bounds check lead to undefined behavior in the SoC-specific
macros?

MAX_NUM_LANES is 8, but macros like LS1088A_RCWSR30_SRDS_PRTCL_S2_LNn
assume a maximum of 4 lanes:

GENMASK(3 + 4 * (3 - (lane)), 4 * (3 - (lane)))

If a PHY driver requests a lane index of 4 or higher on LS1088A, this macro
evaluates to GENMASK(-1, -4), which causes negative bitwise shifts.

[ ... ]
> +int fsl_guts_lane_init(int serdes_idx, int lane, enum lynx_lane_mode lane_mode)
> +{
> +	int err;
> +
> +	err = fsl_guts_lane_validate(serdes_idx, lane, lane_mode);
> +	if (err)
> +		return err;
> +
> +	soc.lane_mode[serdes_idx - 1][lane] = lane_mode;
> +	soc.lanes_initialized[serdes_idx - 1] |= BIT(lane);

[Severity: Medium]
Could concurrent PHY probes cause lost lane initialization status here?

This performs a non-atomic read-modify-write on the shared global state array
without holding a lock. If two PHY instances on the same SerDes controller
probe asynchronously, one update to soc.lanes_initialized might overwrite the
other.

[ ... ]
> +static int ls2088a_serdes_init_rcwcr(int serdes_idx)
> +{
> +	int i, err;
> +	u32 reg;
[ ... ]
> +	/* We need to configure the initial state of all lanes for
> +	 * the SerDes block #1
> +	 */
> +	for_each_set_bit(i, &soc.lanes_initialized[serdes_idx - 1], MAX_NUM_LANES)
> +		if (lynx_lane_mode_uses_xgmii_mac(soc.lane_mode[serdes_idx - 1][i]))
> +			reg |= LS2088A_RCWSR30_SRDS_CLK_SEL_XGMII_Ln_S1(i);
> +
> +	err = fsl_guts_rcw_rmw(29, reg,
> +			       LS2088A_RCWSR30_SRDS_CLK_EN_SEL_XGMII_S1 |
> +			       LS2088A_RCWSR30_SRDS_CLK_SEL_MSK);

[Severity: High]
Does this bulk RCW override initialization clobber active configurations on
uninitialized lanes?

If a client driver for lane A calls fsl_guts_lane_set_mode() before sibling
lane B has initialized, this read-modify-write uses a mask spanning all
lanes (LS2088A_RCWSR30_SRDS_CLK_SEL_MSK). This forcefully writes zeroes
to lane B's configuration because it relies purely on the software state
in soc.lanes_initialized, potentially discarding its bootloader-configured
active state.

[ ... ]
>  static int __init fsl_guts_init(void)
>  {
>  	struct soc_device_attribute *soc_dev_attr = NULL;
[ ... ]
>  err_nomem:
>  	ret = -ENOMEM;
>  err:
>  	kfree(soc_dev_attr->family);
>  	kfree(soc_dev_attr->soc_id);
>  	kfree(soc_dev_attr->revision);
>  	kfree(soc_dev_attr->serial_number);
>  	kfree(soc_dev_attr);

[Severity: High]
This is a pre-existing issue, but can dereferencing soc_dev_attr here cause
a kernel panic on the error path?

If earlier initialization steps fail, such as of_iomap() failing and jumping
to err_nomem before soc_dev_attr is allocated, soc_dev_attr will remain NULL.
The unconditional access to member variables like soc_dev_attr->family will
result in a NULL pointer dereference.

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260720133642.136324-1-vladimir.oltean@nxp.com?part=7

^ permalink raw reply

* Re: [PATCH 2/3] nvmem: mtk-efuse: add support for 32-bit aligned reads
From: Roman Vivchar @ 2026-07-20 14:02 UTC (permalink / raw)
  To: AngeloGioacchino Del Regno
  Cc: Srinivas Kandagatla, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Matthias Brugger, Andrew-CT Chen, Lala Lin,
	devicetree, linux-kernel, linux-arm-kernel, linux-mediatek
In-Reply-To: <c2b85740-4372-4609-a9fa-930010f5296a@collabora.com>

On Monday, July 20th, 2026 at 3:48 PM, AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com> wrote:

> On 7/15/26 16:27, Roman Vivchar via B4 Relay wrote:

...
 
> it's easier at this point if you simply do
> 
> 	if (pdata->needs_aligned_read) {
> 		econfig.stride = 4;
> 		econfig.reg_read = mtk_reg_read_aligned;
> 	} else {
> 		econfig.stride = 1;
> 		econfig.reg_read = mtk_reg_read;
> 	}
> 
> and you avoid touching mtk_reg_read entirely.

stride = 4 means we can't do something like reg = <0x1 0x1>;
For example, CPU speedbin is sitting at 0x181, but we can model that as
0x180.
cpu_speedbin: cpu-speedbin@180 {
    /* This is technically reg = <0x181 0x1> and bits = <0 2> */
    reg = <0x180 0x4>;
    bits = <8 2>;
};

I'm not sure what are mediatek preferences in the devicetree since
things change quite frequently... Downstream never triggers this hw bug
because it uses readl everywhere for each efuse.

I would keep the stride = 1 so we don't need workarounds in the DT, but
the reg_read indeed sounds better :)

Let me know if you have any objections.

Best regards,
Roman

^ permalink raw reply

* Re: [PATCH v6 5/6] arm64: dts: qcom: Add device tree for Nord Ride board
From: Konrad Dybcio @ 2026-07-20 14:02 UTC (permalink / raw)
  To: Shawn Guo
  Cc: Bjorn Andersson, Konrad Dybcio, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Bartosz Golaszewski, Deepti Jaggi, devicetree,
	linux-arm-msm, linux-kernel
In-Reply-To: <al4qB8gIyLSjPBGS@QCOM-aGQu4IUr3Y>

On 7/20/26 4:00 PM, Shawn Guo wrote:
> On Mon, Jul 20, 2026 at 10:40:09AM +0200, Konrad Dybcio wrote:
>> On 7/20/26 6:20 AM, Shawn Guo wrote:
>>> On Thu, Jul 16, 2026 at 07:14:56PM +0200, Konrad Dybcio wrote:
>>>> On 7/16/26 4:26 PM, Shawn Guo wrote:
>>>>> From: Deepti Jaggi <deepti.jaggi@oss.qualcomm.com>
>>>>>
>>>>> Add initial device tree for the Qualcomm SA8797P Ride reference board,
>>>>> which is built on Nord GearVM variant.
>>
>> [...]
>>
>>>>> +&scmi15 {
>>>>> +	status = "okay";
>>>>> +};
>>>>> +
>>>>> +&scmi23 {
>>>>> +	status = "okay";
>>>>> +};
>>>>
>>>> Why only these ones? Can all of the SCMI servers be enabled?
>>>
>>> These are the ones that have actual/enabled client/consumer devices,
>>> e.g. scmi3 for ufs, scmi11 for uart, scmi23 for thermal sensors.
>>
>> We normally refrain from enabling resources in the DT only because the
>> OS (really just Linux) doesn't have the necessary support to cope with
>> the ""complete"" system description. In this case, there's a firmware
>> layer drives everything and handles on/off requests gracefully
>> (hopefully).
>>
>>> We can enable all the SCMI servers, but I'm afraid that cause kernel
>>> to map shared memory and issue SMC calls to discover protocols (like
>>> power domains, DVFS, resets) that have no consumers, which might waste
>>> a small amount of memory and boot time.
>>
>> Please give it a shot and see if there's any immediate
>> problems.
> 
> Sorry! I have to take "We can enable all the SCMI servers" back. I just
> tested. It seems that NHLOS ABL doesn't like the idea, and it
> fails/refuses to boot Linux Kernel when we enable all SCMI instances in
> DT.
> 
> I can try to figure out the cause by working with Auto/firmware team
> internally, but that likely takes some time. Can we address this later
> as a separate topic, so that the whole series doesn't get blocked
> for v7.3 merge window?

Yes

Konrad

^ permalink raw reply

* Re: [PATCH v17 3/4] crypto: spacc - Add SPAcc AUTODETECT Support
From: sashiko-bot @ 2026-07-20 14:02 UTC (permalink / raw)
  To: Pavitrakumar Managutte; +Cc: devicetree, robh, conor+dt
In-Reply-To: <20260720113740.64960-4-pavitrakumarm@vayavyalabs.com>

Thank you for your contribution! Sashiko AI review found 3 potential issue(s) to consider:
- [High] Unkillable wait_event() in device probe can permanently hang the system if an error path is taken.
- [High] Missing test vectors for 128-byte HMAC keys silently disable previously supported algorithms.
- [High] testdata for CRYPTO_MODE_HMAC_SM3 contains identical test vectors for 64-byte and 128-byte keys, validating non-compliant hardware behavior.
--

--- Patch [3]: [PATCH v17 3/4] crypto: spacc - Add SPAcc AUTODETECT Support ---
commit e7cc55bd58c9e6a7c0c33295410fbd1d815c4aec
Author: Pavitrakumar Managutte <pavitrakumarm@vayavyalabs.com>

crypto: spacc - Add SPAcc AUTODETECT Support
    
SPAcc is configurable and it supports the below modes:
1. AUTODETECT configuration - Autodetects the supported algos.
2. Static configuration - The algo support is defined statically.

> diff --git a/drivers/crypto/dwc-spacc/spacc_core.c b/drivers/crypto/dwc-spacc/spacc_core.c
> --- a/drivers/crypto/dwc-spacc/spacc_core.c
> +++ b/drivers/crypto/dwc-spacc/spacc_core.c
[ ... ]
> +	[CRYPTO_MODE_HMAC_MD5] = {
> +		.min_version = 0x65,
> +		.test[1].outlen = 16, .test[1].data = { 0xb6, 0x39, 0xc8, 0x73,
> +			0x16, 0x38, 0x61, 0x8b, 0x70, 0x79, 0x72, 0xaa, 0x6e,
> +			0x96, 0xcf, 0x90,  },
> +		.test[4].outlen = 16, .test[4].data = { 0xb7, 0x79, 0x68, 0xea,
> +			0x17, 0x32, 0x1e, 0x32, 0x13, 0x90, 0x6c, 0x2e, 0x9f,
> +			0xd5, 0xc8, 0xb3,  },
> +		.test[5].outlen = 16, .test[5].data = { 0x80, 0x3e, 0x0a, 0x2f,
> +			0x8a, 0xd8, 0x31, 0x8f, 0x8e, 0x12, 0x28, 0x86, 0x22,
> +			0x59, 0x6b, 0x05,  },
> +	},

[Severity: High]
Does this test data structure omit test vectors for 128-byte keys (test[6])?

For algorithms like CRYPTO_MODE_HMAC_MD5, CRYPTO_MODE_HMAC_SHA1,
CRYPTO_MODE_HMAC_SHA224, and CRYPTO_MODE_HMAC_SHA256, the lack of a test[6]
entry means outlen evaluates to 0. 

Later in spacc_check_modes(), an outlen of 0 causes the driver to silently
disable support for that key size. This might inadvertently remove previously
supported 128-byte keys for these algorithms.

[ ... ]
> +	[CRYPTO_MODE_HMAC_SM3] = {
> +		.min_version = 0x65,
> +		.test[1].outlen = 32, .test[1].data = { 0x68, 0xf0, 0x65,
> +			0xd8, 0xd8, 0xc9, 0xc2, 0x0e, 0x10, 0xfd, 0x52, 0x7c,
> +			0xf2, 0xd7, 0x42, 0xd3,
> +			0x08, 0x44, 0x22, 0xbc, 0xf0, 0x9d, 0xcc, 0x34, 0x7b,
> +			0x76, 0x13, 0x91, 0xba, 0xce, 0x4d, 0x17 },
> +		.test[4].outlen = 32, .test[4].data = { 0xd8, 0xab, 0x2a,
> +			0x7b, 0x56, 0x21, 0xb1, 0x59, 0x64, 0xb2, 0xa3, 0xd6,
> +			0x72, 0xb3, 0x95, 0x81,
> +			0xa0, 0xcd, 0x96, 0x47, 0xf0, 0xbc, 0x8c, 0x16, 0x5b,
> +			0x9b, 0x7d, 0x2f, 0x71, 0x3f, 0x23, 0x19 },
> +		.test[5].outlen = 32, .test[5].data = { 0xa0, 0xd1, 0xd5,
> +			0xa0, 0x9e, 0x4c, 0xca, 0x8c, 0x7b, 0xe0, 0x8f, 0x70,
> +			0x92, 0x2e, 0x3f, 0x4c,
> +			0xa0, 0xca, 0xef, 0xa1, 0x86, 0x9d, 0xb2, 0xe1, 0xc5,
> +			0xfa, 0x9d, 0xfa, 0xbc, 0x11, 0xcb, 0x1f },
> +		.test[6].outlen = 32, .test[6].data = { 0xa0, 0xd1, 0xd5,
> +			0xa0, 0x9e, 0x4c, 0xca, 0x8c, 0x7b, 0xe0, 0x8f, 0x70,
> +			0x92, 0x2e, 0x3f, 0x4c,
> +			0xa0, 0xca, 0xef, 0xa1, 0x86, 0x9d, 0xb2, 0xe1, 0xc5,
> +			0xfa, 0x9d, 0xfa, 0xbc, 0x11, 0xcb, 0x1f }
> +	},

[Severity: High]
Are these test vectors for 64-byte (test[5]) and 128-byte (test[6]) keys
expected to produce the exact same MAC output?

Since HMAC_SM3 has a block size of 64 bytes, keys longer than 64 bytes are
supposed to be hashed to 32 bytes before being used. Producing the same MAC
for both might mean the hardware is incorrectly truncating the 128-byte key
instead of hashing it. Passing validation with these vectors could permit
broken cryptographic behavior to be used in production.

[ ... ]
> +	err = spacc_packet_enqueue_ddt(spacc, rc, ddt, ddt, proclen, 0,
> +				       aadlen, 0, 0, 0);
> +	job = &spacc->job[rc];
> +
> +	if (err == 0) {
> +		/*
> +		 * No timeout, not interruptible: this only returns once
> +		 * job_done is actually true, i.e. the hardware has
> +		 * genuinely relinquished the job. That guarantees it is
> +		 * always safe to close the job/context and (via the
> +		 * caller) free the DMA buffer immediately below --
> +		 * there is no "unconfirmed" case left to handle.
> +		 *
> +		 * Tradeoff: if the hardware ever genuinely fails to
> +		 * complete a submitted job, this hangs here
> +		 * unkillably (TASK_UNINTERRUPTIBLE, no timeout) for the
> +		 * rest of probe. Accepted deliberately in place of the
> +		 * abandoned-job/UAF risk of giving up early with no
> +		 * hardware cancel available.
> +		 */
> +		wait_event(job->waitq, job->job_done);

[Severity: High]
Could this wait_event() cause the system to hang permanently during probe?

The wait_event() macro places the task in TASK_UNINTERRUPTIBLE. However, if
the job is deferred and subsequently fails to be dispatched to hardware
(for example, due to a DMA error in spacc_process_jb()), the error path sets
job_err and calls wake_up_interruptible(&job->waitq).

Since wake_up_interruptible() only wakes tasks in TASK_INTERRUPTIBLE, this
thread would never wake up from the error path, stranding it forever without
a timeout.

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260720113740.64960-1-pavitrakumarm@vayavyalabs.com?part=3

^ permalink raw reply

* Re: [PATCH v2 1/2] dt-bindings: phy: Document MT8196 MediaTek PCI-Express Gen4 S-PHY
From: sashiko-bot @ 2026-07-20 14:01 UTC (permalink / raw)
  To: AngeloGioacchino Del Regno
  Cc: olteanv, linux-phy, conor+dt, neil.armstrong, vkoul, devicetree,
	robh
In-Reply-To: <20260720135344.84183-2-angelogioacchino.delregno@collabora.com>

Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [Low] Typo in the device tree binding description listing an invalid PCIe link rate (6.0 GT/s instead of 8.0 GT/s).
--

--- Patch [1]: [PATCH v2 1/2] dt-bindings: phy: Document MT8196 MediaTek PCI-Express Gen4 S-PHY ---
commit 44ee552d23d168aeb37986df1a94ba1101ff1252
Author: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>

dt-bindings: phy: Document MT8196 MediaTek PCI-Express Gen4 S-PHY

This commit adds device tree bindings for the MT8196 MediaTek PCI-Express
Gen4 S-PHY. It documents the capabilities, register spaces, and required
properties for this PHY.

> diff --git a/Documentation/devicetree/bindings/phy/mediatek,mt8196-pcie-sphy.yaml b/Documentation/devicetree/bindings/phy/mediatek,mt8196-pcie-sphy.yaml
> new file mode 100644
> index 0000000000000..c24871f7e0e5a
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/phy/mediatek,mt8196-pcie-sphy.yaml
> @@ -0,0 +1,93 @@

[ ... ]

> +description:
> +  The MediaTek PCI-Express Gen4 S-PHY is capable of data serialization
> +  and de-serialization with 8, 10, 128 or 130 bits (16GT/s) encoding
> +  and decoding, has analog buffers, elastic buffers and mechanisms for
> +  receiver detection.
> +  This PHY supports link rates of 2.5, 5.0, 6.0 and 16.0 GT/s per-lane
                                              ^^^

[Severity: Low]
This isn't a bug, but is 6.0 GT/s a typo for 8.0 GT/s here? 

Standard PCIe link rates are typically 2.5, 5.0, 8.0 (Gen3), and 16.0 GT/s,
while 6.0 GT/s is a rate usually associated with SATA rather than PCIe.

> +  in both Root Complex (RC) and End Point (EP) modes, depending on the
> +  chosen port.

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260720135344.84183-1-angelogioacchino.delregno@collabora.com?part=1

^ permalink raw reply

* Re: [PATCH v3 phy-next 2/8] soc: fsl: guts: add a global structure to hold state
From: Vladimir Oltean @ 2026-07-20 14:01 UTC (permalink / raw)
  To: sashiko-reviews
  Cc: devicetree, robh, conor+dt, vkoul, neil.armstrong, olteanv,
	linux-phy
In-Reply-To: <20260720135049.8AC231F00A3D@smtp.kernel.org>

On Mon, Jul 20, 2026 at 01:50:49PM +0000, sashiko-bot@kernel.org wrote:
> [Severity: High]
> Will jumping to err_nomem cause a NULL pointer dereference?
> 
> If the allocation of soc_dev_attr fails, the code now jumps to the error
> handling path which dereferences soc_dev_attr to free its members:
> 
> > @@ -269,6 +271,8 @@ static int __init fsl_guts_init(void)
> >  	kfree(soc_dev_attr->revision);
> >  	kfree(soc_dev_attr->serial_number);
> 
> Since soc_dev_attr is NULL when this allocation fails, won't evaluating
> soc_dev_attr->revision and other members result in a kernel panic?

yeah.

I tried to be nice and play with the existing "err_nomem" and "err"
error handling labels, but the truth is that a single error cleanup path
is just an antipattern that doesn't scale as code becomes more complex.

Instead of having a single error handling procedure which needs to
carefully fend off from various invalid contexts from all the goto
sites, the standard convention is to have an incremental set of labels
which undo just the setup that was done up to the goto jump site.

I'll refactor fsl_guts_init() to use that convention for v4.

^ permalink raw reply

* Re: [PATCH v6 5/6] arm64: dts: qcom: Add device tree for Nord Ride board
From: Shawn Guo @ 2026-07-20 14:00 UTC (permalink / raw)
  To: Konrad Dybcio
  Cc: Bjorn Andersson, Konrad Dybcio, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Bartosz Golaszewski, Deepti Jaggi, devicetree,
	linux-arm-msm, linux-kernel
In-Reply-To: <d5240c7c-6450-489a-97a3-c774deb129b5@oss.qualcomm.com>

On Mon, Jul 20, 2026 at 10:40:09AM +0200, Konrad Dybcio wrote:
> On 7/20/26 6:20 AM, Shawn Guo wrote:
> > On Thu, Jul 16, 2026 at 07:14:56PM +0200, Konrad Dybcio wrote:
> >> On 7/16/26 4:26 PM, Shawn Guo wrote:
> >>> From: Deepti Jaggi <deepti.jaggi@oss.qualcomm.com>
> >>>
> >>> Add initial device tree for the Qualcomm SA8797P Ride reference board,
> >>> which is built on Nord GearVM variant.
> 
> [...]
> 
> >>> +&scmi15 {
> >>> +	status = "okay";
> >>> +};
> >>> +
> >>> +&scmi23 {
> >>> +	status = "okay";
> >>> +};
> >>
> >> Why only these ones? Can all of the SCMI servers be enabled?
> > 
> > These are the ones that have actual/enabled client/consumer devices,
> > e.g. scmi3 for ufs, scmi11 for uart, scmi23 for thermal sensors.
> 
> We normally refrain from enabling resources in the DT only because the
> OS (really just Linux) doesn't have the necessary support to cope with
> the ""complete"" system description. In this case, there's a firmware
> layer drives everything and handles on/off requests gracefully
> (hopefully).
> 
> > We can enable all the SCMI servers, but I'm afraid that cause kernel
> > to map shared memory and issue SMC calls to discover protocols (like
> > power domains, DVFS, resets) that have no consumers, which might waste
> > a small amount of memory and boot time.
> 
> Please give it a shot and see if there's any immediate
> problems.

Sorry! I have to take "We can enable all the SCMI servers" back. I just
tested. It seems that NHLOS ABL doesn't like the idea, and it
fails/refuses to boot Linux Kernel when we enable all SCMI instances in
DT.

I can try to figure out the cause by working with Auto/firmware team
internally, but that likely takes some time. Can we address this later
as a separate topic, so that the whole series doesn't get blocked
for v7.3 merge window?

Shawn

^ permalink raw reply

* Re: [PATCH 1/6] dt-bindings: iio: adc: Add AD7768
From: Janani Sunil @ 2026-07-20 14:00 UTC (permalink / raw)
  To: David Lechner, Janani Sunil, Nuno Sá, Michael Hennerich,
	Jonathan Cameron, Andy Shevchenko, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Olivier Moysan, Philipp Zabel,
	Linus Walleij, Bartosz Golaszewski, Jonathan Corbet, Shuah Khan
  Cc: linux, linux-iio, devicetree, linux-kernel, linux-gpio, linux-doc
In-Reply-To: <36df7c4f-82ea-4ed5-a4f9-3a29c75dc99a@baylibre.com>


On 7/9/26 17:43, David Lechner wrote:
> On 7/9/26 3:50 AM, Janani Sunil wrote:
>> Devicetree Bindings for AD7768-4 (4 channel) and AD7768 (8 channel)
>> simultaneous sampling ADC
>>
>> Signed-off-by: Janani Sunil <janani.sunil@analog.com>
>> ---
>>   
>>
>> +
>> +  adi,power-mode:
>> +    $ref: /schemas/types.yaml#/definitions/string
>> +    enum:
>> +      - low
>> +      - median
>> +      - fast
>> +    description:
>> +      Power mode selection.
> Unless there are pins that control this, it seems like it should be
> left up to the driver to decide how to set this.
>
> In this case, it looks like the power mode also influences sample rate
> which is normally something controlled at runtime.

Hi David,

The reason we'd like to retain power mode control is that certain ODRs 
are supported across all three power modes (low/median/fast), and the 
RMS noise and power consumption differ significantly between them at the 
same ODR.

The higher the power mode, the better the noise performance, but power 
consumption nearly doubles for every ~3 dB improvement in dynamic range. 
Silently selecting one power mode in the driver would remove a 
meaningful hardware tradeoff from the user.

We'd like to propose the following instead:
- Remove adi,power-mode from the DT as suggested.
- Expose power mode as a per-device sysfs attribute.
- in_voltage<N>_sampling_frequency_available dynamically reflects only 
the ODRs valid for the currently selected power mode.

This keeps the DT clean while still giving the user explicit control 
over the noise versus power trade off. Would this approach be acceptable?

Thanks,
Jan



^ permalink raw reply

* Re: [PATCH v16 03/12] media: mediatek: jpeg: fix buffer structure size and layout
From: sashiko-bot @ 2026-07-20 13:59 UTC (permalink / raw)
  To: Kyrie Wu; +Cc: devicetree, media-ci, robh, conor+dt
In-Reply-To: <20260720133432.1042046-4-kyrie.wu@mediatek.com>

Thank you for your contribution! Sashiko AI review found 5 potential issue(s) to consider:

Pre-existing issues:
- [High] Closing the device while a multi-core encoding/decoding job is running leads to Use-After-Free of the context and vb2 buffers in the interrupt handler.
- [High] Orphaned vb2 buffers in `dst_done_queue` are leaked on STREAMOFF.
- [High] Failure to cancel `job_timeout_work` in driver remove causes Use-After-Free.
- [High] Flawed reorder queue iteration in `mtk_jpegenc_put_buf` leads to stranded buffers and application hangs when hardware completes frames out of order.
- [Medium] The custom buffer structure `mtk_jpeg_src_buf` manually replicates the fields of `struct v4l2_m2m_buffer` instead of embedding it, which is an architectural anti-pattern and risks future memory corruption.
--

--- Patch [3]: [PATCH v16 03/12] media: mediatek: jpeg: fix buffer structure size and layout ---
commit 4b1c7af5910f25b2a11680a53e22df54bd4fcacd
Author: Kyrie Wu <kyrie.wu@mediatek.com>

    media: mediatek: jpeg: fix buffer structure size and layout
    
    Updates the buf_struct_size in the JPEG driver to use the correct
    structure mtk_jpeg_src_buf instead of v4l2_m2m_buffer, ensuring
    proper handling of source buffers. The previous buffer size led to
    mismatches and potential issues during video buffer handling.
    
    Moves frame_num in the mtk_jpeg_src_buf structure to align with
    other members appropriately. The first field of the driver-specific
    buffer structure must be the subsystem-specificstruct
    (vb2_v4l2_buffer in the case of V4L2).
    
    Fixes: 5fb1c2361e56 ("mtk-jpegenc: add jpeg encode worker interface")
    Signed-off-by: Kyrie Wu <kyrie.wu@mediatek.com>
    Reviewed-by: Nicolas Dufresne <nicolas.dufresne@collabora.com>

> diff --git a/drivers/media/platform/mediatek/jpeg/mtk_jpeg_core.c b/drivers/media/platform/mediatek/jpeg/mtk_jpeg_core.c
> index 34135706a4ac3..7856a556ce68e 100644
> --- a/drivers/media/platform/mediatek/jpeg/mtk_jpeg_core.c
> +++ b/drivers/media/platform/mediatek/jpeg/mtk_jpeg_core.c
> @@ -1092,7 +1092,7 @@ static int mtk_jpeg_queue_init(void *priv, struct vb2_queue *src_vq,
>  	dst_vq->type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
>  	dst_vq->io_modes = VB2_DMABUF | VB2_MMAP;
>  	dst_vq->drv_priv = ctx;
> -	dst_vq->buf_struct_size = sizeof(struct v4l2_m2m_buffer);
> +	dst_vq->buf_struct_size = sizeof(struct mtk_jpeg_src_buf);
>  	dst_vq->ops = jpeg->variant->qops;
>  	dst_vq->mem_ops = &vb2_dma_contig_memops;
>  	dst_vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY;
> diff --git a/drivers/media/platform/mediatek/jpeg/mtk_jpeg_core.h b/drivers/media/platform/mediatek/jpeg/mtk_jpeg_core.h
> index 6be5cf30dea1b..148fd41759b75 100644
> --- a/drivers/media/platform/mediatek/jpeg/mtk_jpeg_core.h
> +++ b/drivers/media/platform/mediatek/jpeg/mtk_jpeg_core.h
> @@ -85,10 +85,10 @@ struct mtk_jpeg_variant {
>  };
>  
>  struct mtk_jpeg_src_buf {
> -	u32 frame_num;
>  	struct vb2_v4l2_buffer b;
>  	struct list_head list;
>  	u32 bs_size;
> +	u32 frame_num;
>  	struct mtk_jpeg_dec_param dec_param;
>  
>  	struct mtk_jpeg_ctx *curr_ctx;
>  };

[Severity: Medium]
This isn't a bug introduced by this patch, but is it safe to manually
replicate the fields of struct v4l2_m2m_buffer here instead of embedding it
directly?

Since v4l2_m2m_buf_queue casts mtk_jpeg_src_buf to v4l2_m2m_buffer, if
upstream modifies struct v4l2_m2m_buffer (for example, by adding a new
field), this implicit structural casting could cause v4l2_m2m_buf_queue to
access invalid memory and lead to silent kernel heap corruption.

There are also a few pre-existing regressions in this driver that I noticed
while reviewing the code.

[Severity: High]
This is a pre-existing issue, but does closing the device while a multi-core
encoding or decoding job is running lead to a use-after-free?

In drivers/media/platform/mediatek/jpeg/mtk_jpeg_core.c:mtk_jpegenc_worker():

	mtk_jpeg_set_enc_params(ctx, comp_jpeg[hw_id]->reg_base);
	mtk_jpeg_enc_start(comp_jpeg[hw_id]->reg_base);
	v4l2_m2m_job_finish(jpeg->m2m_dev, ctx->fh.m2m_ctx);

The worker prematurely calls v4l2_m2m_job_finish() and clears the job running
state while the hardware is still running. If the user closes the device fd,
mtk_jpeg_release() will not wait for hardware completion and will immediately
free the context and queues.

When the hardware interrupt fires later:

drivers/media/platform/mediatek/jpeg/mtk_jpeg_enc_hw.c:mtk_jpegenc_hw_irq_handler():

	ctx = jpeg->hw_param.curr_ctx;
	src_buf = jpeg->hw_param.src_buffer;

The interrupt handler dereferences the context and buffers which may have
already been freed. Could this cause memory corruption?


[Severity: High]
This is a pre-existing issue, but can orphaned vb2 buffers leak when
streaming is stopped?

Looking at mtk_jpeg_enc_stop_streaming() in mtk_jpeg_core.c:

	while ((vb = mtk_jpeg_buf_remove(ctx, q->type)))
		v4l2_m2m_buf_done(vb, VB2_BUF_STATE_ERROR);

The function retrieves buffers from the active v4l2_m2m queues but appears to
fail to flush the ctx->dst_done_queue. If hardware operations complete out of
order, buffers wait in ctx->dst_done_queue. Does stopping the stream abandon
these pending buffers and cause a leak?


[Severity: High]
This is a pre-existing issue, but does the driver teardown logic fail to
cancel the delayed timeout work?

In drivers/media/platform/mediatek/jpeg/mtk_jpeg_core.c:mtk_jpeg_remove():

static void mtk_jpeg_remove(struct platform_device *pdev)
{
	struct mtk_jpeg_dev *jpeg = platform_get_drvdata(pdev);

	pm_runtime_disable(&pdev->dev);
        ...

The driver initializes a delayed work task (jpeg->job_timeout_work) to handle
hardware timeouts, but mtk_jpeg_remove() does not appear to call
cancel_delayed_work_sync(). If the driver is unbound while a job is timing
out, could the delayed work fire after the device structures are freed and
cause a use-after-free?


[Severity: High]
This is a pre-existing issue, but does the queue iteration logic in
mtk_jpegenc_put_buf() fail to restart its scan, leaving buffers stranded?

In drivers/media/platform/mediatek/jpeg/mtk_jpeg_enc_hw.c:mtk_jpegenc_put_buf():

	while (!list_empty(&ctx->dst_done_queue) &&
	       (pos != &ctx->dst_done_queue)) {
		list_for_each_prev_safe(pos, temp_entry, &ctx->dst_done_queue) {
                    ...
                }
        }

When frames complete out of order (e.g., 8, 9, 7), the outer while loop checks
pos != &ctx->dst_done_queue. However, list_for_each_prev_safe() always
terminates with pos pointing to the list head. Since there is no break inside
the outer loop, the outer condition evaluates to false immediately after one
pass, failing to restart the scan.

Could this leave frames indefinitely stranded in the queue, causing the
application to hang? This same pattern also appears in the decoder side in
mtk_jpegdec_put_buf() in mtk_jpeg_dec_hw.c.

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260720133432.1042046-1-kyrie.wu@mediatek.com?part=3

^ permalink raw reply

* Re: [PATCH v3 phy-next 5/8] soc: fsl: guts: make fsl_soc_data available after fsl_guts_init()
From: sashiko-bot @ 2026-07-20 13:58 UTC (permalink / raw)
  To: Vladimir Oltean
  Cc: robh, conor+dt, devicetree, linux-phy, olteanv, vkoul,
	neil.armstrong
In-Reply-To: <20260720133642.136324-6-vladimir.oltean@nxp.com>

Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [High] NULL pointer dereference in the error handling path of `fsl_guts_init()`.
--

--- Patch [5]: [PATCH v3 phy-next 5/8] soc: fsl: guts: make fsl_soc_data available after fsl_guts_init() ---
commit d316b69e1c587b56ad6f914ddbd2e412490c8594
Author: Vladimir Oltean <vladimir.oltean@nxp.com>
soc: fsl: guts: make fsl_soc_data available after fsl_guts_init()

This commit preserves the soc_data determined during fsl_guts_init() so it
can be referenced later for RCW override methods. It updates the error
handling paths to properly clean up the saved state if initialization fails.

> diff --git a/drivers/soc/fsl/guts.c b/drivers/soc/fsl/guts.c
> --- a/drivers/soc/fsl/guts.c
> +++ b/drivers/soc/fsl/guts.c
> @@ -231,10 +232,9 @@ static int __init fsl_guts_init(void)
>  {
> -	struct soc_device_attribute *soc_dev_attr;
> +	struct soc_device_attribute *soc_dev_attr = NULL;
>  	static struct soc_device *soc_dev;

[ ... ]

> @@ -243,12 +243,12 @@ static int __init fsl_guts_init(void)
>  	np = of_find_matching_node_and_match(NULL, fsl_guts_of_match, &match);
>  	if (!np)
>  		return 0;
> -	soc_data = match->data;
> +	soc.data = match->data;
>  
>  	soc.dcfg_ccsr = of_iomap(np, DCFG_CCSR);
>  	if (!soc.dcfg_ccsr) {
>  		of_node_put(np);
> -		return -ENOMEM;
> +		goto err_nomem;
>  	}

[Severity: High]
If of_iomap() fails here, the code executes a goto to the error path while
soc_dev_attr is still explicitly NULL. 

Down in the error cleanup path, the code unconditionally dereferences 
soc_dev_attr to retrieve its members:

> @@ -311,8 +311,11 @@ static int __init fsl_guts_init(void)
>  	kfree(soc_dev_attr->revision);
>  	kfree(soc_dev_attr->serial_number);
>  	kfree(soc_dev_attr);

Will this trigger a NULL pointer dereference?

While kfree() itself handles NULL pointers gracefully, evaluating
soc_dev_attr->revision and soc_dev_attr->serial_number requires reading
memory from the NULL soc_dev_attr pointer before passing the argument to
kfree().

> -	iounmap(soc.dcfg_ccsr);
> -	soc.dcfg_ccsr = NULL;
> +	if (soc.dcfg_ccsr) {
> +		iounmap(soc.dcfg_ccsr);
> +		soc.dcfg_ccsr = NULL;
> +	}
> +	soc.data = NULL;
>  
>  	return ret;
>  }

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260720133642.136324-1-vladimir.oltean@nxp.com?part=5

^ permalink raw reply

* Re: [PATCH 2/2] iio: adc: ad4080: add support for AD4883
From: sashiko-bot @ 2026-07-20 13:58 UTC (permalink / raw)
  To: Antoniu Miclaus; +Cc: robh, devicetree, conor+dt
In-Reply-To: <20260720133707.103366-3-antoniu.miclaus@analog.com>

Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:

Pre-existing issues:
- [High] The `ad4080_get_scale` function calculates the fractional part of the scale in micro units but returns `IIO_VAL_INT_PLUS_NANO`, causing the userspace scale value to be off by a factor of 1000.
--

--- Patch [2]: [PATCH 2/2] iio: adc: ad4080: add support for AD4883 ---
commit 1f80e540484a260f71b5515f8af8d43748391d9e
Author: Antoniu Miclaus <antoniu.miclaus@analog.com>

iio: adc: ad4080: add support for AD4883

This commit adds support for the AD4883, a dual-channel, 16-bit, 40 MSPS
SAR ADC. It shares the register map and SPI interface with the AD4080
family and provides two independent ADC channels.

> diff --git a/drivers/iio/adc/ad4080.c b/drivers/iio/adc/ad4080.c
> index c7ecf6971be45..543728c7e88c0 100644
> --- a/drivers/iio/adc/ad4080.c
> +++ b/drivers/iio/adc/ad4080.c

[ ... ]

> @@ -646,6 +652,16 @@ static const struct ad4080_chip_info ad4880_chip_info = {
>  	.lvds_cnv_clk_cnt_max = AD4080_LVDS_CNV_CLK_CNT_MAX,
>  };
>  
> +static const struct ad4080_chip_info ad4883_chip_info = {
> +	.name = "ad4883",
> +	.product_id = AD4883_CHIP_ID,
> +	.scale_table = ad4080_scale_table,

[Severity: High]
This isn't a bug introduced by this patch, but looking at how the scale table
is used in ad4080_get_scale(), is there a mismatch in the units returned?

drivers/iio/adc/ad4080.c:ad4080_get_scale() {
	...
	tmp = (st->info->scale_table[0][0] * 1000000ULL) >>
		    st->info->channels[0].scan_type.realbits;
	*val = tmp / 1000000;
	*val2 = tmp % 1000000;

	return IIO_VAL_INT_PLUS_NANO;
}

Since the fractional part is calculated using modulo 1000000 (micro units)
but returned as IIO_VAL_INT_PLUS_NANO, the IIO core will format it as a
nano-scale value. Does this cause the scale exposed to userspace to be off
by a factor of 1000?

Should this return IIO_VAL_INT_PLUS_MICRO instead, or calculate with
1000000000ULL to match the NANO return type?

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260720133707.103366-1-antoniu.miclaus@analog.com?part=2

^ permalink raw reply

* Re: [PATCH v3 phy-next 6/8] dt-bindings: fsl: layerscape-dcfg: define DCFG_DCSR region
From: sashiko-bot @ 2026-07-20 13:57 UTC (permalink / raw)
  To: Vladimir Oltean
  Cc: neil.armstrong, linux-phy, robh, devicetree, olteanv, conor+dt,
	vkoul
In-Reply-To: <20260720133642.136324-7-vladimir.oltean@nxp.com>

Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [High] Dereferencing NULL pointer `soc_dev_attr` on the error path.
--

--- Patch [6]: [PATCH v3 phy-next 6/8] dt-bindings: fsl: layerscape-dcfg: define DCFG_DCSR region ---
commit 87aa71bb5ea85cc0388e2ad87f720397de246b0d
Author: Vladimir Oltean <vladimir.oltean@nxp.com>

dt-bindings: fsl: layerscape-dcfg: define DCFG_DCSR region

This commit defines a secondary "reg" array element in the DCFG binding
for the hidden DCSR register space. Exposing this area permits operating
systems to perform Reset Configuration Word (RCW) overrides, enabling
runtime reconfiguration of networking SerDes lanes.

> diff --git a/Documentation/devicetree/bindings/soc/fsl/fsl,layerscape-dcfg.yaml b/Documentation/devicetree/bindings/soc/fsl/fsl,layerscape-dcfg.yaml
> index 3fb0534ea597b..fc14fd0bf84b1 100644
> --- a/Documentation/devicetree/bindings/soc/fsl/fsl,layerscape-dcfg.yaml
> +++ b/Documentation/devicetree/bindings/soc/fsl/fsl,layerscape-dcfg.yaml
> @@ -36,7 +36,20 @@ properties:
>            - const: simple-mfd
>  
>    reg:
> -    maxItems: 1
> +    minItems: 1

[ ... ]

[Severity: High]
Does the error path in fsl_guts_init() cause a NULL pointer dereference?

drivers/soc/fsl/guts.c:fsl_guts_init() {
    ...
	soc.dcfg_ccsr = of_iomap(np, DCFG_CCSR);
	if (!soc.dcfg_ccsr) {
		of_node_put(np);
		goto err_nomem;
	}
    ...
err_nomem:
	ret = -ENOMEM;
err:
	kfree(soc_dev_attr->family);
	kfree(soc_dev_attr->soc_id);
    ...
}

If of_iomap() or the allocation for soc_dev_attr fails in fsl_guts_init(),
the error handling path jumps to err_nomem while soc_dev_attr is still NULL.

The cleanup code at the err label unconditionally evaluates
soc_dev_attr->family and soc_dev_attr->soc_id before passing them to
kfree(). Reading these fields dereferences the NULL soc_dev_attr pointer,
which can cause an immediate page fault during initialization.

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260720133642.136324-1-vladimir.oltean@nxp.com?part=6

^ permalink raw reply

* Re: [PATCH v4 0/4] ASoC: qcom and pinctrl: add LPASS LPR voting and Hawi LPASS LPI TLMM
From: Krzysztof Kozlowski @ 2026-07-20 13:54 UTC (permalink / raw)
  To: Bartosz Golaszewski, Prasad Kumpatla
  Cc: Srinivas Kandagatla, linux-arm-msm, linux-gpio, devicetree,
	linux-kernel, linux-sound, Bjorn Andersson, Linus Walleij,
	Rob Herring, Krzysztof Kozlowski, Conor Dooley, Liam Girdwood,
	Mark Brown, Srinivas Kandagatla, Jaroslav Kysela, Takashi Iwai
In-Reply-To: <CAMRc=MfvfVvJ4anwY5WZUr5K8fSGkcvejah72fUDLc7ZC59jNw@mail.gmail.com>

On 20/07/2026 15:42, Bartosz Golaszewski wrote:
> On Mon, 20 Jul 2026 15:05:07 +0200, Prasad Kumpatla
> <prasad.kumpatla@oss.qualcomm.com> said:
>> This series adds support for LPASS low-power resource (LPR) voting
>> through PRM and introduces LPASS LPI TLMM pinctrl support for newer
>> platforms such as Hawi.
>>
>> On such platforms, LPASS requires LPR resource voting via PRM to keep
>> the subsystem active. This is handled by adding a new clock ID and
>> support for PARAM_ID_RSC_CPU_LPR in q6prm.
>>
>> Additionally, a new LPASS LPI TLMM block is introduced, requiring a
>> dedicated DT binding and pinctrl driver.
> 
> What is the merging strategy? Is an Ack from Mark required and the series
> should go together through the pinctrl tree?

Why would an ack be needed? Cover letter is very explicit on that
through complete silence that there is no dependency (except that it is
not true) so why would you take ASoC bits?

Best regards,
Krzysztof

^ permalink raw reply

* [PATCH v2 2/2] phy: mediatek: Add support for PCI-Express Gen4 S-PHY
From: AngeloGioacchino Del Regno @ 2026-07-20 13:53 UTC (permalink / raw)
  To: chunfeng.yun
  Cc: vkoul, neil.armstrong, robh, krzk+dt, conor+dt, matthias.bgg,
	angelogioacchino.delregno, linux-arm-kernel, linux-mediatek,
	linux-phy, devicetree, linux-kernel, kernel
In-Reply-To: <20260720135344.84183-1-angelogioacchino.delregno@collabora.com>

Add support for the PCI-Express Gen4 S-PHY found in the latest
MediaTek SoCs, including MT8196, MT8894 and similar.

Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
---
 drivers/phy/mediatek/Kconfig             |   9 +
 drivers/phy/mediatek/Makefile            |   1 +
 drivers/phy/mediatek/phy-mtk-pcie-sphy.c | 561 +++++++++++++++++++++++
 3 files changed, 571 insertions(+)
 create mode 100644 drivers/phy/mediatek/phy-mtk-pcie-sphy.c

diff --git a/drivers/phy/mediatek/Kconfig b/drivers/phy/mediatek/Kconfig
index ba6461350951..77236f3084c8 100644
--- a/drivers/phy/mediatek/Kconfig
+++ b/drivers/phy/mediatek/Kconfig
@@ -13,6 +13,15 @@ config PHY_MTK_PCIE
 	  callback for PCIe GEN3 port, it supports software efuse
 	  initialization.
 
+config PHY_MTK_PCIE_SPHY
+	tristate "MediaTek PCIe S-PHY Driver"
+	depends on ARCH_MEDIATEK || COMPILE_TEST
+	depends on OF
+	select GENERIC_PHY
+	help
+	  Say 'Y' here to add support for MediaTek PCIe S-PHY driver for
+	  PCI-Express Gen4 controllers as found in MT6991, MT8196 and others.
+
 config PHY_MTK_XFI_TPHY
 	tristate "MediaTek 10GE SerDes XFI T-PHY driver"
 	depends on ARCH_MEDIATEK || COMPILE_TEST
diff --git a/drivers/phy/mediatek/Makefile b/drivers/phy/mediatek/Makefile
index ed0da708759b..7e984c7cfea3 100644
--- a/drivers/phy/mediatek/Makefile
+++ b/drivers/phy/mediatek/Makefile
@@ -5,6 +5,7 @@
 
 obj-$(CONFIG_PHY_MTK_DP)		+= phy-mtk-dp.o
 obj-$(CONFIG_PHY_MTK_PCIE)		+= phy-mtk-pcie.o
+obj-$(CONFIG_PHY_MTK_PCIE_SPHY)		+= phy-mtk-pcie-sphy.o
 obj-$(CONFIG_PHY_MTK_TPHY)		+= phy-mtk-tphy.o
 obj-$(CONFIG_PHY_MTK_UFS)		+= phy-mtk-ufs.o
 obj-$(CONFIG_PHY_MTK_XSPHY)		+= phy-mtk-xsphy.o
diff --git a/drivers/phy/mediatek/phy-mtk-pcie-sphy.c b/drivers/phy/mediatek/phy-mtk-pcie-sphy.c
new file mode 100644
index 000000000000..6c1362b70fab
--- /dev/null
+++ b/drivers/phy/mediatek/phy-mtk-pcie-sphy.c
@@ -0,0 +1,561 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2022 MediaTek Inc.
+ * Copyright (c) 2026 Collabora Ltd.
+ *                    AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+ */
+
+#include <linux/bitfield.h>
+#include <linux/module.h>
+#include <linux/nvmem-consumer.h>
+#include <linux/of.h>
+#include <linux/phy/phy.h>
+#include <linux/platform_device.h>
+#include <linux/pm_runtime.h>
+#include <linux/slab.h>
+
+#include "phy-mtk-io.h"
+
+/* PHY System Interface (SIF) registers */
+#define PEXTP_DIG_GLB_TOP				0x20
+#  define RG_XTP_BYPASS_PIPE_RST_RC			BIT(17)
+#define PEXTP_DIG_GLB_CKBG0				0x30
+#  define RG_XTP_CKBG_XTAL_STABLE_TIME_SEL		GENMASK(25, 16)
+#define PEXTP_DIG_GLB_TPLL_CTL0				0x38
+#  define RG_XTP_TPLL_SET_STABLE_TIME_SEL		GENMASK(7, 2)
+#  define RG_XTP_TPLL_PWE_ON_STABLE_TIME_SEL		GENMASK(9, 8)
+#define PEXTP_DIG_GLB_CLKREQ_CTL			0x50
+#  define RG_XTP_CKM_EN_L1S0				BIT(13)
+#  define RG_XTP_CKM_EN_L1S1				BIT(14)
+#define PEXTP_DIG_GLB_TPLL_CTL2				0xf4
+#  define RG_XTP_TPLL_ISO_EN_STABLE_TIME_SEL		GENMASK(13, 12)
+
+/* PHY System Interface Digital registers */
+#define PEXTP_DIG_LN_TRX_PIPE_IF_17			0x30e8
+#  define RG_XTP_LN_RX_LF_CTLE_CSEL_GEN4		GENMASK(14, 12)
+#define PEXTP_DIG_LN_RX_F0				0x50f0
+#  define RG_XTP_LN_RX_GEN1_CTLE1_CSEL			GENMASK(3, 0)
+#  define RG_XTP_LN_RX_GEN2_CTLE1_CSEL			GENMASK(7, 4)
+#  define RG_XTP_LN_RX_GEN3_CTLE1_CSEL			GENMASK(11, 8)
+#  define RG_XTP_LN_RX_GEN4_CTLE1_CSEL			GENMASK(15, 12)
+#define PEXTP_DIG_LN_RX2_AEQ_EDGE_0			0x6004
+#  define RG_XTP_LN_RX_AEQ_EGEQ_RATIO_GEN3		GENMASK(21, 16)
+#  define RG_XTP_LN_RX_AEQ_EGEQ_RATIO_GEN4		GENMASK(29, 24)
+#  define AEQ_EGEQ_RATIO_GEN3_TO_22			0x16
+#  define AEQ_EGEQ_RATIO_GEN4_TO_22			0x16
+
+/* PHY System Interface Analog registers */
+#define PEXTP_ANA_GLB_TPLL1_RSVD			0x902c
+#  define RG_XTP_GLB_TPLL1_P_PATH_GAIN			GENMASK(2, 0)
+#define PEXTP_ANA_GLB_BIAS_0				0x9060
+#  define RG_XTP_GLB_BIAS_INTR_CTRL			GENMASK(5, 0)
+#define PEXTP_ANA_GLB_BIAS_1				0x90c0
+#  define RG_XTP_GLB_BIAS_V2V_VTRIM			GENMASK(9, 6)
+#define PEXTP_ANA_LN_TRX_0C				0xa00c
+#  define RG_XTP_LN_TX_RSWN_IMPSEL			GENMASK(20, 16)
+#define PEXTP_ANA_LN_TRX_34				0xa034
+#  define RG_XTP_LN_RX_FE				BIT(15)
+#define PEXTP_ANA_LN_TRX_6C				0xa06c
+#  define RG_XTP_LN_RX_AEQ_CTLE_ERR_TYPE		GENMASK(14, 13)
+#   define AEQ_CTLE_SEARCH_ERR_TYPE_H1P5		0
+#   define AEQ_CTLE_SEARCH_ERR_TYPE_H1P5_H2P5		1
+#   define AEQ_CTLE_SEARCH_ERR_TYPE_P1P5_H2P5_H3P5	2
+#define PEXTP_ANA_LN_TRX_A0				0xa0a0
+#  define RG_XTP_LN_TX_IMPSEL_PMOS			GENMASK(4, 0)
+#  define RG_XTP_LN_TX_IMPSEL_NMOS			GENMASK(11, 7)
+#  define RG_XTP_LN_RX_IMPSEL				GENMASK(15, 12)
+#define PEXTP_ANA_LN_TRX_A8				0xa0a8
+#  define RG_XTP_LN_RX_LEQ_RL_CTLE_CAL			GENMASK(6, 2)
+#  define RG_XTP_LN_RX_LEQ_RL_VGA_CAL			GENMASK(11, 7)
+#  define RG_XTP_LN_RX_LEQ_RL_DFE_CAL			GENMASK(23, 19)
+#define PEXTP_DIG_LN_TX_LC_TABLE_RSWN_4			0xb004
+#define PEXTP_DIG_LN_TX_LC_TABLE_RSWN_8			0xb008
+#define PEXTP_DIG_LN_TX_LC_TABLE_RSWN_C			0xb00c
+#define PEXTP_DIG_LN_TX_LC_TABLE_RSWN_10		0xb010
+#define PEXTP_DIG_LN_TX_LC_TABLE_RSWN_14		0xb014
+#define PEXTP_DIG_LN_TX_LC_TABLE_RSWN_18		0xb018
+#  define RG_XTP_LN_TX_LC_PRESET_MGx_Px_CM1		GENMASK(5, 0)
+#  define RG_XTP_LN_TX_LC_PRESET_MGx_Px_C0		GENMASK(13, 8)
+#  define RG_XTP_LN_TX_LC_PRESET_MGx_Px_CP1		GENMASK(21, 16)
+#define PEXTP_REG_LANE(x)				((x) * 0x100)
+
+/* PHY Clock Management (CKM) registers */
+#define XTP_CKM_FORCE_6					0x38
+#  define RG_CKM_BIAS_WAIT_PRD_US			GENMASK(21, 16)
+#define XTP_CKM_REG_SPLL_FBKDIV_5			0xd4
+#  define RG_CKM_CKTX_IMPSEL_PMOS			GENMASK(19, 16)
+#  define RG_CKM_CKTX_IMPSEL_NMOS			GENMASK(23, 20)
+#  define RG_CKM_CKTX_IMPSEL_SW				GENMASK(27, 24)
+
+/* Calibration data from eFuses */
+#define MTK_PCIE_SPHY_CALIBRATION_MAX_DATA_LANES	2
+#define MTK_PCIE_SPHY_CALIBRATION_LAST_QUIRK_VER	4
+
+/**
+ * struct mtk_pcie_sphy_imp_sel - Impedance Selection parameters
+ * @pmos: Impedance selection for P-Channel MOSFET
+ * @nmos: Impedance selection for N-Channel MOSFET
+ */
+struct mtk_pcie_sphy_imp_sel {
+	u8 pmos;
+	u8 nmos;
+};
+
+/**
+ * struct mtk_pcie_sphy_efuse - eFuse calibration data for S-PHY
+ * @int_r_ctrl:     Internal resistor selection of TX Bias Current
+ * @xtp_vtrim:      XTP Bias V2V voltage calibration
+ * @cktx_impsel:    SPLL CKTX Impedance Selection (P and N MOSFET)
+ * @cktx_r_mid:     SPLL CKTX Intermediate Transition Impedance (Rmid)
+ * @rx_leq_rl_ctle: RX Front-End Return Loss Continuous Time Linear Equalization value
+ * @rx_leq_rl_vga:  RX Front-End Return Loss Variable Gain Amplifier value
+ * @rx_leq_rl_dfe:  RX Front-End Return Loss Decision Feedback Equalization value
+ * @rx_impsel:      RX Impedance Selection
+ * @tx_impsel:      TX Impedance Selection (P and N MOSFET)
+ * @tx_rswn_impsel: TX RSWn (Switch Resistance) impedance selection
+ * @supported:      eFuse calibration data is supported
+ */
+struct mtk_pcie_sphy_efuse {
+	u8 int_r_ctrl;
+	u8 xtp_vtrim;
+	struct mtk_pcie_sphy_imp_sel cktx_impsel;
+	u8 cktx_r_mid;
+	u8 rx_leq_rl_ctle;
+	u8 rx_leq_rl_vga;
+	u8 rx_leq_rl_dfe;
+	u8 rx_impsel;
+	struct mtk_pcie_sphy_imp_sel tx_impsel;
+	u8 tx_rswn_impsel[MTK_PCIE_SPHY_CALIBRATION_MAX_DATA_LANES];
+	bool supported;
+};
+
+/**
+ * struct mtk_pcie_sphy - PCI-Express S-PHY driver main structure
+ * @dev:         Pointer to device structure
+ * @phy:         Pointer to generic phy structure
+ * @sif_base:    IO mapped register base address of system interface
+ * @ckm_base:    IO mapped register base address of clock management interface
+ * @num_lanes:   Number of lanes
+ * @calibration: eFuse calibration data for S-PHY
+ */
+struct mtk_pcie_sphy {
+	struct device *dev;
+	struct phy *phy;
+	void __iomem *sif_base;
+	void __iomem *ckm_base;
+	u8 num_lanes;
+	struct mtk_pcie_sphy_efuse calibration;
+};
+
+static void mtk_pcie_sphy_apply_calibration(struct mtk_pcie_sphy *pcie_sphy)
+{
+	struct mtk_pcie_sphy_efuse *cal = &pcie_sphy->calibration;
+	int i;
+
+	mtk_phy_update_field(pcie_sphy->sif_base + PEXTP_ANA_GLB_BIAS_0,
+			     RG_XTP_GLB_BIAS_INTR_CTRL, cal->int_r_ctrl);
+
+	mtk_phy_update_field(pcie_sphy->sif_base + PEXTP_ANA_GLB_BIAS_1,
+			     RG_XTP_GLB_BIAS_V2V_VTRIM, cal->xtp_vtrim);
+
+	mtk_phy_update_field(pcie_sphy->ckm_base + XTP_CKM_REG_SPLL_FBKDIV_5,
+			     RG_CKM_CKTX_IMPSEL_PMOS, cal->cktx_impsel.pmos);
+
+	mtk_phy_update_field(pcie_sphy->ckm_base + XTP_CKM_REG_SPLL_FBKDIV_5,
+			     RG_CKM_CKTX_IMPSEL_NMOS, cal->cktx_impsel.nmos);
+
+	mtk_phy_update_field(pcie_sphy->ckm_base + XTP_CKM_REG_SPLL_FBKDIV_5,
+			     RG_CKM_CKTX_IMPSEL_SW, cal->cktx_r_mid);
+
+	for (i = 0; i < pcie_sphy->num_lanes; i++) {
+		void __iomem *sif_lane_base = pcie_sphy->sif_base + PEXTP_REG_LANE(i);
+
+		mtk_phy_update_field(sif_lane_base + PEXTP_ANA_LN_TRX_0C,
+				     RG_XTP_LN_TX_RSWN_IMPSEL, cal->tx_rswn_impsel[i]);
+
+		mtk_phy_update_field(sif_lane_base + PEXTP_ANA_LN_TRX_A8,
+				     RG_XTP_LN_RX_LEQ_RL_CTLE_CAL, cal->rx_leq_rl_ctle);
+
+		mtk_phy_update_field(sif_lane_base + PEXTP_ANA_LN_TRX_A8,
+				     RG_XTP_LN_RX_LEQ_RL_VGA_CAL, cal->rx_leq_rl_vga);
+
+		mtk_phy_update_field(sif_lane_base + PEXTP_ANA_LN_TRX_A8,
+				     RG_XTP_LN_RX_LEQ_RL_DFE_CAL, cal->rx_leq_rl_dfe);
+
+		mtk_phy_update_field(sif_lane_base + PEXTP_ANA_LN_TRX_A0,
+				     RG_XTP_LN_RX_IMPSEL, cal->rx_impsel);
+
+		mtk_phy_update_field(sif_lane_base + PEXTP_ANA_LN_TRX_A0,
+				     RG_XTP_LN_TX_IMPSEL_PMOS, cal->tx_impsel.pmos);
+
+		mtk_phy_update_field(sif_lane_base + PEXTP_ANA_LN_TRX_A0,
+				     RG_XTP_LN_TX_IMPSEL_NMOS, cal->tx_impsel.nmos);
+	}
+}
+
+/**
+ * mtk_pcie_sphy_init() - Initialize the PCI-Express S-PHY
+ * @phy: the phy to be initialized
+ *
+ * The hardware settings will be reset during suspend, it should be
+ * reinitialized when the consumer calls phy_init() again on resume.
+ */
+static int mtk_pcie_sphy_init(struct phy *phy)
+{
+	struct mtk_pcie_sphy *pcie_sphy = phy_get_drvdata(phy);
+	struct mtk_pcie_sphy_imp_sel tx_impsel;
+	int i;
+
+	/* Set CKM Bias wait time to 4 microseconds */
+	mtk_phy_update_field(pcie_sphy->ckm_base + XTP_CKM_FORCE_6,
+			     RG_CKM_BIAS_WAIT_PRD_US, 4);
+
+	/* TPLL needs 63 ref_ck ticks to stabilize when setting frequency */
+	mtk_phy_update_field(pcie_sphy->sif_base + PEXTP_DIG_GLB_TPLL_CTL0,
+			     RG_XTP_TPLL_SET_STABLE_TIME_SEL, 63);
+
+	/* TPLL needs 3 ref_ck ticks to stabilize when powering on... */
+	mtk_phy_update_field(pcie_sphy->sif_base + PEXTP_DIG_GLB_TPLL_CTL0,
+			     RG_XTP_TPLL_PWE_ON_STABLE_TIME_SEL, 3);
+
+	/* ...and the same goes for setting isolation */
+	mtk_phy_update_field(pcie_sphy->sif_base + PEXTP_DIG_GLB_TPLL_CTL2,
+			     RG_XTP_TPLL_ISO_EN_STABLE_TIME_SEL, 3);
+
+	/* XTAL doesn't need any stabilization time */
+	mtk_phy_update_field(pcie_sphy->sif_base + PEXTP_DIG_GLB_CKBG0,
+			     RG_XTP_CKBG_XTAL_STABLE_TIME_SEL, 0);
+
+	/* Keep pextp_ckm enabled when in L1SS_L1S1 state */
+	mtk_phy_clear_bits(pcie_sphy->sif_base + PEXTP_DIG_GLB_CLKREQ_CTL, RG_XTP_CKM_EN_L1S1);
+
+	/* Set PIPE to reset TPLL */
+	mtk_phy_clear_bits(pcie_sphy->sif_base + PEXTP_DIG_GLB_TOP, RG_XTP_BYPASS_PIPE_RST_RC);
+
+	/* Set TPLL P-Path gain compensation to 1 */
+	mtk_phy_update_field(pcie_sphy->sif_base + PEXTP_ANA_GLB_TPLL1_RSVD,
+			     RG_XTP_GLB_TPLL1_P_PATH_GAIN, 1);
+
+	for (i = 0; i < pcie_sphy->num_lanes; i++) {
+		void __iomem *sif_lane_base = pcie_sphy->sif_base + PEXTP_REG_LANE(i);
+
+		/* Set RX Lane AEQ CTRL-E Search Error type to h1.5 + h2.5 */
+		mtk_phy_update_field(sif_lane_base + PEXTP_ANA_LN_TRX_6C,
+				     RG_XTP_LN_RX_AEQ_CTLE_ERR_TYPE,
+				     AEQ_CTLE_SEARCH_ERR_TYPE_H1P5_H2P5);
+
+		mtk_phy_set_bits(sif_lane_base + PEXTP_ANA_LN_TRX_34, RG_XTP_LN_RX_FE);
+
+		/* TRX: Select CTLE1 for RX Lane AutoEQ CTRL-E Setting on Gen4 */
+		mtk_phy_update_field(sif_lane_base + PEXTP_DIG_LN_TRX_PIPE_IF_17,
+				     RG_XTP_LN_RX_LF_CTLE_CSEL_GEN4, 1);
+
+		/* Set RX Lane AutoEQ CTRL-E for PCI-Express Gen1 to Gen 4 */
+		mtk_phy_update_field(sif_lane_base + PEXTP_DIG_LN_RX_F0,
+				     RG_XTP_LN_RX_GEN1_CTLE1_CSEL, 13);
+
+		mtk_phy_update_field(sif_lane_base + PEXTP_DIG_LN_RX_F0,
+				     RG_XTP_LN_RX_GEN2_CTLE1_CSEL, 13);
+
+		mtk_phy_update_field(sif_lane_base + PEXTP_DIG_LN_RX_F0,
+				     RG_XTP_LN_RX_GEN3_CTLE1_CSEL, 13);
+
+		mtk_phy_update_field(sif_lane_base + PEXTP_DIG_LN_RX_F0,
+				     RG_XTP_LN_RX_GEN4_CTLE1_CSEL, 0);
+
+		/* Set RX Lane AutoEQ's Edge EQ Ratio to 22 * 0.0625 = 1.375 */
+		mtk_phy_update_field(sif_lane_base + PEXTP_DIG_LN_RX2_AEQ_EDGE_0,
+				     RG_XTP_LN_RX_AEQ_EGEQ_RATIO_GEN3, 22);
+
+		mtk_phy_update_field(sif_lane_base + PEXTP_DIG_LN_RX2_AEQ_EDGE_0,
+				     RG_XTP_LN_RX_AEQ_EGEQ_RATIO_GEN4, 22);
+
+		/* Setup Digital lane TX Link Characteristics Table */
+		mtk_phy_update_field(sif_lane_base + PEXTP_DIG_LN_TX_LC_TABLE_RSWN_4,
+				     RG_XTP_LN_TX_LC_PRESET_MGx_Px_C0, 10);
+
+		mtk_phy_update_field(sif_lane_base + PEXTP_DIG_LN_TX_LC_TABLE_RSWN_4,
+				     RG_XTP_LN_TX_LC_PRESET_MGx_Px_CP1, 2);
+
+		mtk_phy_update_field(sif_lane_base + PEXTP_DIG_LN_TX_LC_TABLE_RSWN_8,
+				     RG_XTP_LN_TX_LC_PRESET_MGx_Px_C0, 11);
+
+		mtk_phy_update_field(sif_lane_base + PEXTP_DIG_LN_TX_LC_TABLE_RSWN_8,
+				     RG_XTP_LN_TX_LC_PRESET_MGx_Px_CP1, 1);
+
+		mtk_phy_update_field(sif_lane_base + PEXTP_DIG_LN_TX_LC_TABLE_RSWN_C,
+				     RG_XTP_LN_TX_LC_PRESET_MGx_Px_C0, 12);
+
+		mtk_phy_update_field(sif_lane_base + PEXTP_DIG_LN_TX_LC_TABLE_RSWN_10,
+				     RG_XTP_LN_TX_LC_PRESET_MGx_Px_C0, 13);
+
+		mtk_phy_update_field(sif_lane_base + PEXTP_DIG_LN_TX_LC_TABLE_RSWN_10,
+				     RG_XTP_LN_TX_LC_PRESET_MGx_Px_CM1, 1);
+
+		mtk_phy_update_field(sif_lane_base + PEXTP_DIG_LN_TX_LC_TABLE_RSWN_14,
+				     RG_XTP_LN_TX_LC_PRESET_MGx_Px_C0, 11);
+
+		mtk_phy_update_field(sif_lane_base + PEXTP_DIG_LN_TX_LC_TABLE_RSWN_14,
+				     RG_XTP_LN_TX_LC_PRESET_MGx_Px_CM1, 1);
+
+		mtk_phy_update_field(sif_lane_base + PEXTP_DIG_LN_TX_LC_TABLE_RSWN_18,
+				     RG_XTP_LN_TX_LC_PRESET_MGx_Px_C0, 10);
+
+		mtk_phy_update_field(sif_lane_base + PEXTP_DIG_LN_TX_LC_TABLE_RSWN_18,
+				     RG_XTP_LN_TX_LC_PRESET_MGx_Px_CM1, 2);
+	}
+
+	if (pcie_sphy->calibration.supported) {
+		mtk_pcie_sphy_apply_calibration(pcie_sphy);
+
+		tx_impsel.pmos = pcie_sphy->calibration.tx_impsel.pmos;
+		tx_impsel.nmos = pcie_sphy->calibration.tx_impsel.nmos;
+	} else {
+		/* Set P=10, N=9 to prevent EMI if no calibration present */
+		tx_impsel.pmos = 10;
+		tx_impsel.nmos = 9;
+	}
+
+	/* Select TX Impedance on N and P MOSFETs */
+	for (i = 0; i < pcie_sphy->num_lanes; i++) {
+		void __iomem *sif_lane_base = pcie_sphy->sif_base + PEXTP_REG_LANE(i);
+
+		mtk_phy_update_field(sif_lane_base + PEXTP_ANA_LN_TRX_A0,
+				     RG_XTP_LN_TX_IMPSEL_PMOS, tx_impsel.pmos);
+
+		mtk_phy_update_field(sif_lane_base + PEXTP_ANA_LN_TRX_A0,
+				     RG_XTP_LN_TX_IMPSEL_NMOS, tx_impsel.nmos);
+	}
+
+	return 0;
+}
+
+static const struct phy_ops mtk_pcie_sphy_ops = {
+	.init	= mtk_pcie_sphy_init,
+	.owner	= THIS_MODULE,
+};
+
+static int mtk_pcie_sphy_get_one_cal_para(struct device *dev, const char *name, u8 max_val)
+{
+	u16 buf;
+	u8 tmp;
+	int ret;
+
+	/*
+	 * All of the calibrations are always max 8 bits long, but some may
+	 * be split between two different 8-bits cells: handle this corner
+	 * case by retrying reading as u16.
+	 */
+	ret = nvmem_cell_read_u8(dev, name, &tmp);
+	if (ret == 0)
+		buf = tmp;
+	else
+		ret = nvmem_cell_read_u16(dev, name, &buf);
+
+	if (ret)
+		return dev_err_probe(dev, ret,
+				     "Cannot get calibration data for %s\n", name);
+
+	if (buf == 0) {
+		dev_info(dev, "No calibration for %s. Using defaults\n", name);
+		return -ENOENT;
+	}
+
+	if (buf > max_val)
+		return dev_err_probe(dev, -ERANGE,
+				     "Bad value %u retrieved for %s.\n", buf, name);
+
+	return buf;
+}
+
+static int mtk_pcie_sphy_get_calibration_data(struct mtk_pcie_sphy *pcie_sphy)
+{
+	struct mtk_pcie_sphy_efuse *cal = &pcie_sphy->calibration;
+	struct device *dev = pcie_sphy->dev;
+	u8 version;
+	int ret;
+
+	ret = mtk_pcie_sphy_get_one_cal_para(dev, "int-r",
+					     FIELD_MAX(RG_XTP_GLB_BIAS_INTR_CTRL));
+	if (ret < 0)
+		goto end;
+	cal->int_r_ctrl = ret;
+
+	ret = mtk_pcie_sphy_get_one_cal_para(dev, "xtp-vtrim",
+					     FIELD_MAX(RG_XTP_GLB_BIAS_V2V_VTRIM));
+	if (ret < 0)
+		goto end;
+	cal->xtp_vtrim = ret;
+
+	ret = mtk_pcie_sphy_get_one_cal_para(dev, "cktx-pmos",
+					     FIELD_MAX(RG_CKM_CKTX_IMPSEL_PMOS));
+	if (ret < 0)
+		goto end;
+	cal->cktx_impsel.pmos = ret;
+
+	ret = mtk_pcie_sphy_get_one_cal_para(dev, "cktx-nmos",
+					     FIELD_MAX(RG_CKM_CKTX_IMPSEL_NMOS));
+	if (ret < 0)
+		goto end;
+	cal->cktx_impsel.nmos = ret;
+
+	ret = mtk_pcie_sphy_get_one_cal_para(dev, "cktx-r-mid",
+					     FIELD_MAX(RG_CKM_CKTX_IMPSEL_SW));
+	if (ret < 0)
+		goto end;
+	cal->cktx_r_mid = ret;
+
+	ret = mtk_pcie_sphy_get_one_cal_para(dev, "rxfe-lanes-rl-ctle",
+					     FIELD_MAX(RG_XTP_LN_RX_LEQ_RL_CTLE_CAL));
+	if (ret < 0)
+		goto end;
+	cal->rx_leq_rl_ctle = ret;
+
+	ret = mtk_pcie_sphy_get_one_cal_para(dev, "rxfe-lanes-rl-vga",
+					     FIELD_MAX(RG_XTP_LN_RX_LEQ_RL_VGA_CAL));
+	if (ret < 0)
+		goto end;
+	cal->rx_leq_rl_vga = ret;
+
+	ret = mtk_pcie_sphy_get_one_cal_para(dev, "rxfe-lanes-rl-dfe",
+					     FIELD_MAX(RG_XTP_LN_RX_LEQ_RL_DFE_CAL));
+	if (ret < 0)
+		goto end;
+	cal->rx_leq_rl_dfe = ret;
+
+	ret = mtk_pcie_sphy_get_one_cal_para(dev, "rx-lanes-imp",
+					     FIELD_MAX(RG_XTP_LN_RX_IMPSEL));
+	if (ret < 0)
+		goto end;
+	cal->rx_impsel = ret;
+
+	ret = mtk_pcie_sphy_get_one_cal_para(dev, "tx-lanes-pmos",
+					     FIELD_MAX(RG_XTP_LN_TX_IMPSEL_PMOS));
+	if (ret < 0)
+		goto end;
+	cal->tx_impsel.pmos = ret;
+
+	ret = mtk_pcie_sphy_get_one_cal_para(dev, "tx-lanes-nmos",
+					     FIELD_MAX(RG_XTP_LN_TX_IMPSEL_NMOS));
+	if (ret < 0)
+		goto end;
+	cal->tx_impsel.nmos = ret;
+
+	ret = mtk_pcie_sphy_get_one_cal_para(dev, "tx-ln0-rswn",
+					     FIELD_MAX(RG_XTP_LN_TX_RSWN_IMPSEL));
+	if (ret < 0)
+		goto end;
+	cal->tx_rswn_impsel[0] = ret;
+
+	if (pcie_sphy->num_lanes == 2) {
+		ret = mtk_pcie_sphy_get_one_cal_para(dev, "tx-ln1-rswn",
+						     FIELD_MAX(RG_XTP_LN_TX_RSWN_IMPSEL));
+		if (ret < 0)
+			goto end;
+		cal->tx_rswn_impsel[1] = ret;
+	}
+
+	ret = mtk_pcie_sphy_get_one_cal_para(dev, "cal-version", 15);
+	if (ret < 0)
+		goto end;
+	version = ret;
+
+	/* Quirk for eFuse calibration table versions 0 to 4 */
+	if ((version <= MTK_PCIE_SPHY_CALIBRATION_LAST_QUIRK_VER) &&
+	    cal->rx_leq_rl_ctle == 10) {
+		cal->rx_leq_rl_vga = cal->rx_leq_rl_ctle;
+		cal->rx_leq_rl_dfe = cal->rx_leq_rl_ctle;
+	}
+
+end:
+	if (ret < 0) {
+		/*
+		 * If any of the calibration values is missing, or if there is
+		 * no calibration at all in the eFuses, this is not a problem,
+		 * as the PHY doesn't require one to actually work.
+		 */
+		if (ret == -ENOENT) {
+			cal->supported = false;
+			return 0;
+		}
+		return ret;
+	};
+	cal->supported = true;
+
+	return 0;
+}
+
+static int mtk_pcie_sphy_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct phy_provider *provider;
+	struct mtk_pcie_sphy *pcie_sphy;
+	u32 num_lanes;
+	int ret;
+
+	pcie_sphy = devm_kzalloc(dev, sizeof(*pcie_sphy), GFP_KERNEL);
+	if (!pcie_sphy)
+		return -ENOMEM;
+
+	pcie_sphy->sif_base = devm_platform_ioremap_resource_byname(pdev, "sif");
+	if (IS_ERR(pcie_sphy->sif_base))
+		return dev_err_probe(dev, PTR_ERR(pcie_sphy->sif_base),
+				     "Failed to map phy-sif base\n");
+
+	pcie_sphy->ckm_base = devm_platform_ioremap_resource_byname(pdev, "ckm");
+	if (IS_ERR(pcie_sphy->ckm_base))
+		return dev_err_probe(dev, PTR_ERR(pcie_sphy->ckm_base),
+				     "Failed to map phy-ckm base\n");
+
+	pcie_sphy->phy = devm_phy_create(dev, dev->of_node, &mtk_pcie_sphy_ops);
+	if (IS_ERR(pcie_sphy->phy))
+		return dev_err_probe(dev, PTR_ERR(pcie_sphy->phy),
+				     "Failed to create PCIe phy\n");
+
+	ret = of_property_read_u32(dev->of_node, "num-lanes", &num_lanes);
+	if (ret)
+		num_lanes = 1;
+	else if (num_lanes > 4)
+		return dev_err_probe(dev, -EINVAL, "Invalid number of lanes.\n");
+
+	pcie_sphy->num_lanes = num_lanes;
+	pcie_sphy->dev = dev;
+
+	if (pcie_sphy->num_lanes <= MTK_PCIE_SPHY_CALIBRATION_MAX_DATA_LANES) {
+		ret = mtk_pcie_sphy_get_calibration_data(pcie_sphy);
+		if (ret)
+			return ret;
+	}
+
+	phy_set_drvdata(pcie_sphy->phy, pcie_sphy);
+
+	ret = devm_pm_runtime_enable(dev);
+	if (ret)
+		return ret;
+
+	provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate);
+	if (IS_ERR(provider))
+		return dev_err_probe(dev, PTR_ERR(provider),
+				     "Could not register PCI-Express S-PHY\n");
+
+	return 0;
+}
+
+static const struct of_device_id mtk_pcie_sphy_of_match[] = {
+	{ .compatible = "mediatek,mt8196-pcie-sphy" },
+	{ /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, mtk_pcie_sphy_of_match);
+
+static struct platform_driver mtk_pcie_sphy_driver = {
+	.probe	= mtk_pcie_sphy_probe,
+	.driver	= {
+		.name = "mtk-pcie-sphy",
+		.of_match_table = mtk_pcie_sphy_of_match,
+	},
+};
+module_platform_driver(mtk_pcie_sphy_driver);
+
+MODULE_DESCRIPTION("MediaTek PCIe SPHY driver");
+MODULE_AUTHOR("AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>");
+MODULE_LICENSE("GPL");
-- 
2.55.0


^ permalink raw reply related

* [PATCH v2 1/2] dt-bindings: phy: Document MT8196 MediaTek PCI-Express Gen4 S-PHY
From: AngeloGioacchino Del Regno @ 2026-07-20 13:53 UTC (permalink / raw)
  To: chunfeng.yun
  Cc: vkoul, neil.armstrong, robh, krzk+dt, conor+dt, matthias.bgg,
	angelogioacchino.delregno, linux-arm-kernel, linux-mediatek,
	linux-phy, devicetree, linux-kernel, kernel
In-Reply-To: <20260720135344.84183-1-angelogioacchino.delregno@collabora.com>

This adds bindings for the PCI-Express Gen4 S-PHY found in newer
MediaTek SoCs, such as MT8196 and its variants.

In the current "revision 3", depending on the specific port, this
S-PHY supports up to two lanes of PCI-Express Gen 4 and both EP
and RC modes.
It is not clear whether revisions/versions earlier than 3 have
ever been shipped in any other MediaTek SoC.

Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
---
 .../phy/mediatek,mt8196-pcie-sphy.yaml        | 93 +++++++++++++++++++
 1 file changed, 93 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/phy/mediatek,mt8196-pcie-sphy.yaml

diff --git a/Documentation/devicetree/bindings/phy/mediatek,mt8196-pcie-sphy.yaml b/Documentation/devicetree/bindings/phy/mediatek,mt8196-pcie-sphy.yaml
new file mode 100644
index 000000000000..c24871f7e0e5
--- /dev/null
+++ b/Documentation/devicetree/bindings/phy/mediatek,mt8196-pcie-sphy.yaml
@@ -0,0 +1,93 @@
+# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/phy/mediatek,mt8196-pcie-sphy.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: MediaTek PCI-Express Gen4 S-PHY
+
+maintainers:
+  - AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+
+description:
+  The MediaTek PCI-Express Gen4 S-PHY is capable of data serialization
+  and de-serialization with 8, 10, 128 or 130 bits (16GT/s) encoding
+  and decoding, has analog buffers, elastic buffers and mechanisms for
+  receiver detection.
+  This PHY supports link rates of 2.5, 5.0, 6.0 and 16.0 GT/s per-lane
+  in both Root Complex (RC) and End Point (EP) modes, depending on the
+  chosen port.
+  The Digital PHY (PHYD) part adheres to the Intel PIPE (PHY Interface
+  for the PCIe) specification.
+
+properties:
+  compatible:
+    const: mediatek,mt8196-pcie-sphy
+
+  reg:
+    items:
+      - description: System Interface (SIF) registers
+      - description: Clock Management (CKM) registers
+
+  reg-names:
+    items:
+      - const: sif
+      - const: ckm
+
+  "#phy-cells":
+    const: 0
+
+  nvmem-cells:
+    items:
+      - description: Internal resistor selection of TX Bias Current
+      - description: XTP Bias V2V voltage calibration
+      - description: S-PLL CKTX Impedance Selection (P-MOSFET side)
+      - description: S-PLL CKTX Impedance Selection (N-MOSFET side)
+      - description: S-PLL CKTX Intermediate Transition Impedance
+      - description: RX Front-End Return Loss Continuous Time Linear EQ
+      - description: RX Front-End Return Loss Variable Gain Amplifier
+      - description: RX Front-End Return Loss Decision Feedback EQ
+      - description: RX Impedance Selection
+      - description: TX Impedance Selection (P-MOSFET side)
+      - description: TX Impedance Selection (N-MOSFET side)
+      - description: TX Lane 0 Switch Resistance (RSWn)
+      - description: TX Lane 1 Switch Resistance (RSWn)
+      - description: eFuse calibration table version
+
+  nvmem-cell-names:
+    items:
+      - const: int-r
+      - const: xtp-vtrim
+      - const: cktx-pmos
+      - const: cktx-nmos
+      - const: cktx-r-mid
+      - const: rxfe-lanes-rl-ctle
+      - const: rxfe-lanes-rl-vga
+      - const: rxfe-lanes-rl-dfe
+      - const: rx-lanes-imp
+      - const: tx-lanes-pmos
+      - const: tx-lanes-nmos
+      - const: tx-ln0-rswn
+      - const: tx-ln1-rswn
+      - const: cal-version
+
+  power-domains:
+    maxItems: 1
+
+required:
+  - compatible
+  - reg
+  - reg-names
+  - "#phy-cells"
+
+additionalProperties: false
+
+examples:
+  - |
+    phy@16900000 {
+        compatible = "mediatek,mt8196-pcie-sphy";
+        reg = <0x16900000 0x10000>, <0x16920000 0x10000>;
+        reg-names = "sif", "ckm";
+        power-domains = <&spm 10>;
+        #phy-cells = <0>;
+    };
-- 
2.55.0


^ permalink raw reply related

* [PATCH v2 0/2] PHY: Add MediaTek PCI-Express Gen4 S-PHY Driver
From: AngeloGioacchino Del Regno @ 2026-07-20 13:53 UTC (permalink / raw)
  To: chunfeng.yun
  Cc: vkoul, neil.armstrong, robh, krzk+dt, conor+dt, matthias.bgg,
	angelogioacchino.delregno, linux-arm-kernel, linux-mediatek,
	linux-phy, devicetree, linux-kernel, kernel

Changes in v2:
 - Added items/description to reg in binding
 - Added missing pm_runtime.h inclusion
 - Moved pm_runtime_enable call to before registering PHY
 - Fixed pmos/nmos variable size for 5 bits calibration values
 - Fixed calibration for single-lane PCIe, as in, the ln1 rswn
   calibration nvmem value is ignored in code if it's single
   lane and will not return an error; this is due to the fact
   that, effectively, single-lane may have a zero calibration
   in tx-ln1-rswn which is fine, as that'd be anyway unused
 - Changed calibration data errors to dev_err_probe and changed
   the "no calibration for ..." message to dev_info instead

This adds a driver for the PCI-Express Gen4 "S-PHY" found in the
Genio MT8894, Kompanio MT8196, Dimensity MT6991 SoCs (which are
all variants of the same chip).

This was successfully tested on MT8894 and MT8196.

AngeloGioacchino Del Regno (2):
  dt-bindings: phy: Document MT8196 MediaTek PCI-Express Gen4 S-PHY
  phy: mediatek: Add support for PCI-Express Gen4 S-PHY

 .../phy/mediatek,mt8196-pcie-sphy.yaml        |  93 +++
 drivers/phy/mediatek/Kconfig                  |   9 +
 drivers/phy/mediatek/Makefile                 |   1 +
 drivers/phy/mediatek/phy-mtk-pcie-sphy.c      | 561 ++++++++++++++++++
 4 files changed, 664 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/phy/mediatek,mt8196-pcie-sphy.yaml
 create mode 100644 drivers/phy/mediatek/phy-mtk-pcie-sphy.c

-- 
2.55.0


^ permalink raw reply


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox