Linux-ARM-Kernel Archive on lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v3 3/4] Input: adc-keys - Use dev_err_probe in probe function
From: Nicolas Frattaroli @ 2026-04-08 17:49 UTC (permalink / raw)
  To: Dmitry Torokhov, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	Alexandre Belloni, Heiko Stuebner
  Cc: kernel, linux-input, devicetree, linux-kernel, linux-arm-kernel,
	linux-rockchip, Nicolas Frattaroli
In-Reply-To: <20260408-rock4d-audio-v3-0-49e43c3c2a68@collabora.com>

Rework the probe function, and functions called by the probe function,
to use dev_err_probe for error logging.

While at it, also do some minor style cleanups, like not error logging
on -ENOMEM and using ! instead of == 0.

Reviewed-by: Alexandre Belloni <alexandre.belloni@bootlin.com>
Signed-off-by: Nicolas Frattaroli <nicolas.frattaroli@collabora.com>
---
 drivers/input/keyboard/adc-keys.c | 53 ++++++++++++++++-----------------------
 1 file changed, 21 insertions(+), 32 deletions(-)

diff --git a/drivers/input/keyboard/adc-keys.c b/drivers/input/keyboard/adc-keys.c
index 62376f34f7d0..6f2ddcecea99 100644
--- a/drivers/input/keyboard/adc-keys.c
+++ b/drivers/input/keyboard/adc-keys.c
@@ -74,10 +74,8 @@ static int adc_keys_load_keymap(struct device *dev, struct adc_keys_state *st)
 	int i;
 
 	st->num_keys = device_get_child_node_count(dev);
-	if (st->num_keys == 0) {
-		dev_err(dev, "keymap is missing\n");
-		return -EINVAL;
-	}
+	if (!st->num_keys)
+		return dev_err_probe(dev, -EINVAL, "keymap is missing\n");
 
 	map = devm_kmalloc_array(dev, st->num_keys, sizeof(*map), GFP_KERNEL);
 	if (!map)
@@ -86,17 +84,16 @@ static int adc_keys_load_keymap(struct device *dev, struct adc_keys_state *st)
 	i = 0;
 	device_for_each_child_node_scoped(dev, child) {
 		if (fwnode_property_read_u32(child, "press-threshold-microvolt",
-					     &map[i].voltage)) {
-			dev_err(dev, "Key with invalid or missing voltage\n");
-			return -EINVAL;
-		}
+					     &map[i].voltage))
+			return dev_err_probe(dev, -EINVAL,
+					     "Key with invalid or missing voltage\n");
+
 		map[i].voltage /= 1000;
 
 		if (fwnode_property_read_u32(child, "linux,code",
-					     &map[i].code)) {
-			dev_err(dev, "Key with invalid or missing linux,code\n");
-			return -EINVAL;
-		}
+					     &map[i].code))
+			return dev_err_probe(dev, -EINVAL,
+					     "Key with invalid or missing linux,code\n");
 
 		if (fwnode_property_read_u32(child, "linux,input-type",
 					     &map[i].type))
@@ -129,7 +126,8 @@ static int adc_keys_probe(struct platform_device *pdev)
 
 	st->channel = devm_iio_channel_get(dev, "buttons");
 	if (IS_ERR(st->channel))
-		return PTR_ERR(st->channel);
+		return dev_err_probe(dev, PTR_ERR(st->channel),
+				     "Could not get iio channel\n");
 
 	if (!st->channel->indio_dev)
 		return -ENXIO;
@@ -138,16 +136,13 @@ static int adc_keys_probe(struct platform_device *pdev)
 	if (error < 0)
 		return error;
 
-	if (type != IIO_VOLTAGE) {
-		dev_err(dev, "Incompatible channel type %d\n", type);
-		return -EINVAL;
-	}
+	if (type != IIO_VOLTAGE)
+		return dev_err_probe(dev, -EINVAL, "Incompatible channel type %d\n", type);
 
 	if (device_property_read_u32(dev, "keyup-threshold-microvolt",
-				     &st->keyup_voltage)) {
-		dev_err(dev, "Invalid or missing keyup voltage\n");
-		return -EINVAL;
-	}
+				     &st->keyup_voltage))
+		return dev_err_probe(dev, -EINVAL, "Invalid or missing keyup voltage\n");
+
 	st->keyup_voltage /= 1000;
 
 	error = adc_keys_load_keymap(dev, st);
@@ -155,10 +150,8 @@ static int adc_keys_probe(struct platform_device *pdev)
 		return error;
 
 	input = devm_input_allocate_device(dev);
-	if (!input) {
-		dev_err(dev, "failed to allocate input device\n");
+	if (!input)
 		return -ENOMEM;
-	}
 
 	input_set_drvdata(input, st);
 
@@ -178,19 +171,15 @@ static int adc_keys_probe(struct platform_device *pdev)
 
 
 	error = input_setup_polling(input, adc_keys_poll);
-	if (error) {
-		dev_err(dev, "Unable to set up polling: %d\n", error);
-		return error;
-	}
+	if (error)
+		return dev_err_probe(dev, error, "Unable to set up polling\n");
 
 	if (!device_property_read_u32(dev, "poll-interval", &value))
 		input_set_poll_interval(input, value);
 
 	error = input_register_device(input);
-	if (error) {
-		dev_err(dev, "Unable to register input device: %d\n", error);
-		return error;
-	}
+	if (error)
+		return dev_err_probe(dev, error, "Unable to register input device\n");
 
 	return 0;
 }

-- 
2.53.0



^ permalink raw reply related

* [PATCH v3 4/4] arm64: dts: rockchip: add analog audio to ROCK 4D
From: Nicolas Frattaroli @ 2026-04-08 17:49 UTC (permalink / raw)
  To: Dmitry Torokhov, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	Alexandre Belloni, Heiko Stuebner
  Cc: kernel, linux-input, devicetree, linux-kernel, linux-arm-kernel,
	linux-rockchip, Nicolas Frattaroli, Cristian Ciocaltea
In-Reply-To: <20260408-rock4d-audio-v3-0-49e43c3c2a68@collabora.com>

The RADXA ROCK 4D, like many other Rockchip-based boards, uses an ES8388
analog audio codec. On the production version of the board, the codec's
LOUT1 and ROUT1 pins are tied to the headphone jack, whereas pins LOUT2
and ROUT2 lead to a non-populated speaker amplifier that itself leads to
a non-populated speaker jack. The schematic is still haunted by the
ghosts of those symbols, but it clearly marks them as "NC".

The 3.5mm TRRS jack has its microphone ring (and ground ring) wired to
the codec's LINPUT1 and RINPUT1 pins for differential signalling.

Furthermore, it uses the SoCs ADC to detect whether the inserted cable
is of headphones (i.e., no microphone), or a headset (i.e., with
microphone). The way this is done is that the ADC input taps the output
of a 100K/100K resistor divider that divides the microphone ring pin
that's pulled up to 3.3V.

There is no ADC level difference between a completely empty jack and one
with a set of headphones (i.e., ones that don't have a microphone)
connected. Consequently headphone insertion detection isn't something
that can be done.

Add the necessary codec and audio card nodes. The non-populated parts,
i.e. LOUT2 and ROUT2, are not modeled at all, as they are not present on
the hardware.

Also, add an adc-keys node for the headset detection, which uses an
input type of EV_SW with the SW_MICROPHONE_INSERT keycode. Below the
220mV pressed voltage level of our SW_MICROPHONE_INSERT switch, we also
define a button that emits a KEY_RESERVED code, which is there to model
this part of the voltage range as not just being extra legroom for the
button above it, but actually a state that is encountered in the real
world, and should be recognised as a valid state for the ADC range to be
in so that no "closer" ADC button is chosen.

Tested-by: Cristian Ciocaltea <cristian.ciocaltea@collabora.com>
Signed-off-by: Nicolas Frattaroli <nicolas.frattaroli@collabora.com>
---
 arch/arm64/boot/dts/rockchip/rk3576-rock-4d.dts | 90 +++++++++++++++++++++++++
 1 file changed, 90 insertions(+)

diff --git a/arch/arm64/boot/dts/rockchip/rk3576-rock-4d.dts b/arch/arm64/boot/dts/rockchip/rk3576-rock-4d.dts
index 899a84b1fbf9..c848c706196e 100644
--- a/arch/arm64/boot/dts/rockchip/rk3576-rock-4d.dts
+++ b/arch/arm64/boot/dts/rockchip/rk3576-rock-4d.dts
@@ -6,6 +6,7 @@
 /dts-v1/;
 
 #include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
 #include <dt-bindings/leds/common.h>
 #include <dt-bindings/pinctrl/rockchip.h>
 #include <dt-bindings/pwm/pwm.h>
@@ -37,6 +38,31 @@ hdmi_con_in: endpoint {
 		};
 	};
 
+	es8388_sound: es8388-sound {
+		compatible = "simple-audio-card";
+		simple-audio-card,format = "i2s";
+		simple-audio-card,mclk-fs = <256>;
+		simple-audio-card,name = "On-board Analog ES8388";
+		simple-audio-card,widgets = "Microphone", "Headphone Mic",
+					    "Headphone", "Headphone";
+		simple-audio-card,routing = "Headphone", "LOUT1",
+					    "Headphone", "ROUT1",
+					    "Left PGA Mux", "Differential Mux",
+					    "Differential Mux", "LINPUT1",
+					    "Differential Mux", "RINPUT1",
+					    "LINPUT1", "Headphone Mic",
+					    "RINPUT1", "Headphone Mic";
+
+		simple-audio-card,cpu {
+			sound-dai = <&sai1>;
+		};
+
+		simple-audio-card,codec {
+			sound-dai = <&es8388>;
+			system-clock-frequency = <12288000>;
+		};
+	};
+
 	rfkill {
 		compatible = "rfkill-gpio";
 		pinctrl-names = "default";
@@ -65,6 +91,37 @@ user-led {
 		};
 	};
 
+	saradc_keys: adc-keys {
+		compatible = "adc-keys";
+		io-channels = <&saradc 3>;
+		io-channel-names = "buttons";
+		keyup-threshold-microvolt = <3000000>;
+		poll-interval = <100>;
+
+		/*
+		 * During insertion and removal of a regular set of headphones,
+		 * i.e. one without a microphone, the voltage level briefly
+		 * dips below the 220mV of the headset connection switch.
+		 * By having a button definition with a KEY_RESERVED signal
+		 * between 0 to 220, we ensure no driver implementation thinks
+		 * that the closest thing to 0V is 220mV so clearly there must
+		 * be a headset connected.
+		 */
+
+		button-headset-disconnected {
+			label = "Headset Microphone Disconnected";
+			linux,code = <KEY_RESERVED>;
+			press-threshold-microvolt = <0>;
+		};
+
+		button-headset-connected {
+			label = "Headset Microphone Connected";
+			linux,code = <SW_MICROPHONE_INSERT>;
+			linux,input-type = <EV_SW>;
+			press-threshold-microvolt = <220000>;
+		};
+	};
+
 	vcc_5v0_dcin: regulator-vcc-5v0-dcin {
 		compatible = "regulator-fixed";
 		regulator-always-on;
@@ -696,6 +753,25 @@ eeprom@50 {
 	};
 };
 
+&i2c3 {
+	status = "okay";
+
+	es8388: audio-codec@10 {
+		compatible = "everest,es8388", "everest,es8328";
+		reg = <0x10>;
+		clocks = <&cru CLK_SAI1_MCLKOUT_TO_IO>;
+		AVDD-supply = <&vcca_3v3_s0>;
+		DVDD-supply = <&vcc_3v3_s0>;
+		HPVDD-supply = <&vcca_3v3_s0>;
+		PVDD-supply = <&vcc_3v3_s0>;
+		assigned-clocks = <&cru CLK_SAI1_MCLKOUT_TO_IO>;
+		assigned-clock-rates = <12288000>;
+		#sound-dai-cells = <0>;
+		pinctrl-names = "default";
+		pinctrl-0 = <&sai1m0_mclk>;
+	};
+};
+
 &mdio0 {
 	rgmii_phy0: ethernet-phy@1 {
 		compatible = "ethernet-phy-id001c.c916";
@@ -770,10 +846,24 @@ wifi_en_h: wifi-en-h {
 	};
 };
 
+&sai1 {
+	pinctrl-names = "default";
+	pinctrl-0 = <&sai1m0_lrck
+		     &sai1m0_sclk
+		     &sai1m0_sdi0
+		     &sai1m0_sdo0>;
+	status = "okay";
+};
+
 &sai6 {
 	status = "okay";
 };
 
+&saradc {
+	vref-supply = <&vcca1v8_pldo2_s0>;
+	status = "okay";
+};
+
 &sdmmc {
 	bus-width = <4>;
 	cap-mmc-highspeed;

-- 
2.53.0



^ permalink raw reply related

* Re: [PATCH] Subject: ASoC stm32_sai: fix incorrect BCLK polarity for DSP_A/B, LEFT_J
From: Mark Brown @ 2026-04-08 12:25 UTC (permalink / raw)
  To: alsa-devel, Tomasz Merta
  Cc: olivier.moysan, arnaud.pouliquen, lgirdwood, perex, tiwai,
	mcoquelin.stm32, alexandre.torgue, linux-stm32, linux-arm-kernel,
	linux-kernel, Tomasz Merta
In-Reply-To: <20260408084056.20588-1-tommerta@gmail.com>

On Wed, 08 Apr 2026 10:40:56 +0200, Tomasz Merta wrote:
> Subject: ASoC stm32_sai: fix incorrect BCLK polarity for DSP_A/B, LEFT_J

Applied to

   https://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound.git for-7.0

Thanks!

[1/1] Subject: ASoC stm32_sai: fix incorrect BCLK polarity for DSP_A/B, LEFT_J
      https://git.kernel.org/broonie/sound/c/0669631dbccd

All being well this means that it will be integrated into the linux-next
tree (usually sometime in the next 24 hours) and sent to Linus during
the next merge window (or sooner if it is a bug fix), however if
problems are discovered then the patch may be dropped or reverted.

You may get further e-mails resulting from automated or manual testing
and review of the tree, please engage with people reporting problems and
send followup patches addressing any issues that are reported if needed.

If any updates are required or you are submitting further changes they
should be sent as incremental updates against current git, existing
patches will not be replaced.

Please add any relevant lists and maintainers to the CCs when replying
to this mail.

Thanks,
Mark



^ permalink raw reply

* [PATCH net] net: airoha: Add missing RX_CPU_IDX() configuration in airoha_qdma_cleanup_rx_queue()
From: Lorenzo Bianconi @ 2026-04-08 18:26 UTC (permalink / raw)
  To: Andrew Lunn, David S. Miller, Eric Dumazet, Jakub Kicinski,
	Paolo Abeni, Lorenzo Bianconi
  Cc: linux-arm-kernel, linux-mediatek, netdev

When the descriptor index written in REG_RX_CPU_IDX() is equal to the one
stored in REG_RX_DMA_IDX(), the hw will stop since the QDMA RX ring is
empty.
Add missing REG_RX_CPU_IDX() configuration in airoha_qdma_cleanup_rx_queue
routine during QDMA RX ring cleanup.

Fixes: 514aac359987 ("net: airoha: Add missing cleanup bits in airoha_qdma_cleanup_rx_queue()")
Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
---
 drivers/net/ethernet/airoha/airoha_eth.c | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/drivers/net/ethernet/airoha/airoha_eth.c b/drivers/net/ethernet/airoha/airoha_eth.c
index 91cb63a32d99..919b7009cbe5 100644
--- a/drivers/net/ethernet/airoha/airoha_eth.c
+++ b/drivers/net/ethernet/airoha/airoha_eth.c
@@ -819,6 +819,11 @@ static void airoha_qdma_cleanup_rx_queue(struct airoha_queue *q)
 	}
 
 	q->head = q->tail;
+	/* Set RX_DMA_IDX to RX_CPU_IDX to notify the hw the QDMA RX ring is
+	 * empty.
+	 */
+	airoha_qdma_rmw(qdma, REG_RX_CPU_IDX(qid), RX_RING_CPU_IDX_MASK,
+			FIELD_PREP(RX_RING_CPU_IDX_MASK, q->head));
 	airoha_qdma_rmw(qdma, REG_RX_DMA_IDX(qid), RX_RING_DMA_IDX_MASK,
 			FIELD_PREP(RX_RING_DMA_IDX_MASK, q->tail));
 }

---
base-commit: f821664dde29302e8450aa0597bf1e4c7c5b0a22
change-id: 20260331-airoha-cpu-idx-airoha_qdma_cleanup_rx_queue-efde9e4ab786

Best regards,
-- 
Lorenzo Bianconi <lorenzo@kernel.org>



^ permalink raw reply related

* [PATCH 1/2] dt-bindings: arm: fsl: Add SolidRun i.MX8DXL SoM and HummingBoard
From: Josua Mayer @ 2026-04-08 18:38 UTC (permalink / raw)
  To: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Shawn Guo,
	Frank Li, Sascha Hauer, Pengutronix Kernel Team, Fabio Estevam
  Cc: Yazan Shhady, Mikhail Anikin, Alexander Dahl, devicetree,
	linux-kernel, imx, linux-arm-kernel, Josua Mayer
In-Reply-To: <20260408-imx8dxl-sr-som-v1-0-ce5a39acd713@solid-run.com>

Add binding for the SolidRun i.MX8DXL based System on Module, and the
reference HummingBoard Telematics.

Signed-off-by: Josua Mayer <josua@solid-run.com>
---
 Documentation/devicetree/bindings/arm/fsl.yaml | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/Documentation/devicetree/bindings/arm/fsl.yaml b/Documentation/devicetree/bindings/arm/fsl.yaml
index 5716d701292cf..c7a885159318f 100644
--- a/Documentation/devicetree/bindings/arm/fsl.yaml
+++ b/Documentation/devicetree/bindings/arm/fsl.yaml
@@ -1376,6 +1376,13 @@ properties:
               - fsl,imx8dxl-evk           # i.MX8DXL EVK Board
           - const: fsl,imx8dxl
 
+      - description: SolidRun i.MX8DXL SoM based boards
+        items:
+          - enum:
+              - solidrun,imx8dxl-hummingboard-telematics # SolidRun i.MX8DXL SoM EVK Board
+          - const: solidrun,imx8dxl-sr-som
+          - const: fsl,imx8dxl
+
       - description: i.MX8QXP/i.MX8DX Boards with Toradex Colibri iMX8X Modules
         items:
           - enum:

-- 
2.51.0



^ permalink raw reply related

* [PATCH 0/2] arm64: dts: imx8dxl: Add SolidRun SoM and HummingBoard
From: Josua Mayer @ 2026-04-08 18:38 UTC (permalink / raw)
  To: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Shawn Guo,
	Frank Li, Sascha Hauer, Pengutronix Kernel Team, Fabio Estevam
  Cc: Yazan Shhady, Mikhail Anikin, Alexander Dahl, devicetree,
	linux-kernel, imx, linux-arm-kernel, Josua Mayer

Add bindings and description for SolidRUn i.MX8DXL based SoM and
HummingBoard Telematics.

This patch-set is based on v7.0-rc2, because rc1 was experiencing
deadlocks with imx8qxp clock driver.

Signed-off-by: Josua Mayer <josua@solid-run.com>
---
Josua Mayer (2):
      dt-bindings: arm: fsl: Add SolidRun i.MX8DXL SoM and HummingBoard
      arm64: dts: imx8dxl: Add SolidRun SoM and HummingBoard

 Documentation/devicetree/bindings/arm/fsl.yaml     |   7 +
 arch/arm64/boot/dts/freescale/Makefile             |   2 +
 .../freescale/imx8dxl-hummingboard-telematics.dts  | 536 +++++++++++++++++++++
 arch/arm64/boot/dts/freescale/imx8dxl-sr-som.dtsi  | 460 ++++++++++++++++++
 arch/arm64/boot/dts/freescale/imx8mp-sr-som.dtsi   |   1 -
 5 files changed, 1005 insertions(+), 1 deletion(-)
---
base-commit: 11439c4635edd669ae435eec308f4ab8a0804808
change-id: 20260408-imx8dxl-sr-som-f141ec343173

Best regards,
-- 
Josua Mayer <josua@solid-run.com>



^ permalink raw reply

* [PATCH 2/2] arm64: dts: imx8dxl: Add SolidRun SoM and HummingBoard
From: Josua Mayer @ 2026-04-08 18:38 UTC (permalink / raw)
  To: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Shawn Guo,
	Frank Li, Sascha Hauer, Pengutronix Kernel Team, Fabio Estevam
  Cc: Yazan Shhady, Mikhail Anikin, Alexander Dahl, devicetree,
	linux-kernel, imx, linux-arm-kernel, Josua Mayer
In-Reply-To: <20260408-imx8dxl-sr-som-v1-0-ce5a39acd713@solid-run.com>

Add support for the SolidRun i.MX8DXL System-on-Module (revision 2.1)
and its corresponding evaluation carrier board, the HummingBoard
Telematics (revision 2.0).

The SoM features:
- eMMC
- GNSS with 1PPS
- V2X DSRC Radio
- Secure Element for V2X Applications
- Inertial Sensor
- Pressure Sensor
- Compass

The HummingBoard Telematics carrier board features:
- Cellular Modem
- WiFi & Bluetooth
- RTC with backup battery
- CAN
- 100Base-TX Ethernet
- 100Base-T1 Ethernet
- Multi-interface I/O connector
- Multi-interface add-on board connector

The multi-interface I/O connector supplies power and provides basic I/O
(Console UART, 100Base-TX, 100Base-T1, CAN, and power-supply logic level
GPIOs). The SolidRun Evaluation Kit includes a suitable cable and
adapter board that breaks these out into RJ45, USB Type-A, microUSB
Console, and Terminal Block connectors.

The multi-interface add-on board connector provides additional
interfaces (4x 100Base-T1, 2x SGMII, USB 2.0 shared with the cellular
modem, CAN, MDIO, SPI, UART, PCIe, I2C, and GPIO). These add-on
interfaces are disabled by default in the base device tree and are
intended to be enabled and extended via device tree overlays.

Note that a few components physically present on the SoM were omitted
from this description due to a lack of upstream bindings and drivers:
- Pressure Sensor
- V2X DSRC Radio
- Secure Element

Signed-off-by: Josua Mayer <josua@solid-run.com>
---
 arch/arm64/boot/dts/freescale/Makefile             |   2 +
 .../freescale/imx8dxl-hummingboard-telematics.dts  | 536 +++++++++++++++++++++
 arch/arm64/boot/dts/freescale/imx8dxl-sr-som.dtsi  | 460 ++++++++++++++++++
 arch/arm64/boot/dts/freescale/imx8mp-sr-som.dtsi   |   1 -
 4 files changed, 998 insertions(+), 1 deletion(-)

diff --git a/arch/arm64/boot/dts/freescale/Makefile b/arch/arm64/boot/dts/freescale/Makefile
index 700bab4d3e600..12b946c08400b 100644
--- a/arch/arm64/boot/dts/freescale/Makefile
+++ b/arch/arm64/boot/dts/freescale/Makefile
@@ -111,6 +111,8 @@ dtb-$(CONFIG_ARCH_MXC) += imx8dxl-evk.dtb
 
 imx8dxl-evk-pcie-ep-dtbs += imx8dxl-evk.dtb imx-pcie0-ep.dtbo
 dtb-$(CONFIG_ARCH_MXC) += imx8dxl-evk-pcie-ep.dtb
+DTC_FLAGS_imx8dxl-hummingboard-telematics := -@
+dtb-$(CONFIG_ARCH_MXC) += imx8dxl-hummingboard-telematics.dtb
 
 dtb-$(CONFIG_ARCH_MXC) += imx8dxp-tqma8xdp-mba8xx.dtb
 dtb-$(CONFIG_ARCH_MXC) += imx8dxp-tqma8xdps-mb-smarc-2.dtb
diff --git a/arch/arm64/boot/dts/freescale/imx8dxl-hummingboard-telematics.dts b/arch/arm64/boot/dts/freescale/imx8dxl-hummingboard-telematics.dts
new file mode 100644
index 0000000000000..ad2371f3c2632
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/imx8dxl-hummingboard-telematics.dts
@@ -0,0 +1,536 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright 2022-2026 Josua Mayer <josua@solid-run.com>
+ */
+
+/dts-v1/;
+
+#include "imx8dxl-sr-som.dtsi"
+
+/ {
+	compatible = "solidrun,imx8dxl-hummingboard-telematics",
+		     "solidrun,imx8dxl-sr-som", "fsl,imx8dxl";
+	model = "SolidRun i.MX8DXL HummingBoard Telematics";
+
+	aliases {
+		/* override ethernat aliases from imx8dxl.dtsi */
+		ethernet0 = &eqos;
+		/delete-property/ ethernet1;
+		gpio8 = &tca6408_u2;
+		mmc2 = &usdhc3;
+		rtc0 = &carrier_rtc;
+		rtc1 = &rtc;
+		serial1 = &lpuart1;
+	};
+
+	v_1_1: regulator-1-1 {
+		compatible = "regulator-fixed";
+		regulator-name = "1v1";
+		pinctrl-0 = <&regulator_1v1_pins>;
+		pinctrl-names = "default";
+		regulator-always-on;
+		regulator-max-microvolt = <1100000>;
+		regulator-min-microvolt = <1100000>;
+		vin-supply = <&v_5_0>;
+		gpio = <&lsio_gpio4 5 GPIO_ACTIVE_HIGH>;
+		enable-active-high;
+	};
+
+	v_5_0: regulator-5-0 {
+		compatible = "regulator-fixed";
+		regulator-name = "5v0";
+		regulator-max-microvolt = <5000000>;
+		regulator-min-microvolt = <5000000>;
+	};
+
+	/* can transceiver builtin regulator (STBN1 pin) */
+	reg_flexcan1_stby: regulator-flexcan1-standby {
+		compatible = "regulator-fixed";
+		regulator-name = "flexcan1-standby";
+		regulator-max-microvolt = <3300000>;
+		regulator-min-microvolt = <3300000>;
+		gpio = <&tca6408_u2 2 GPIO_ACTIVE_HIGH>;
+		enable-active-high;
+	};
+
+	/* can transceiver builtin regulator (STBN2 pin) */
+	reg_flexcan2_stby: regulator-flexcan2-standby {
+		compatible = "regulator-fixed";
+		regulator-name = "flexcan2-standby";
+		regulator-max-microvolt = <3300000>;
+		regulator-min-microvolt = <3300000>;
+		gpio = <&tca6408_u2 3 GPIO_ACTIVE_HIGH>;
+		enable-active-high;
+	};
+
+	modem_vbat: regulator-modem-vbat {
+		compatible = "regulator-fixed";
+		regulator-name = "vbat";
+		pinctrl-0 = <&regulator_modem_vbat_pins>;
+		pinctrl-names = "default";
+		regulator-max-microvolt = <3600000>;
+		regulator-min-microvolt = <3600000>;
+		vin-supply = <&v_5_0>;
+		gpio = <&lsio_gpio0 14 GPIO_ACTIVE_HIGH>;
+		enable-active-high;
+	};
+
+	vbus1: regulator-vbus-1 {
+		compatible = "regulator-fixed";
+		regulator-name = "vbus1";
+		pinctrl-0 = <&regulator_usb1_vbus_pins>;
+		pinctrl-names = "default";
+		regulator-max-microvolt = <5000000>;
+		regulator-min-microvolt = <5000000>;
+		gpio = <&lsio_gpio0 16 GPIO_ACTIVE_HIGH>;
+		enable-active-high;
+	};
+
+	usdhc3_pwrseq: usdhc3-pwrseq {
+		compatible = "mmc-pwrseq-simple";
+		reset-gpios = <&lsio_gpio0 15 GPIO_ACTIVE_LOW>;
+	};
+};
+
+&dma_apbh {
+	status = "disabled";
+};
+
+&eqos {
+	phy-mode = "rgmii-id";
+	pinctrl-0 = <&eqos_pins>;
+	pinctrl-names = "default";
+	status = "okay";
+
+	fixed-link {
+		full-duplex;
+		speed = <1000>;
+	};
+};
+
+&flexcan1 {
+	pinctrl-0 = <&flexcan1_pins>;
+	pinctrl-names = "default";
+	xceiver-supply = <&reg_flexcan1_stby>;
+	status = "okay";
+
+	can-transceiver {
+		max-bitrate = <5000000>;
+	};
+};
+
+&flexcan2 {
+	pinctrl-0 = <&flexcan2_pins>;
+	pinctrl-names = "default";
+	xceiver-supply = <&reg_flexcan2_stby>;
+	status = "okay";
+
+	can-transceiver {
+		max-bitrate = <5000000>;
+	};
+};
+
+&i2c2 {
+	/* routed to J14: SDA(51), SCL(53) */
+
+	/* regulator@18 */
+
+	tca6408_u2: gpio@20 {
+		compatible = "ti,tca6408";
+		reg = <0x20>;
+		#interrupt-cells = <2>;
+		interrupt-controller;
+		#gpio-cells = <2>;
+		gpio-controller;
+		gpio-line-names = "DIG_IN1", "DIG_IN2", "CAN_STNB1", "CAN_STNB2",
+				  "DIG_OUT1", "DIG_OUT2", "", "";
+		interrupts-extended = <&lsio_gpio0 20 IRQ_TYPE_EDGE_FALLING>;
+		pinctrl-0 = <&tca6408_u2_int_pins>;
+		pinctrl-names = "default";
+	};
+
+	carrier_rtc: rtc@32 {
+		compatible = "epson,rx8111";
+		reg = <0x32>;
+	};
+};
+
+&iomuxc {
+	bluetooth_pins: pinctrl-bluetooth-grp {
+		fsl,pins = <
+			/* BT_REG_ON: io without pull (module integrates pd) */
+			IMX8DXL_SPI3_SCK_LSIO_GPIO0_IO13			0x0000061
+		>;
+	};
+
+	eqos_pins: pinctrl-eqos-grp {
+		fsl,pins = <
+			/* MDIO to Switch */
+			/* enet0 mdio pads supplied with 3.3v */
+			/* IMX8DXL_COMP_CTL_GPIO_1V8_3V3_GPIOCT */
+			IMX8DXL_ENET0_MDC_CONN_EQOS_MDC				0x06000020
+			IMX8DXL_ENET0_MDIO_CONN_EQOS_MDIO			0x06000020
+			/* RGMII to Switch */
+			IMX8DXL_ENET1_RGMII_TX_CTL_CONN_EQOS_RGMII_TX_CTL	0x06000020
+			IMX8DXL_ENET1_RGMII_TXC_CONN_EQOS_RGMII_TXC		0x06000020
+			IMX8DXL_ENET1_RGMII_TXD0_CONN_EQOS_RGMII_TXD0		0x06000020
+			IMX8DXL_ENET1_RGMII_TXD1_CONN_EQOS_RGMII_TXD1		0x06000020
+			IMX8DXL_ENET1_RGMII_TXD2_CONN_EQOS_RGMII_TXD2		0x06000020
+			IMX8DXL_ENET1_RGMII_TXD3_CONN_EQOS_RGMII_TXD3		0x06000020
+			IMX8DXL_ENET1_RGMII_RXC_CONN_EQOS_RGMII_RXC		0x06000020
+			IMX8DXL_ENET1_RGMII_RX_CTL_CONN_EQOS_RGMII_RX_CTL	0x06000020
+			IMX8DXL_ENET1_RGMII_RXD0_CONN_EQOS_RGMII_RXD0		0x06000020
+			IMX8DXL_ENET1_RGMII_RXD1_CONN_EQOS_RGMII_RXD1		0x06000020
+			IMX8DXL_ENET1_RGMII_RXD2_CONN_EQOS_RGMII_RXD2		0x06000020
+			IMX8DXL_ENET1_RGMII_RXD3_CONN_EQOS_RGMII_RXD3		0x06000020
+		>;
+	};
+
+	flexcan1_pins: pinctrl-flexcan1-grp {
+		fsl,pins = <
+			IMX8DXL_FLEXCAN0_TX_ADMA_FLEXCAN0_TX			0x00000021
+			IMX8DXL_FLEXCAN0_RX_ADMA_FLEXCAN0_RX			0x00000021
+		>;
+	};
+
+	flexcan2_pins: pinctrl-flexcan2-grp {
+		fsl,pins = <
+			IMX8DXL_FLEXCAN1_TX_ADMA_FLEXCAN1_TX			0x00000021
+			IMX8DXL_FLEXCAN1_RX_ADMA_FLEXCAN1_RX			0x00000021
+		>;
+	};
+
+	lpspi0_pins: pinctrl-lpspi0-grp {
+		fsl,pins = <
+			IMX8DXL_SPI0_SCK_ADMA_SPI0_SCK				0x600004c
+			IMX8DXL_SPI0_SDO_ADMA_SPI0_SDO				0x600004c
+			IMX8DXL_SPI0_SDI_ADMA_SPI0_SDI				0x600004c
+			IMX8DXL_SPI0_CS0_LSIO_GPIO1_IO08			0x0000021
+			IMX8DXL_SPI0_CS1_LSIO_GPIO1_IO07			0x0000021
+		>;
+	};
+
+	lpuart1_pins: pinctrl-lpuart1-grp {
+		fsl,pins = <
+			IMX8DXL_UART1_RX_ADMA_UART1_RX				0x06000020
+			IMX8DXL_UART1_TX_ADMA_UART1_TX				0x06000020
+			IMX8DXL_UART1_CTS_B_ADMA_UART1_CTS_B			0x06000020
+			IMX8DXL_UART1_RTS_B_ADMA_UART1_RTS_B			0x06000020
+		>;
+	};
+
+	modem_pins: pinctrl-lte-grp {
+		fsl,pins = <
+			/* modem RESET_N: io open drain drive 2mA */
+			IMX8DXL_ADC_IN3_LSIO_GPIO1_IO11	0x2000061
+
+			/* modem PWRKEY: io open drain with pull-up, drive 2mA */
+			IMX8DXL_ADC_IN2_LSIO_GPIO1_IO12	0x2000021
+		>;
+	};
+
+	regulator_1v1_pins: pinctrl-regulator-1-1-grp {
+		fsl,pins = <
+			/* SW_PE: io without pull-up */
+			IMX8DXL_USB_SS3_TC2_LSIO_GPIO4_IO05			0x0000061
+		>;
+	};
+
+	regulator_modem_vbat_pins: pinctrl-regulator-modem-vbat-grp {
+		fsl,pins = <
+			/*
+			 * RF_PWR: io without pull-up,
+			 * has either external pull-up (R1117) or pull-down (R1118).
+			 * With pull-up Modem will boot at system power-up,
+			 * with pull-down modem will enter power-down mode once
+			 * vbat is enabled -> toggle pwrkey to boot modem.
+			 * Hence pull-up (R1117) is preferred.
+			 */
+			IMX8DXL_SPI3_SDO_LSIO_GPIO0_IO14			0x0000061
+		>;
+	};
+
+	regulator_usb1_vbus_pins: pinctrl-regulator-usb1-vbus-grp {
+		fsl,pins = <
+			/* regulator enable: open-drain with pull-up & low drive strength */
+			IMX8DXL_SPI3_CS0_LSIO_GPIO0_IO16			0x2000021
+		>;
+	};
+
+	switch_pins: pinctrl-switch-grp {
+		fsl,pins = <
+			/* SW_RSTn: io without pull-up */
+			IMX8DXL_USB_SS3_TC0_LSIO_GPIO4_IO03			0x0000021
+
+			/* SW_CORE_RSTn: io without pull-up */
+			IMX8DXL_USB_SS3_TC1_LSIO_GPIO4_IO04			0x0000021
+
+			/* INT_N: io without pull-up */
+			IMX8DXL_USB_SS3_TC3_LSIO_GPIO4_IO06			0x0000021
+		>;
+	};
+
+	tca6408_u2_int_pins: pinctrl-tca6408-u2-int-grp {
+		fsl,pins = <
+			/* gpio-expander interrupt: io with pull-up */
+			IMX8DXL_MCLK_OUT0_LSIO_GPIO0_IO20			0x0000021
+		>;
+	};
+
+	usdhc3_pins: pinctrl-usdhc3-grp {
+		fsl,pins = <
+			IMX8DXL_ENET0_RGMII_TXC_CONN_USDHC2_CLK			0x06000040
+			IMX8DXL_ENET0_RGMII_TX_CTL_CONN_USDHC2_CMD		0x00000021
+			IMX8DXL_ENET0_RGMII_TXD0_CONN_USDHC2_DATA0		0x00000021
+			IMX8DXL_ENET0_RGMII_TXD1_CONN_USDHC2_DATA1		0x00000021
+			IMX8DXL_ENET0_RGMII_TXD2_CONN_USDHC2_DATA2		0x00000021
+			IMX8DXL_ENET0_RGMII_TXD3_CONN_USDHC2_DATA3		0x00000021
+		>;
+	};
+
+	wifi_pins: pinctrl-wifi-grp {
+		fsl,pins = <
+			/* WL_REG_ON: io without pull (module integrates pd) */
+			IMX8DXL_SPI3_SDI_LSIO_GPIO0_IO15			0x0000061
+		>;
+	};
+};
+
+&lpspi0 {
+	cs-gpios = <&lsio_gpio1 8 GPIO_ACTIVE_LOW>, <&lsio_gpio1 7 GPIO_ACTIVE_LOW>;
+	pinctrl-0 = <&lpspi0_pins>, <&switch_pins>;
+	pinctrl-names = "default";
+	status = "okay";
+
+	ethernet-switch@0 {
+		compatible = "nxp,sja1110a";
+		reg = <0>;
+		reset-gpios = <&lsio_gpio4 3 GPIO_ACTIVE_LOW>;
+		spi-cpol;
+		spi-max-frequency = <4000000>;
+
+		ethernet-ports {
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			/* to 100Base-TX on connector J26 */
+			port@1 {
+				reg = <0x1>;
+				label = "lan1";
+				phy-handle = <&switch_port1_base_tx_phy>;
+				phy-mode = "internal";
+				status = "okay";
+			};
+
+			/* to CPU */
+			port@2 {
+				reg = <0x2>;
+				ethernet = <&eqos>;
+				label = "cpu";
+				phy-mode = "rgmii-id";
+				rx-internal-delay-ps = <2000>;
+				tx-internal-delay-ps = <2000>;
+				status = "okay";
+
+				fixed-link {
+					full-duplex;
+					speed = <1000>;
+				};
+			};
+
+			/* sgmii on addon board connector J21 */
+			port@3 {
+				reg = <0x3>;
+				label = "lan3";
+				status = "disabled";
+			};
+
+			/* sgmii on addon board connector J21 */
+			port@4 {
+				reg = <0x4>;
+				label = "lan4";
+				status = "disabled";
+			};
+
+			/* 100base-t1 on addon board connector J21 */
+			port@5 {
+				reg = <0x5>;
+				label = "trx1";
+				phy-handle = <&switch_port5_base_t1_phy>;
+				phy-mode = "internal";
+				status = "disabled";
+			};
+
+			/* 100base-t1 on addon board connector J21 */
+			port@6 {
+				reg = <0x6>;
+				label = "trx2";
+				phy-handle = <&switch_port6_base_t1_phy>;
+				phy-mode = "internal";
+				status = "disabled";
+			};
+
+			/* 100base-t1 on addon board connector J21 */
+			port@7 {
+				reg = <0x7>;
+				label = "trx3";
+				phy-handle = <&switch_port7_base_t1_phy>;
+				phy-mode = "internal";
+				status = "disabled";
+			};
+
+			/* 100base-t1 on addon board connector J21 */
+			port@8 {
+				reg = <0x8>;
+				label = "trx4";
+				phy-handle = <&switch_port8_base_t1_phy>;
+				phy-mode = "internal";
+				status = "disabled";
+			};
+
+			/* 100base-t1 on addon board connector J21 */
+			port@9 {
+				reg = <0x9>;
+				label = "trx5";
+				phy-handle = <&switch_port9_base_t1_phy>;
+				phy-mode = "internal";
+				status = "disabled";
+			};
+
+			/* 100Base-T1 on connector J26 */
+			port@a {
+				reg = <0xa>;
+				label = "trx6";
+				phy-handle = <&switch_port10_base_t1_phy>;
+				phy-mode = "internal";
+				status = "okay";
+			};
+		};
+
+		mdios {
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			mdio@0 {
+				compatible = "nxp,sja1110-base-t1-mdio";
+				reg = <0>;
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				/* 100base-t1 on addon board connector J21 */
+				switch_port5_base_t1_phy: ethernet-phy@1 {
+					compatible = "ethernet-phy-ieee802.3-c45";
+					reg = <0x1>;
+					status = "disabled";
+				};
+
+				/* 100base-t1 on addon board connector J21 */
+				switch_port6_base_t1_phy: ethernet-phy@2 {
+					compatible = "ethernet-phy-ieee802.3-c45";
+					reg = <0x2>;
+					status = "disabled";
+				};
+
+				/* 100base-t1 on addon board connector J21 */
+				switch_port7_base_t1_phy: ethernet-phy@3 {
+					compatible = "ethernet-phy-ieee802.3-c45";
+					reg = <0x3>;
+					status = "disabled";
+				};
+
+				/* 100base-t1 on addon board connector J21 */
+				switch_port8_base_t1_phy: ethernet-phy@4 {
+					compatible = "ethernet-phy-ieee802.3-c45";
+					reg = <0x4>;
+					status = "disabled";
+				};
+
+				/* 100base-t1 on addon board connector J21 */
+				switch_port9_base_t1_phy: ethernet-phy@5 {
+					compatible = "ethernet-phy-ieee802.3-c45";
+					reg = <0x5>;
+					status = "disabled";
+				};
+
+				/* 100Base-T1 on connector J26 */
+				switch_port10_base_t1_phy: ethernet-phy@6 {
+					compatible = "ethernet-phy-ieee802.3-c45";
+					reg = <0x6>;
+				};
+			};
+
+			mdio@1 {
+				compatible = "nxp,sja1110-base-tx-mdio";
+				reg = <1>;
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				/* to 100Base-TX on connector J26 */
+				switch_port1_base_tx_phy: ethernet-phy@1 {
+					reg = <0x1>;
+				};
+			};
+		};
+	};
+};
+
+/* bluetooth */
+&lpuart1 {
+	pinctrl-0 = <&lpuart1_pins>, <&bluetooth_pins>;
+	pinctrl-names = "default";
+	uart-has-rtscts;
+	status = "okay";
+
+	bluetooth {
+		compatible = "brcm,bcm4345c5";
+		/* Murata 1MW module supports max. 3M baud */
+		max-speed = <3000000>;
+		shutdown-gpios = <&lsio_gpio0 13 GPIO_ACTIVE_HIGH>;
+	};
+};
+
+&usbotg1 {
+	vbus-supply = <&vbus1>;
+};
+
+/* cellular modem */
+&usbotg2 {
+	#address-cells = <1>;
+	#size-cells = <0>;
+	adp-disable;
+	disable-over-current;
+	dr_mode = "host";
+	hnp-disable;
+	pinctrl-0 = <&modem_pins>;
+	pinctrl-names = "default";
+	power-active-high;
+	srp-disable;
+	vbus-supply = <&v_5_0>;
+	status = "okay";
+
+	usb-device@1 {
+		compatible = "usb2c7c,125";
+		reg = <1>;
+		reset-duration-us = <150000>;
+		reset-gpios = <&lsio_gpio1 11 GPIO_ACTIVE_LOW>;
+		vbus-supply = <&v_3_3>;
+		vdd-supply = <&modem_vbat>;
+	};
+};
+
+&usbphy2 {
+	status = "okay";
+};
+
+/* WiFi */
+&usdhc3 {
+	bus-width = <4>;
+	mmc-pwrseq = <&usdhc3_pwrseq>;
+	non-removable;
+	no-sd;
+	pinctrl-0 = <&usdhc3_pins>, <&wifi_pins>;
+	pinctrl-names = "default";
+	vmmc-supply = <&v_3_3>;
+	vqmmc-supply = <&v_1_8>;
+	status = "okay";
+};
diff --git a/arch/arm64/boot/dts/freescale/imx8dxl-sr-som.dtsi b/arch/arm64/boot/dts/freescale/imx8dxl-sr-som.dtsi
new file mode 100644
index 0000000000000..d72e960c3e5e3
--- /dev/null
+++ b/arch/arm64/boot/dts/freescale/imx8dxl-sr-som.dtsi
@@ -0,0 +1,460 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright 2022-2026 Josua Mayer <josua@solid-run.com>
+ */
+
+#include "imx8dxl.dtsi"
+/ {
+	compatible = "solidrun,imx8dxl-sr-som", "fsl,imx8dxl";
+	model = "SolidRun i.MX8DXL SoM";
+
+	aliases {
+		i2c2 = &i2c2;
+		i2c3 = &i2c3;
+		mmc0 = &usdhc1;
+		mmc1 = &usdhc2;
+		serial0 = &lpuart0;
+		serial2 = &lpuart2;
+	};
+
+	chosen {
+		stdout-path = "serial0:115200n8";
+	};
+
+	imx8dxl-cm4 {
+		compatible = "fsl,imx8qxp-cm4";
+		clocks = <&clk_dummy>;
+		mboxes = <&lsio_mu5 0 1 &lsio_mu5 1 1 &lsio_mu5 3 1>;
+		mbox-names = "tx", "rx", "rxdb";
+		memory-region = <&vdevbuffer>, <&vdev0vring0>, <&vdev0vring1>,
+				<&vdev1vring0>, <&vdev1vring1>, <&rsc_table>;
+		power-domains = <&pd IMX_SC_R_M4_0_PID0>, <&pd IMX_SC_R_M4_0_MU_1A>;
+		fsl,entry-address = <0x34fe0000>;
+		fsl,resource-id = <IMX_SC_R_M4_0_PID0>;
+	};
+
+	pps {
+		compatible = "pps-gpio";
+		gpios = <&lsio_gpio2 6 GPIO_ACTIVE_HIGH>;
+		pinctrl-0 = <&gnss_pps_pins>;
+		pinctrl-names = "default";
+	};
+
+	v_1_2: regulator-1-2 {
+		compatible = "regulator-fixed";
+		regulator-name = "1v2";
+		pinctrl-0 = <&regulator_1_2_pins>;
+		pinctrl-names = "default";
+		regulator-always-on;
+		regulator-max-microvolt = <1200000>;
+		regulator-min-microvolt = <1200000>;
+		gpio = <&lsio_gpio1 13 GPIO_ACTIVE_HIGH>;
+		enable-active-high;
+	};
+
+	v_1_6: regulator-1-6 {
+		compatible = "regulator-fixed";
+		regulator-name = "1v6";
+		pinctrl-0 = <&regulator_1_6_pins>;
+		pinctrl-names = "default";
+		regulator-always-on;
+		regulator-max-microvolt = <1600000>;
+		regulator-min-microvolt = <1600000>;
+		vin-supply = <&v_1_8>;
+		gpio = <&lsio_gpio1 14 GPIO_ACTIVE_HIGH>;
+		enable-active-high;
+	};
+
+	v_1_8: regulator-1-8 {
+		compatible = "regulator-fixed";
+		regulator-name = "1v8";
+		regulator-max-microvolt = <1800000>;
+		regulator-min-microvolt = <1800000>;
+	};
+
+	v_1_8_se: regulator-1-8-secure-element {
+		compatible = "regulator-fixed";
+		regulator-name = "1v8-se";
+		pinctrl-0 = <&regulator_1_8_se_pins>;
+		pinctrl-names = "default";
+		regulator-max-microvolt = <1800000>;
+		regulator-min-microvolt = <1800000>;
+		vin-supply = <&v_1_8>;
+		gpio = <&lsio_gpio3 18 GPIO_ACTIVE_HIGH>;
+		enable-active-high;
+	};
+
+	v_3_3: regulator-3-3 {
+		compatible = "regulator-fixed";
+		regulator-name = "3v3";
+		regulator-max-microvolt = <3300000>;
+		regulator-min-microvolt = <3300000>;
+	};
+
+	reserved-memory {
+		ranges;
+		#address-cells = <2>;
+		#size-cells = <2>;
+
+		/* global autoconfigured region for contiguous allocations */
+		linux,cma {
+			compatible = "shared-dma-pool";
+			alloc-ranges = <0 0x98000000 0 0x14000000>;
+			reusable;
+			size = <0 0x14000000>;
+			linux,cma-default;
+		};
+
+		vdev0vring0: memory0@90000000 {
+			reg = <0 0x90000000 0 0x8000>;
+			no-map;
+		};
+
+		vdev0vring1: memory@90008000 {
+			reg = <0 0x90008000 0 0x8000>;
+			no-map;
+		};
+
+		vdev1vring0: memory@90010000 {
+			reg = <0 0x90010000 0 0x8000>;
+			no-map;
+		};
+
+		vdev1vring1: memory@90018000 {
+			reg = <0 0x90018000 0 0x8000>;
+			no-map;
+		};
+
+		rsc_table: memory-rsc-table@900ff000 {
+			reg = <0 0x900ff000 0 0x1000>;
+			no-map;
+		};
+
+		vdevbuffer: memory-vdevbuffer@90400000 {
+			compatible = "shared-dma-pool";
+			reg = <0 0x90400000 0 0x100000>;
+			no-map;
+		};
+
+		/*
+		 * Memory reserved for optee usage. Please do not use.
+		 * This will be automatically added to dtb if OP-TEE is installed.
+		 * optee@96000000 {
+		 *     reg = <0 0x96000000 0 0x2000000>;
+		 *     no-map;
+		 * };
+		 */
+	};
+
+	memory@80000000 {
+		reg = <0x00000000 0x80000000 0 0x40000000>;
+		device_type = "memory";
+	};
+};
+
+&i2c2 {
+	#address-cells = <1>;
+	#size-cells = <0>;
+	clock-frequency = <100000>;
+	pinctrl-0 = <&i2c2_pins>;
+	pinctrl-1 = <&i2c2_gpio_pins>;
+	pinctrl-names = "default", "gpio";
+	scl-gpios = <&lsio_gpio3 1 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
+	sda-gpios = <&lsio_gpio3 0 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
+	status = "okay";
+};
+
+&i2c3 {
+	#address-cells = <1>;
+	#size-cells = <0>;
+	clock-frequency = <100000>;
+	pinctrl-0 = <&i2c3_pins>;
+	pinctrl-1 = <&i2c3_gpio_pins>;
+	pinctrl-names = "default", "gpio";
+	scl-gpios = <&lsio_gpio3 2 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
+	sda-gpios = <&lsio_gpio3 3 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
+	status = "okay";
+
+	magnetometer@1e {
+		compatible = "st,iis2mdc";
+		reg = <0x1e>;
+		interrupt-parent = <&lsio_gpio2>;
+		interrupts = <10 IRQ_TYPE_EDGE_RISING>;
+		pinctrl-0 = <&magnetometer_pins>;
+		pinctrl-names = "default";
+		st,drdy-int-pin = <1>;
+	};
+
+	/* pressure-sensor@5c */
+
+	inertial-sensor@6b {
+		compatible = "st,ism330dhcx";
+		reg = <0x6b>;
+		interrupt-parent = <&lsio_gpio2>;
+		interrupts = <11 IRQ_TYPE_EDGE_RISING>;
+		pinctrl-0 = <&imu_pins>;
+		pinctrl-names = "default";
+		st,drdy-int-pin = <1>;
+	};
+};
+
+&iomuxc {
+	pinctrl-0 = <&pinctrl_hog>;
+	pinctrl-names = "default";
+
+	pinctrl_hog: hoggrp {
+		fsl,pins = <
+			IMX8DXL_COMP_CTL_GPIO_1V8_3V3_GPIORHB_PAD	0x000514a0
+			IMX8DXL_COMP_CTL_GPIO_1V8_3V3_GPIORHK_PAD	0x000014a0
+		>;
+	};
+
+	dsrc_pins: pinctrl-dsrc-grp {
+		fsl,pins = <
+			/* reset: io without pull */
+			IMX8DXL_ADC_IN0_LSIO_GPIO1_IO10			0x0000060
+
+			/*
+			 * boot0: io without pull
+			 * After reset, this pin selects radio boot media:
+			 * - 0: flash spi
+			 * - 1: slave sdio
+			 * Once the firmware boots however, the radio controls
+			 * this pin for flow-control to signal readiness.
+			 */
+			IMX8DXL_ADC_IN1_LSIO_GPIO1_IO09			0x0000060
+		>;
+	};
+
+	gnss_pins: pinctrl-gnss-grp {
+		fsl,pins = <
+			/* gps reset: input with pull-up */
+			IMX8DXL_SNVS_TAMPER_OUT4_LSIO_GPIO2_IO08_IN	0x0000021
+			/* gps interrupt: io without pull-up */
+			IMX8DXL_SNVS_TAMPER_IN0_LSIO_GPIO2_IO09_IN	0x0000061
+		>;
+	};
+
+	gnss_pps_pins: pinctrl-gnss-pps-grp {
+		fsl,pins = <
+			/* gps timepulse: input without pull-up */
+			IMX8DXL_SNVS_TAMPER_OUT2_LSIO_GPIO2_IO06_IN	0x0000061
+		>;
+	};
+
+	i2c2_gpio_pins: pinctrl-i2c2-gpio-grp {
+		fsl,pins = <
+			/* io with pull-up and weak drive */
+			IMX8DXL_SPI1_SCK_LSIO_GPIO3_IO00		0x00000021
+			/* io with pull-up, weak drive, open-drain */
+			IMX8DXL_SPI1_SDO_LSIO_GPIO3_IO01		0x02000021
+		>;
+	};
+
+	i2c2_pins: pinctrl-i2c2-grp {
+		fsl,pins = <
+			/* io with pull-up and weak drive */
+			IMX8DXL_SPI1_SCK_ADMA_I2C2_SDA			0x06000021
+			IMX8DXL_SPI1_SDO_ADMA_I2C2_SCL			0x06000021
+		>;
+	};
+
+	i2c3_gpio_pins: pinctrl-i2c3-gpio-grp {
+		fsl,pins = <
+			/* io with pull-up and weak drive */
+			IMX8DXL_SPI1_CS0_LSIO_GPIO3_IO03		0x00000021
+			/* io with pull-up, weak drive, open-drain */
+			IMX8DXL_SPI1_SDI_LSIO_GPIO3_IO02		0x02000021
+		>;
+	};
+
+	i2c3_pins: pinctrl-i2c3-grp {
+		fsl,pins = <
+			/* io with pull-up and weak drive */
+			IMX8DXL_SPI1_CS0_ADMA_I2C3_SDA			0x06000021
+			IMX8DXL_SPI1_SDI_ADMA_I2C3_SCL			0x06000021
+		>;
+	};
+
+	imu_pins: pinctrl-imu-grp {
+		fsl,pins = <
+			/* interrupt: io with pull-down */
+			IMX8DXL_SNVS_TAMPER_IN2_LSIO_GPIO2_IO11_IN	0x0000041
+		>;
+	};
+
+	lpspi2_pins: pinctrl-lpspi2-grp {
+		fsl,pins = <
+			IMX8DXL_USDHC1_RESET_B_ADMA_SPI2_SCK		0x600004c
+			IMX8DXL_USDHC1_VSELECT_ADMA_SPI2_SDO		0x600004c
+			IMX8DXL_USDHC1_WP_ADMA_SPI2_SDI			0x600004c
+			IMX8DXL_USDHC1_CD_B_LSIO_GPIO4_IO22		0x6000021
+		>;
+	};
+
+	lpuart0_pins: pinctrl-lpuart0-grp {
+		fsl,pins = <
+			IMX8DXL_UART0_RX_ADMA_UART0_RX			0x06000020
+			IMX8DXL_UART0_TX_ADMA_UART0_TX			0x06000020
+		>;
+	};
+
+	lpuart2_pins: pinctrl-lpuart2-grp {
+		fsl,pins = <
+			IMX8DXL_UART2_TX_ADMA_UART2_TX			0x06000020
+			IMX8DXL_UART2_RX_ADMA_UART2_RX			0x06000020
+		>;
+	};
+
+	magnetometer_pins: pinctrl-magnetometer-grp {
+		fsl,pins = <
+			/* interrupt: io with pull-down */
+			IMX8DXL_SNVS_TAMPER_IN1_LSIO_GPIO2_IO10_IN	0x0000041
+		>;
+	};
+
+	regulator_1_2_pins: pinctrl-regulator-1-2-grp {
+		fsl,pins = <
+			/* io without pull-up */
+			/* has etxernal pull-down */
+			IMX8DXL_ADC_IN5_LSIO_GPIO1_IO13			0x0000061
+		>;
+	};
+
+	regulator_1_6_pins: pinctrl-regulator-1-6-grp {
+		fsl,pins = <
+			/* io without pull-up */
+			/* has etxernal pull-down */
+			IMX8DXL_ADC_IN4_LSIO_GPIO1_IO14			0x0000061
+		>;
+	};
+
+	regulator_1_8_se_pins: pinctrl-regulator-1-8-secure-element-grp {
+		fsl,pins = <
+			/* v2x-secure-element power switch: io with pull-down */
+			IMX8DXL_QSPI0B_DATA0_LSIO_GPIO3_IO18		0x0000041
+		>;
+	};
+
+	se_pins: pinctrl-secure-element-grp {
+		fsl,pins = <
+			/* v2x-secure-element reset: io with pull-up */
+			IMX8DXL_QSPI0B_DATA1_LSIO_GPIO3_IO19		0x0000021
+
+			/*
+			 * v2x-secure-element gpio0: io with pull-up
+			 * pulled low by sxf after boot indicating ready for commands
+			 */
+			IMX8DXL_QSPI0B_DATA2_LSIO_GPIO3_IO20		0x0000021
+
+			/* v2x-secure-element gpio1: io with pull-up */
+			IMX8DXL_QSPI0B_DATA3_LSIO_GPIO3_IO21		0x0000021
+		>;
+	};
+
+	usdhc1_pins: pinctrl-usdhc1-grp {
+		fsl,pins = <
+			IMX8DXL_EMMC0_CLK_CONN_EMMC0_CLK		0x06000041
+			IMX8DXL_EMMC0_CMD_CONN_EMMC0_CMD		0x00000021
+			IMX8DXL_EMMC0_DATA0_CONN_EMMC0_DATA0		0x00000021
+			IMX8DXL_EMMC0_DATA1_CONN_EMMC0_DATA1		0x00000021
+			IMX8DXL_EMMC0_DATA2_CONN_EMMC0_DATA2		0x00000021
+			IMX8DXL_EMMC0_DATA3_CONN_EMMC0_DATA3		0x00000021
+			IMX8DXL_EMMC0_DATA4_CONN_EMMC0_DATA4		0x00000021
+			IMX8DXL_EMMC0_DATA5_CONN_EMMC0_DATA5		0x00000021
+			IMX8DXL_EMMC0_DATA6_CONN_EMMC0_DATA6		0x00000021
+			IMX8DXL_EMMC0_DATA7_CONN_EMMC0_DATA7		0x00000021
+			IMX8DXL_EMMC0_STROBE_CONN_EMMC0_STROBE		0x00000041
+			IMX8DXL_EMMC0_RESET_B_CONN_EMMC0_RESET_B	0x00000061
+		>;
+	};
+
+	usdhc2_pins: pinctrl-usdhc2-grp {
+		fsl,pins = <
+			IMX8DXL_ENET0_RGMII_RXC_CONN_USDHC1_CLK		0x06000040
+			IMX8DXL_ENET0_RGMII_RX_CTL_CONN_USDHC1_CMD	0x00000021
+			IMX8DXL_ENET0_RGMII_RXD0_CONN_USDHC1_DATA0	0x00000021
+			IMX8DXL_ENET0_RGMII_RXD1_CONN_USDHC1_DATA1	0x00000021
+			IMX8DXL_ENET0_RGMII_RXD2_CONN_USDHC1_DATA2	0x00000021
+			IMX8DXL_ENET0_RGMII_RXD3_CONN_USDHC1_DATA3	0x00000021
+		>;
+	};
+};
+
+&lpspi2 {
+	cs-gpios = <&lsio_gpio4 22 GPIO_ACTIVE_LOW>;
+	num-cs = <1>;
+	pinctrl-0 = <&lpspi2_pins>, <&se_pins>;
+	pinctrl-names = "default";
+	status = "okay";
+};
+
+/* console */
+&lpuart0 {
+	pinctrl-0 = <&lpuart0_pins>;
+	pinctrl-names = "default";
+	status = "okay";
+};
+
+/* gnss */
+&lpuart2 {
+	pinctrl-0 = <&lpuart2_pins>, <&gnss_pins>;
+	pinctrl-names = "default";
+	status = "okay";
+};
+
+&lsio_gpio3 {
+	gpio-line-names = "", "", "", "", "", "", "", "",
+			  "", "", "", "", "", "", "", "",
+			  "", "", "", "SXF_RST", "SXF_GPIO0", "SXF_GPIO1", "", "",
+			  "", "", "", "", "", "", "", "";
+};
+
+&lsio_mu5 {
+	status = "okay";
+};
+
+/* OTG port for boot */
+&usbotg1 {
+	adp-disable;
+	disable-over-current;
+	dr_mode = "peripheral";
+	hnp-disable;
+	power-active-high;
+	srp-disable;
+	status = "okay";
+};
+
+&usbphy1 {
+	status = "okay";
+};
+
+/* eMMC */
+&usdhc1 {
+	bus-width = <8>;
+	cap-mmc-hw-reset;
+	non-removable;
+	no-sd;
+	no-sdio;
+	pinctrl-0 = <&usdhc1_pins>;
+	pinctrl-1 = <&usdhc1_pins>;
+	pinctrl-2 = <&usdhc1_pins>;
+	pinctrl-names = "default", "state_100mhz", "state_200mhz";
+	vmmc-supply = <&v_3_3>;
+	vqmmc-supply = <&v_1_8>;
+	status = "okay";
+};
+
+/* DSRC Radio */
+&usdhc2 {
+	bus-width = <4>;
+	keep-power-in-suspend;
+	max-frequency = <40000000>;
+	non-removable;
+	no-sd;
+	pinctrl-0 = <&usdhc2_pins>, <&dsrc_pins>;
+	pinctrl-names = "default";
+	vmmc-supply = <&v_3_3>;
+	vqmmc-supply = <&v_1_8>;
+	status = "okay";
+};
diff --git a/arch/arm64/boot/dts/freescale/imx8mp-sr-som.dtsi b/arch/arm64/boot/dts/freescale/imx8mp-sr-som.dtsi
index 3cdb0bc0ab721..16d4280a1ae65 100644
--- a/arch/arm64/boot/dts/freescale/imx8mp-sr-som.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx8mp-sr-som.dtsi
@@ -10,7 +10,6 @@ / {
 	compatible = "solidrun,imx8mp-sr-som", "fsl,imx8mp";
 
 	chosen {
-		bootargs = "earlycon=ec_imx6q,0x30890000,115200";
 		stdout-path = &uart2;
 	};
 

-- 
2.51.0



^ permalink raw reply related

* Re: [PATCH 2/2] arm64: dts: imx8dxl: Add SolidRun SoM and HummingBoard
From: Josua Mayer @ 2026-04-08 18:45 UTC (permalink / raw)
  To: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Shawn Guo,
	Frank Li, Sascha Hauer, Pengutronix Kernel Team, Fabio Estevam
  Cc: Yazan Shhady, Mikhail Anikin, Alexander Dahl,
	devicetree@vger.kernel.org, linux-kernel@vger.kernel.org,
	imx@lists.linux.dev, linux-arm-kernel@lists.infradead.org
In-Reply-To: <20260408-imx8dxl-sr-som-v1-2-ce5a39acd713@solid-run.com>

Am 08.04.26 um 20:38 schrieb Josua Mayer:
> Add support for the SolidRun i.MX8DXL System-on-Module (revision 2.1)
> and its corresponding evaluation carrier board, the HummingBoard
> Telematics (revision 2.0).
cut
> diff --git a/arch/arm64/boot/dts/freescale/imx8mp-sr-som.dtsi b/arch/arm64/boot/dts/freescale/imx8mp-sr-som.dtsi
> index 3cdb0bc0ab721..16d4280a1ae65 100644
> --- a/arch/arm64/boot/dts/freescale/imx8mp-sr-som.dtsi
> +++ b/arch/arm64/boot/dts/freescale/imx8mp-sr-som.dtsi
> @@ -10,7 +10,6 @@ / {
>  	compatible = "solidrun,imx8mp-sr-som", "fsl,imx8mp";
>  
>  	chosen {
> -		bootargs = "earlycon=ec_imx6q,0x30890000,115200";
>  		stdout-path = &uart2;
>  	};
I will drop this unintentional change for next revision ... ... but I' ll wait a while for comments.

^ permalink raw reply

* [PATCH v3 0/3] ARM: dts: aspeed-g6: add AST2600 I3C nodes and bindings
From: Dawid Glazik @ 2026-04-08 20:34 UTC (permalink / raw)
  To: Alexandre Belloni, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	Joel Stanley, Andrew Jeffery, linux-aspeed
  Cc: linux-i3c, devicetree, linux-arm-kernel, Frank Li, Dawid Glazik,
	Maciej Lawniczak

This series reworks and resubmits AST2600 I3C DTS updates that were
originally posted in 2024, but stalled without further upstream
progress.[1] The series was rebased onto the current tree and merge
conflicts were resolved.

The patches first move i2c nodes under the APB simple-bus for layout
consistency, then add AST2600 I3C controller nodes in aspeed-g6.dtsi
and finally add the missing dt-binding for AST2600 I3C global
registers. Jeremy agreed in a separate email thread that I can continue
this series under my authorship.

Link: https://lore.kernel.org/all/9d8c03d742fa9767f30e23d75ddf0baf4296c88e.1714647917.git.jk@codeconstruct.com.au/

Dawid Glazik (3):
  ARM: dts: aspeed-g6: move i2c controllers directly into apb node
  ARM: dts: aspeed-g6: Add nodes for i3c controllers
  dt-bindings: i3c: Add AST2600 I3C global registers

 .../i3c/aspeed,ast2600-i3c-global.yaml        |  55 ++
 arch/arm/boot/dts/aspeed/aspeed-g6.dtsi       | 549 ++++++++++--------
 2 files changed, 377 insertions(+), 227 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/i3c/aspeed,ast2600-i3c-global.yaml


base-commit: 6de23f81a5e08be8fbf5e8d7e9febc72a5b5f27f
-- 
2.43.0



^ permalink raw reply

* [PATCH v3 1/3] ARM: dts: aspeed-g6: move i2c controllers directly into apb node
From: Dawid Glazik @ 2026-04-08 20:34 UTC (permalink / raw)
  To: Alexandre Belloni, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	Joel Stanley, Andrew Jeffery, linux-aspeed
  Cc: linux-i3c, devicetree, linux-arm-kernel, Frank Li, Dawid Glazik,
	Maciej Lawniczak, Jeremy Kerr
In-Reply-To: <cover.1775679285.git.dawid.glazik@linux.intel.com>

We currently have the apb's mapping of the i2c controller space as a
labelled mostly-empty node:

  apb {
    i2c: bus@1e78a000 {
      ranges = <...>;
    };
  }

... and then define the contents of the i2c block later:

  i2c: {
    i2c0: i2c-bus@80 {
      reg = <0x80 0x80>;
    };
    i2c1: i2c-bus@100 {
      reg = <0x100 0x80>;
    };
  }

Krzysztof mentions[1] that isn't convention though, with the top-level
simple-bus being empty and linked via the label. So, drop the label
usage and move the i2c bus definition into the simple-bus node directly
under the apb:

  apb {
     bus@1e78a000 {
      ranges = <...>;

      i2c0: i2c-bus@80 {
        reg = <0x80 0x80>;
      };
      i2c1: i2c-bus@100 {
        reg = <0x100 0x80>;
      };
    };
  }

This will allow us to be consistent when we add new definitions for the
i3c nodes, which would require the latter format.

Link: https://lore.kernel.org/linux-devicetree/c5331cf8-7295-4e6a-ba39-e0751a2c357e@kernel.org/ [1]
Originally-by: Jeremy Kerr <jk@codeconstruct.com.au>
Signed-off-by: Dawid Glazik <dawid.glazik@linux.intel.com>
---
v3:
 - wasn't sure about target tree - picked the one pointed in
	https://docs.kernel.org/process/maintainer-soc.html
 - pick up series after two years
 - rebase on top of latest tree and solve conflicts
 - as agreed with Jeremy off-list, he said I can take authorship of this going forward
v2:
 - new patch: reorganise i2c nodes before adding new-format i3c nodes
---
 arch/arm/boot/dts/aspeed/aspeed-g6.dtsi | 452 ++++++++++++------------
 1 file changed, 225 insertions(+), 227 deletions(-)

diff --git a/arch/arm/boot/dts/aspeed/aspeed-g6.dtsi b/arch/arm/boot/dts/aspeed/aspeed-g6.dtsi
index 189bc3bbb47c..f5641128614f 100644
--- a/arch/arm/boot/dts/aspeed/aspeed-g6.dtsi
+++ b/arch/arm/boot/dts/aspeed/aspeed-g6.dtsi
@@ -835,11 +835,235 @@ uart9: serial@1e790300 {
 				status = "disabled";
 			};
 
-			i2c: bus@1e78a000 {
+			bus@1e78a000 {
 				compatible = "simple-bus";
 				#address-cells = <1>;
 				#size-cells = <1>;
 				ranges = <0 0x1e78a000 0x1000>;
+
+				i2c0: i2c@80 {
+					#address-cells = <1>;
+					#size-cells = <0>;
+					reg = <0x80 0x80>;
+					compatible = "aspeed,ast2600-i2c-bus";
+					clocks = <&syscon ASPEED_CLK_APB2>;
+					resets = <&syscon ASPEED_RESET_I2C>;
+					interrupts = <GIC_SPI 110 IRQ_TYPE_LEVEL_HIGH>;
+					bus-frequency = <100000>;
+					pinctrl-names = "default";
+					pinctrl-0 = <&pinctrl_i2c1_default>;
+					status = "disabled";
+				};
+
+				i2c1: i2c@100 {
+					#address-cells = <1>;
+					#size-cells = <0>;
+					reg = <0x100 0x80>;
+					compatible = "aspeed,ast2600-i2c-bus";
+					clocks = <&syscon ASPEED_CLK_APB2>;
+					resets = <&syscon ASPEED_RESET_I2C>;
+					interrupts = <GIC_SPI 111 IRQ_TYPE_LEVEL_HIGH>;
+					bus-frequency = <100000>;
+					pinctrl-names = "default";
+					pinctrl-0 = <&pinctrl_i2c2_default>;
+					status = "disabled";
+				};
+
+				i2c2: i2c@180 {
+					#address-cells = <1>;
+					#size-cells = <0>;
+					reg = <0x180 0x80>;
+					compatible = "aspeed,ast2600-i2c-bus";
+					clocks = <&syscon ASPEED_CLK_APB2>;
+					resets = <&syscon ASPEED_RESET_I2C>;
+					interrupts = <GIC_SPI 112 IRQ_TYPE_LEVEL_HIGH>;
+					bus-frequency = <100000>;
+					pinctrl-names = "default";
+					pinctrl-0 = <&pinctrl_i2c3_default>;
+					status = "disabled";
+				};
+
+				i2c3: i2c@200 {
+					#address-cells = <1>;
+					#size-cells = <0>;
+					reg = <0x200 0x80>;
+					compatible = "aspeed,ast2600-i2c-bus";
+					clocks = <&syscon ASPEED_CLK_APB2>;
+					resets = <&syscon ASPEED_RESET_I2C>;
+					interrupts = <GIC_SPI 113 IRQ_TYPE_LEVEL_HIGH>;
+					bus-frequency = <100000>;
+					pinctrl-names = "default";
+					pinctrl-0 = <&pinctrl_i2c4_default>;
+					status = "disabled";
+				};
+
+				i2c4: i2c@280 {
+					#address-cells = <1>;
+					#size-cells = <0>;
+					reg = <0x280 0x80>;
+					compatible = "aspeed,ast2600-i2c-bus";
+					clocks = <&syscon ASPEED_CLK_APB2>;
+					resets = <&syscon ASPEED_RESET_I2C>;
+					interrupts = <GIC_SPI 114 IRQ_TYPE_LEVEL_HIGH>;
+					bus-frequency = <100000>;
+					pinctrl-names = "default";
+					pinctrl-0 = <&pinctrl_i2c5_default>;
+					status = "disabled";
+				};
+
+				i2c5: i2c@300 {
+					#address-cells = <1>;
+					#size-cells = <0>;
+					reg = <0x300 0x80>;
+					compatible = "aspeed,ast2600-i2c-bus";
+					clocks = <&syscon ASPEED_CLK_APB2>;
+					resets = <&syscon ASPEED_RESET_I2C>;
+					interrupts = <GIC_SPI 115 IRQ_TYPE_LEVEL_HIGH>;
+					bus-frequency = <100000>;
+					pinctrl-names = "default";
+					pinctrl-0 = <&pinctrl_i2c6_default>;
+					status = "disabled";
+				};
+
+				i2c6: i2c@380 {
+					#address-cells = <1>;
+					#size-cells = <0>;
+					reg = <0x380 0x80>;
+					compatible = "aspeed,ast2600-i2c-bus";
+					clocks = <&syscon ASPEED_CLK_APB2>;
+					resets = <&syscon ASPEED_RESET_I2C>;
+					interrupts = <GIC_SPI 116 IRQ_TYPE_LEVEL_HIGH>;
+					bus-frequency = <100000>;
+					pinctrl-names = "default";
+					pinctrl-0 = <&pinctrl_i2c7_default>;
+					status = "disabled";
+				};
+
+				i2c7: i2c@400 {
+					#address-cells = <1>;
+					#size-cells = <0>;
+					reg = <0x400 0x80>;
+					compatible = "aspeed,ast2600-i2c-bus";
+					clocks = <&syscon ASPEED_CLK_APB2>;
+					resets = <&syscon ASPEED_RESET_I2C>;
+					interrupts = <GIC_SPI 117 IRQ_TYPE_LEVEL_HIGH>;
+					bus-frequency = <100000>;
+					pinctrl-names = "default";
+					pinctrl-0 = <&pinctrl_i2c8_default>;
+					status = "disabled";
+				};
+
+				i2c8: i2c@480 {
+					#address-cells = <1>;
+					#size-cells = <0>;
+					reg = <0x480 0x80>;
+					compatible = "aspeed,ast2600-i2c-bus";
+					clocks = <&syscon ASPEED_CLK_APB2>;
+					resets = <&syscon ASPEED_RESET_I2C>;
+					interrupts = <GIC_SPI 118 IRQ_TYPE_LEVEL_HIGH>;
+					bus-frequency = <100000>;
+					pinctrl-names = "default";
+					pinctrl-0 = <&pinctrl_i2c9_default>;
+					status = "disabled";
+				};
+
+				i2c9: i2c@500 {
+					#address-cells = <1>;
+					#size-cells = <0>;
+					reg = <0x500 0x80>;
+					compatible = "aspeed,ast2600-i2c-bus";
+					clocks = <&syscon ASPEED_CLK_APB2>;
+					resets = <&syscon ASPEED_RESET_I2C>;
+					interrupts = <GIC_SPI 119 IRQ_TYPE_LEVEL_HIGH>;
+					bus-frequency = <100000>;
+					pinctrl-names = "default";
+					pinctrl-0 = <&pinctrl_i2c10_default>;
+					status = "disabled";
+				};
+
+				i2c10: i2c@580 {
+					#address-cells = <1>;
+					#size-cells = <0>;
+					reg = <0x580 0x80>;
+					compatible = "aspeed,ast2600-i2c-bus";
+					clocks = <&syscon ASPEED_CLK_APB2>;
+					resets = <&syscon ASPEED_RESET_I2C>;
+					interrupts = <GIC_SPI 120 IRQ_TYPE_LEVEL_HIGH>;
+					bus-frequency = <100000>;
+					pinctrl-names = "default";
+					pinctrl-0 = <&pinctrl_i2c11_default>;
+					status = "disabled";
+				};
+
+				i2c11: i2c@600 {
+					#address-cells = <1>;
+					#size-cells = <0>;
+					reg = <0x600 0x80>;
+					compatible = "aspeed,ast2600-i2c-bus";
+					clocks = <&syscon ASPEED_CLK_APB2>;
+					resets = <&syscon ASPEED_RESET_I2C>;
+					interrupts = <GIC_SPI 121 IRQ_TYPE_LEVEL_HIGH>;
+					bus-frequency = <100000>;
+					pinctrl-names = "default";
+					pinctrl-0 = <&pinctrl_i2c12_default>;
+					status = "disabled";
+				};
+
+				i2c12: i2c@680 {
+					#address-cells = <1>;
+					#size-cells = <0>;
+					reg = <0x680 0x80>;
+					compatible = "aspeed,ast2600-i2c-bus";
+					clocks = <&syscon ASPEED_CLK_APB2>;
+					resets = <&syscon ASPEED_RESET_I2C>;
+					interrupts = <GIC_SPI 122 IRQ_TYPE_LEVEL_HIGH>;
+					bus-frequency = <100000>;
+					pinctrl-names = "default";
+					pinctrl-0 = <&pinctrl_i2c13_default>;
+					status = "disabled";
+				};
+
+				i2c13: i2c@700 {
+					#address-cells = <1>;
+					#size-cells = <0>;
+					reg = <0x700 0x80>;
+					compatible = "aspeed,ast2600-i2c-bus";
+					clocks = <&syscon ASPEED_CLK_APB2>;
+					resets = <&syscon ASPEED_RESET_I2C>;
+					interrupts = <GIC_SPI 123 IRQ_TYPE_LEVEL_HIGH>;
+					bus-frequency = <100000>;
+					pinctrl-names = "default";
+					pinctrl-0 = <&pinctrl_i2c14_default>;
+					status = "disabled";
+				};
+
+				i2c14: i2c@780 {
+					#address-cells = <1>;
+					#size-cells = <0>;
+					reg = <0x780 0x80>;
+					compatible = "aspeed,ast2600-i2c-bus";
+					clocks = <&syscon ASPEED_CLK_APB2>;
+					resets = <&syscon ASPEED_RESET_I2C>;
+					interrupts = <GIC_SPI 124 IRQ_TYPE_LEVEL_HIGH>;
+					bus-frequency = <100000>;
+					pinctrl-names = "default";
+					pinctrl-0 = <&pinctrl_i2c15_default>;
+					status = "disabled";
+				};
+
+				i2c15: i2c@800 {
+					#address-cells = <1>;
+					#size-cells = <0>;
+					reg = <0x800 0x80>;
+					compatible = "aspeed,ast2600-i2c-bus";
+					clocks = <&syscon ASPEED_CLK_APB2>;
+					resets = <&syscon ASPEED_RESET_I2C>;
+					interrupts = <GIC_SPI 125 IRQ_TYPE_LEVEL_HIGH>;
+					bus-frequency = <100000>;
+					pinctrl-names = "default";
+					pinctrl-0 = <&pinctrl_i2c16_default>;
+					status = "disabled";
+				};
 			};
 
 			fsim0: fsi@1e79b000 {
@@ -870,229 +1094,3 @@ fsim1: fsi@1e79b100 {
 };
 
 #include "aspeed-g6-pinctrl.dtsi"
-
-&i2c {
-	i2c0: i2c@80 {
-		#address-cells = <1>;
-		#size-cells = <0>;
-		reg = <0x80 0x80>;
-		compatible = "aspeed,ast2600-i2c-bus";
-		clocks = <&syscon ASPEED_CLK_APB2>;
-		resets = <&syscon ASPEED_RESET_I2C>;
-		interrupts = <GIC_SPI 110 IRQ_TYPE_LEVEL_HIGH>;
-		bus-frequency = <100000>;
-		pinctrl-names = "default";
-		pinctrl-0 = <&pinctrl_i2c1_default>;
-		status = "disabled";
-	};
-
-	i2c1: i2c@100 {
-		#address-cells = <1>;
-		#size-cells = <0>;
-		reg = <0x100 0x80>;
-		compatible = "aspeed,ast2600-i2c-bus";
-		clocks = <&syscon ASPEED_CLK_APB2>;
-		resets = <&syscon ASPEED_RESET_I2C>;
-		interrupts = <GIC_SPI 111 IRQ_TYPE_LEVEL_HIGH>;
-		bus-frequency = <100000>;
-		pinctrl-names = "default";
-		pinctrl-0 = <&pinctrl_i2c2_default>;
-		status = "disabled";
-	};
-
-	i2c2: i2c@180 {
-		#address-cells = <1>;
-		#size-cells = <0>;
-		reg = <0x180 0x80>;
-		compatible = "aspeed,ast2600-i2c-bus";
-		clocks = <&syscon ASPEED_CLK_APB2>;
-		resets = <&syscon ASPEED_RESET_I2C>;
-		interrupts = <GIC_SPI 112 IRQ_TYPE_LEVEL_HIGH>;
-		bus-frequency = <100000>;
-		pinctrl-names = "default";
-		pinctrl-0 = <&pinctrl_i2c3_default>;
-		status = "disabled";
-	};
-
-	i2c3: i2c@200 {
-		#address-cells = <1>;
-		#size-cells = <0>;
-		reg = <0x200 0x80>;
-		compatible = "aspeed,ast2600-i2c-bus";
-		clocks = <&syscon ASPEED_CLK_APB2>;
-		resets = <&syscon ASPEED_RESET_I2C>;
-		interrupts = <GIC_SPI 113 IRQ_TYPE_LEVEL_HIGH>;
-		bus-frequency = <100000>;
-		pinctrl-names = "default";
-		pinctrl-0 = <&pinctrl_i2c4_default>;
-		status = "disabled";
-	};
-
-	i2c4: i2c@280 {
-		#address-cells = <1>;
-		#size-cells = <0>;
-		reg = <0x280 0x80>;
-		compatible = "aspeed,ast2600-i2c-bus";
-		clocks = <&syscon ASPEED_CLK_APB2>;
-		resets = <&syscon ASPEED_RESET_I2C>;
-		interrupts = <GIC_SPI 114 IRQ_TYPE_LEVEL_HIGH>;
-		bus-frequency = <100000>;
-		pinctrl-names = "default";
-		pinctrl-0 = <&pinctrl_i2c5_default>;
-		status = "disabled";
-	};
-
-	i2c5: i2c@300 {
-		#address-cells = <1>;
-		#size-cells = <0>;
-		reg = <0x300 0x80>;
-		compatible = "aspeed,ast2600-i2c-bus";
-		clocks = <&syscon ASPEED_CLK_APB2>;
-		resets = <&syscon ASPEED_RESET_I2C>;
-		interrupts = <GIC_SPI 115 IRQ_TYPE_LEVEL_HIGH>;
-		bus-frequency = <100000>;
-		pinctrl-names = "default";
-		pinctrl-0 = <&pinctrl_i2c6_default>;
-		status = "disabled";
-	};
-
-	i2c6: i2c@380 {
-		#address-cells = <1>;
-		#size-cells = <0>;
-		reg = <0x380 0x80>;
-		compatible = "aspeed,ast2600-i2c-bus";
-		clocks = <&syscon ASPEED_CLK_APB2>;
-		resets = <&syscon ASPEED_RESET_I2C>;
-		interrupts = <GIC_SPI 116 IRQ_TYPE_LEVEL_HIGH>;
-		bus-frequency = <100000>;
-		pinctrl-names = "default";
-		pinctrl-0 = <&pinctrl_i2c7_default>;
-		status = "disabled";
-	};
-
-	i2c7: i2c@400 {
-		#address-cells = <1>;
-		#size-cells = <0>;
-		reg = <0x400 0x80>;
-		compatible = "aspeed,ast2600-i2c-bus";
-		clocks = <&syscon ASPEED_CLK_APB2>;
-		resets = <&syscon ASPEED_RESET_I2C>;
-		interrupts = <GIC_SPI 117 IRQ_TYPE_LEVEL_HIGH>;
-		bus-frequency = <100000>;
-		pinctrl-names = "default";
-		pinctrl-0 = <&pinctrl_i2c8_default>;
-		status = "disabled";
-	};
-
-	i2c8: i2c@480 {
-		#address-cells = <1>;
-		#size-cells = <0>;
-		reg = <0x480 0x80>;
-		compatible = "aspeed,ast2600-i2c-bus";
-		clocks = <&syscon ASPEED_CLK_APB2>;
-		resets = <&syscon ASPEED_RESET_I2C>;
-		interrupts = <GIC_SPI 118 IRQ_TYPE_LEVEL_HIGH>;
-		bus-frequency = <100000>;
-		pinctrl-names = "default";
-		pinctrl-0 = <&pinctrl_i2c9_default>;
-		status = "disabled";
-	};
-
-	i2c9: i2c@500 {
-		#address-cells = <1>;
-		#size-cells = <0>;
-		reg = <0x500 0x80>;
-		compatible = "aspeed,ast2600-i2c-bus";
-		clocks = <&syscon ASPEED_CLK_APB2>;
-		resets = <&syscon ASPEED_RESET_I2C>;
-		interrupts = <GIC_SPI 119 IRQ_TYPE_LEVEL_HIGH>;
-		bus-frequency = <100000>;
-		pinctrl-names = "default";
-		pinctrl-0 = <&pinctrl_i2c10_default>;
-		status = "disabled";
-	};
-
-	i2c10: i2c@580 {
-		#address-cells = <1>;
-		#size-cells = <0>;
-		reg = <0x580 0x80>;
-		compatible = "aspeed,ast2600-i2c-bus";
-		clocks = <&syscon ASPEED_CLK_APB2>;
-		resets = <&syscon ASPEED_RESET_I2C>;
-		interrupts = <GIC_SPI 120 IRQ_TYPE_LEVEL_HIGH>;
-		bus-frequency = <100000>;
-		pinctrl-names = "default";
-		pinctrl-0 = <&pinctrl_i2c11_default>;
-		status = "disabled";
-	};
-
-	i2c11: i2c@600 {
-		#address-cells = <1>;
-		#size-cells = <0>;
-		reg = <0x600 0x80>;
-		compatible = "aspeed,ast2600-i2c-bus";
-		clocks = <&syscon ASPEED_CLK_APB2>;
-		resets = <&syscon ASPEED_RESET_I2C>;
-		interrupts = <GIC_SPI 121 IRQ_TYPE_LEVEL_HIGH>;
-		bus-frequency = <100000>;
-		pinctrl-names = "default";
-		pinctrl-0 = <&pinctrl_i2c12_default>;
-		status = "disabled";
-	};
-
-	i2c12: i2c@680 {
-		#address-cells = <1>;
-		#size-cells = <0>;
-		reg = <0x680 0x80>;
-		compatible = "aspeed,ast2600-i2c-bus";
-		clocks = <&syscon ASPEED_CLK_APB2>;
-		resets = <&syscon ASPEED_RESET_I2C>;
-		interrupts = <GIC_SPI 122 IRQ_TYPE_LEVEL_HIGH>;
-		bus-frequency = <100000>;
-		pinctrl-names = "default";
-		pinctrl-0 = <&pinctrl_i2c13_default>;
-		status = "disabled";
-	};
-
-	i2c13: i2c@700 {
-		#address-cells = <1>;
-		#size-cells = <0>;
-		reg = <0x700 0x80>;
-		compatible = "aspeed,ast2600-i2c-bus";
-		clocks = <&syscon ASPEED_CLK_APB2>;
-		resets = <&syscon ASPEED_RESET_I2C>;
-		interrupts = <GIC_SPI 123 IRQ_TYPE_LEVEL_HIGH>;
-		bus-frequency = <100000>;
-		pinctrl-names = "default";
-		pinctrl-0 = <&pinctrl_i2c14_default>;
-		status = "disabled";
-	};
-
-	i2c14: i2c@780 {
-		#address-cells = <1>;
-		#size-cells = <0>;
-		reg = <0x780 0x80>;
-		compatible = "aspeed,ast2600-i2c-bus";
-		clocks = <&syscon ASPEED_CLK_APB2>;
-		resets = <&syscon ASPEED_RESET_I2C>;
-		interrupts = <GIC_SPI 124 IRQ_TYPE_LEVEL_HIGH>;
-		bus-frequency = <100000>;
-		pinctrl-names = "default";
-		pinctrl-0 = <&pinctrl_i2c15_default>;
-		status = "disabled";
-	};
-
-	i2c15: i2c@800 {
-		#address-cells = <1>;
-		#size-cells = <0>;
-		reg = <0x800 0x80>;
-		compatible = "aspeed,ast2600-i2c-bus";
-		clocks = <&syscon ASPEED_CLK_APB2>;
-		resets = <&syscon ASPEED_RESET_I2C>;
-		interrupts = <GIC_SPI 125 IRQ_TYPE_LEVEL_HIGH>;
-		bus-frequency = <100000>;
-		pinctrl-names = "default";
-		pinctrl-0 = <&pinctrl_i2c16_default>;
-		status = "disabled";
-	};
-};
-- 
2.43.0



^ permalink raw reply related

* [PATCH v3 2/3] ARM: dts: aspeed-g6: Add nodes for i3c controllers
From: Dawid Glazik @ 2026-04-08 20:34 UTC (permalink / raw)
  To: Alexandre Belloni, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	Joel Stanley, Andrew Jeffery, linux-aspeed
  Cc: linux-i3c, devicetree, linux-arm-kernel, Frank Li, Dawid Glazik,
	Maciej Lawniczak, Jeremy Kerr
In-Reply-To: <cover.1775679285.git.dawid.glazik@linux.intel.com>

Add the i3c controller devices to the ast2600 g6 common dts. We add all
6 busses to the common g6 definition, but leave disabled through the
status property, to be enabled per-platform.

Originally-by: Jeremy Kerr <jk@codeconstruct.com.au>
Signed-off-by: Dawid Glazik <dawid.glazik@linux.intel.com>
---
v3:
 - add i3c aliases
 - rebase on top of latest tree and solve conflicts
 - as agreed with Jeremy off-list, he said I can take authorship of this going forward
v2:
 - use inline bus representation, without the i3c: label
---
 arch/arm/boot/dts/aspeed/aspeed-g6.dtsi | 97 +++++++++++++++++++++++++
 1 file changed, 97 insertions(+)

diff --git a/arch/arm/boot/dts/aspeed/aspeed-g6.dtsi b/arch/arm/boot/dts/aspeed/aspeed-g6.dtsi
index f5641128614f..f986fcbed604 100644
--- a/arch/arm/boot/dts/aspeed/aspeed-g6.dtsi
+++ b/arch/arm/boot/dts/aspeed/aspeed-g6.dtsi
@@ -29,6 +29,12 @@ aliases {
 		i2c13 = &i2c13;
 		i2c14 = &i2c14;
 		i2c15 = &i2c15;
+		i3c0 = &i3c0;
+		i3c1 = &i3c1;
+		i3c2 = &i3c2;
+		i3c3 = &i3c3;
+		i3c4 = &i3c4;
+		i3c5 = &i3c5;
 		serial0 = &uart1;
 		serial1 = &uart2;
 		serial2 = &uart3;
@@ -1066,6 +1072,97 @@ i2c15: i2c@800 {
 				};
 			};
 
+			bus@1e7a0000 {
+				compatible = "simple-bus";
+				#address-cells = <1>;
+				#size-cells = <1>;
+				ranges = <0 0x1e7a0000 0x8000>;
+
+				i3c_global: i3c-global@0 {
+					compatible = "aspeed,ast2600-i3c-global", "syscon";
+					reg = <0x0 0x1000>;
+					resets = <&syscon ASPEED_RESET_I3C_DMA>;
+				};
+
+				i3c0: i3c@2000 {
+					compatible = "aspeed,ast2600-i3c";
+					reg = <0x2000 0x1000>;
+					#address-cells = <3>;
+					#size-cells = <0>;
+					clocks = <&syscon ASPEED_CLK_GATE_I3C0CLK>;
+					pinctrl-names = "default";
+					pinctrl-0 = <&pinctrl_i3c1_default>;
+					interrupts = <GIC_SPI 102 IRQ_TYPE_LEVEL_HIGH>;
+					aspeed,global-regs = <&i3c_global 0>;
+					status = "disabled";
+				};
+
+				i3c1: i3c@3000 {
+					compatible = "aspeed,ast2600-i3c";
+					reg = <0x3000 0x1000>;
+					#address-cells = <3>;
+					#size-cells = <0>;
+					clocks = <&syscon ASPEED_CLK_GATE_I3C1CLK>;
+					pinctrl-names = "default";
+					pinctrl-0 = <&pinctrl_i3c2_default>;
+					interrupts = <GIC_SPI 103 IRQ_TYPE_LEVEL_HIGH>;
+					aspeed,global-regs = <&i3c_global 1>;
+					status = "disabled";
+				};
+
+				i3c2: i3c@4000 {
+					compatible = "aspeed,ast2600-i3c";
+					reg = <0x4000 0x1000>;
+					#address-cells = <3>;
+					#size-cells = <0>;
+					clocks = <&syscon ASPEED_CLK_GATE_I3C2CLK>;
+					pinctrl-names = "default";
+					pinctrl-0 = <&pinctrl_i3c3_default>;
+					interrupts = <GIC_SPI 104 IRQ_TYPE_LEVEL_HIGH>;
+					aspeed,global-regs = <&i3c_global 2>;
+					status = "disabled";
+				};
+
+				i3c3: i3c@5000 {
+					compatible = "aspeed,ast2600-i3c";
+					reg = <0x5000 0x1000>;
+					#address-cells = <3>;
+					#size-cells = <0>;
+					clocks = <&syscon ASPEED_CLK_GATE_I3C3CLK>;
+					pinctrl-names = "default";
+					pinctrl-0 = <&pinctrl_i3c4_default>;
+					interrupts = <GIC_SPI 105 IRQ_TYPE_LEVEL_HIGH>;
+					aspeed,global-regs = <&i3c_global 3>;
+					status = "disabled";
+				};
+
+				i3c4: i3c@6000 {
+					compatible = "aspeed,ast2600-i3c";
+					reg = <0x6000 0x1000>;
+					#address-cells = <3>;
+					#size-cells = <0>;
+					clocks = <&syscon ASPEED_CLK_GATE_I3C4CLK>;
+					pinctrl-names = "default";
+					pinctrl-0 = <&pinctrl_i3c5_default>;
+					interrupts = <GIC_SPI 106 IRQ_TYPE_LEVEL_HIGH>;
+					aspeed,global-regs = <&i3c_global 4>;
+					status = "disabled";
+				};
+
+				i3c5: i3c@7000 {
+					compatible = "aspeed,ast2600-i3c";
+					reg = <0x7000 0x1000>;
+					#address-cells = <3>;
+					#size-cells = <0>;
+					clocks = <&syscon ASPEED_CLK_GATE_I3C5CLK>;
+					pinctrl-names = "default";
+					pinctrl-0 = <&pinctrl_i3c6_default>;
+					interrupts = <GIC_SPI 107 IRQ_TYPE_LEVEL_HIGH>;
+					aspeed,global-regs = <&i3c_global 5>;
+					status = "disabled";
+				};
+			};
+
 			fsim0: fsi@1e79b000 {
 				#interrupt-cells = <1>;
 				compatible = "aspeed,ast2600-fsi-master";
-- 
2.43.0



^ permalink raw reply related

* [PATCH v3 3/3] dt-bindings: i3c: Add AST2600 I3C global registers
From: Dawid Glazik @ 2026-04-08 20:34 UTC (permalink / raw)
  To: Alexandre Belloni, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	Joel Stanley, Andrew Jeffery, linux-aspeed
  Cc: linux-i3c, devicetree, linux-arm-kernel, Frank Li, Dawid Glazik,
	Maciej Lawniczak
In-Reply-To: <cover.1775679285.git.dawid.glazik@linux.intel.com>

Introduce the device-tree bindings for I3C global registers found on
AST2600 SoCs.

Signed-off-by: Dawid Glazik <dawid.glazik@linux.intel.com>
---
I wasn't sure if I should add newline at the end of the
file or not so I took
https://github.com/torvalds/linux/tree/master/Documentation/devicetree/bindings/i3c
as an example.
---
 .../i3c/aspeed,ast2600-i3c-global.yaml        | 55 +++++++++++++++++++
 1 file changed, 55 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/i3c/aspeed,ast2600-i3c-global.yaml

diff --git a/Documentation/devicetree/bindings/i3c/aspeed,ast2600-i3c-global.yaml b/Documentation/devicetree/bindings/i3c/aspeed,ast2600-i3c-global.yaml
new file mode 100644
index 000000000000..edecc18796a9
--- /dev/null
+++ b/Documentation/devicetree/bindings/i3c/aspeed,ast2600-i3c-global.yaml
@@ -0,0 +1,55 @@
+# SPDX-License-Identifier: GPL-2.0 OR BSD-2-Clause
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/i3c/aspeed,ast2600-i3c-global.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: ASPEED AST2600 I3C Global Registers
+
+description: |
+  The AST2600 SoC provides a shared I3C global register block used by all
+  I3C controller instances. This block contains per-instance global
+  configuration fields, including controller instance ID and SDA pull-up
+  configuration.
+  Each I3C controller references this syscon node through the
+  aspeed,global-regs property.
+
+maintainers:
+  - Dawid Glazik <dawid.glazik@linux.intel.com>
+
+allOf:
+  - $ref: /schemas/mfd/syscon-common.yaml#
+
+properties:
+  compatible:
+    items:
+      - const: aspeed,ast2600-i3c-global
+      - const: syscon
+
+  reg:
+    maxItems: 1
+
+  resets:
+    maxItems: 1
+
+required:
+  - compatible
+  - reg
+
+unevaluatedProperties: false
+
+examples:
+  - |
+    bus@1e7a0000 {
+        compatible = "simple-bus";
+        #address-cells = <1>;
+        #size-cells = <1>;
+        ranges = <0 0x1e7a0000 0x8000>;
+
+        i3c-global@0 {
+            compatible = "aspeed,ast2600-i3c-global", "syscon";
+            reg = <0x0 0x1000>;
+            resets = <&syscon ASPEED_RESET_I3C_DMA>;
+        };
+    };
+...
\ No newline at end of file
-- 
2.43.0



^ permalink raw reply related

* Re: [PATCH 2/3] nvmem: Add the Raspberry Pi OTP driver
From: Gregor Herburger @ 2026-04-08 19:47 UTC (permalink / raw)
  To: Stefan Wahren
  Cc: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Florian Fainelli,
	Ray Jui, Scott Branden, Broadcom internal kernel review list,
	Srinivas Kandagatla, devicetree, linux-rpi-kernel,
	linux-arm-kernel, linux-kernel
In-Reply-To: <251100fe-db96-4d83-899a-cd764582d698@gmx.net>

Hi Stefan,

thanks for the review.

> > +config NVMEM_RASPBERRYPI_OTP
> > +	tristate "Raspberry Pi OTP support"
> > +	# Make sure not 'y' when RASPBERRYPI_FIRMWARE is 'm'. This can only
> > +	# happen when COMPILE_TEST=y, hence the added !RASPBERRYPI_FIRMWARE.
> I don't think these comments are necessary, because this applies to other
> firmware drivers, too.

I have seen this in all the other drivers that depend on RASPBERRYPI_FIRMWARE
so I added it here as well. I can remove it.
> > +	depends on RASPBERRYPI_FIRMWARE || (COMPILE_TEST && !RASPBERRYPI_FIRMWARE)
> > +	help
> > +	  This driver provides access to the Raspberry Pi OTP memory via the
> > +	  nvmem subsystem. The driver supports the customer otp as well as the
> > +	  device specific private key OTP.
> > +
> > +	  This driver can also be built as a module. If so, the module
> > +	  will be called raspberrypi-otp.
> >   endif
> > diff --git a/drivers/nvmem/Makefile b/drivers/nvmem/Makefile
> > index 7252b8ec88d4..8ca2095e068f 100644

> Is there any reason, why we cannot register this driver in
> rpi_firmware_probe() like hwmon and clk driver?
> 
> I like to avoid the complete dt-binding from patch 1.

The private OTP registers are not available on all Raspberries. Afaik
only on 4 and 5. So I think these registers must be described through
the device tree. Therefore the bindings are needed.

> > +module_platform_driver(raspberry_otp_driver);
> > +
> > +MODULE_AUTHOR("Gregor Herburger <gregor.herburger@linutronix.de>");
> > +MODULE_DESCRIPTION("Raspberry OTP driver");
> Raspberry Pi OTP driver ?

Yes. I will update in the next version.


^ permalink raw reply

* Re: [PATCH v2] media: verisilicon: Create AV1 helper library
From: Nicolas Dufresne @ 2026-04-08 19:49 UTC (permalink / raw)
  To: Benjamin Gaignard, p.zabel, mchehab, heiko
  Cc: linux-kernel, linux-media, linux-rockchip, linux-arm-kernel,
	kernel
In-Reply-To: <20260312091525.28118-1-benjamin.gaignard@collabora.com>

[-- Attachment #1: Type: text/plain, Size: 2641 bytes --]

Le jeudi 12 mars 2026 à 10:15 +0100, Benjamin Gaignard a écrit :
> Regroup all none hardware related AV1 functions into a helper library.
> The goal is to avoid code duplication for futur AV1 codecs.
> 
> Tested on rock 5b board Fluster score remains the same 204/241.
> 
> Signed-off-by: Benjamin Gaignard <benjamin.gaignard@collabora.com>
> ---
> change in v2
> - rockchip av1 codec use hantro_av1_get_hardware_tx_mode() and no more
>   it own function.
> 
>  drivers/media/platform/verisilicon/Makefile   |   7 +-
>  .../media/platform/verisilicon/hantro_av1.c   | 780 +++++++++++++++
>  .../media/platform/verisilicon/hantro_av1.h   |  62 ++
>  ...entropymode.c => hantro_av1_entropymode.c} |  18 +-
>  ...entropymode.h => hantro_av1_entropymode.h} |  18 +-
>  ...av1_filmgrain.c => hantro_av1_filmgrain.c} |  82 +-
>  .../verisilicon/hantro_av1_filmgrain.h        |  44 +
>  .../media/platform/verisilicon/hantro_hw.h    |   4 +-
>  .../verisilicon/rockchip_av1_filmgrain.h      |  36 -
>  .../verisilicon/rockchip_vpu981_hw_av1_dec.c  | 942 ++----------------
>  10 files changed, 1048 insertions(+), 945 deletions(-)
>  create mode 100644 drivers/media/platform/verisilicon/hantro_av1.c
>  create mode 100644 drivers/media/platform/verisilicon/hantro_av1.h
>  rename drivers/media/platform/verisilicon/{rockchip_av1_entropymode.c => hantro_av1_entropymode.c} (99%)
>  rename drivers/media/platform/verisilicon/{rockchip_av1_entropymode.h => hantro_av1_entropymode.h} (95%)
>  rename drivers/media/platform/verisilicon/{rockchip_av1_filmgrain.c => hantro_av1_filmgrain.c} (92%)
>  create mode 100644 drivers/media/platform/verisilicon/hantro_av1_filmgrain.h
>  delete mode 100644 drivers/media/platform/verisilicon/rockchip_av1_filmgrain.h

[...]
 
>  	rockchip_vpu981_av1_dec_set_parameters(ctx);
>  	rockchip_vpu981_av1_dec_set_global_model(ctx);
> @@ -2197,6 +1439,16 @@ int rockchip_vpu981_av1_dec_run(struct hantro_ctx *ctx)
>  	return ret;
>  }
>  
> +int rockchip_vpu981_av1_dec_init(struct hantro_ctx *ctx)

nit: The wrapper is no longer needed, you can change rockchip_vpu_hw.c code to:

           .init = hantro_av1_init

> +{
> +	return hantro_av1_init(ctx);
> +}
> +
> +void rockchip_vpu981_av1_dec_exit(struct hantro_ctx *ctx)
> +{
> +	hantro_av1_exit(ctx);

Same nit, different function. Appart from that:

Reviewed-by: Nicolas Dufresne <nicolas.dufresne@collabora.com>

> +}
> +
>  static void rockchip_vpu981_postproc_enable(struct hantro_ctx *ctx)
>  {
>  	struct hantro_dev *vpu = ctx->dev;

[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 228 bytes --]

^ permalink raw reply

* Re: BUG: net-next (7.0-rc6 based and later) fails to boot on Jetson Xavier NX
From: Russell King (Oracle) @ 2026-04-08 19:52 UTC (permalink / raw)
  To: Robin Murphy
  Cc: netdev, linux-arm-kernel, linux-kernel, iommu, linux-ext4,
	Linus Torvalds, dmaengine, Marek Szyprowski, Theodore Ts'o,
	Andreas Dilger, Vinod Koul, Frank Li
In-Reply-To: <3a1d0520-3402-47b2-9d7b-4e14a3cd07a4@arm.com>

On Wed, Apr 08, 2026 at 05:40:48PM +0100, Robin Murphy wrote:
> On 2026-04-08 5:16 pm, Russell King (Oracle) wrote:
> > On Wed, Apr 08, 2026 at 05:08:34PM +0100, Russell King (Oracle) wrote:
> > > The rebase is still progressing, but it's landed on:
> > > 
> > > c7d812e33f3e dmaengine: xilinx: xilinx_dma: Fix unmasked residue subtraction
> 
> FWIW I don't see a Tegra having the Xilinx IP in it anyway - judging by the
> DT it has their own tegra-gpcdma engine...
> 
> There's a fair chance this could be 90c5def10bea ("iommu: Do not call
> drivers for empty gathers"), which JonH also reported causing boot issues on
> Tegras - in short, SMMU TLB maintenance may not be completed properly which
> could lead to recycled DMA addresses causing exactly this kind of random
> memory corruption. I CC'd you on a patch:
> 
> https://lore.kernel.org/linux-iommu/20260408162846.GE3357077@nvidia.com/T/#t

Okay, bisect complete, and... no idea. It seems to suggest that 7.0-rc6
is actually fine - it ended up blaming Linus' tagging of 7.0-rc6 which
only changed the makefile. So, my assumption that because rc6 was merged
into net-next last Thursday which fails, net-next+rc7 fails, rc7 also
fails, that rc6 would also fail seems to be false.

Right, rc7 built with the same .config that rc6 was built with
definitely fails, this time with:

Root device found: PARTUUID=741c0777-391a-4bce-a222-455e180ece2a
depmod: ERROR: could not open directory /lib/modules/7.0.0-rc7-bisect: No such file or directory
depmod: FATAL: could not search modules: No such file or directory
usb 2-3: new SuperSpeed Plus Gen 2x1 USB device number 2 using tegra-xusb
hub 2-3:1.0: USB hub found
hub 2-3:1.0: 4 ports detected
usb 1-3: new full-speed USB device number 3 using tegra-xusb
EXT4-fs (mmcblk0p1): VFS: Can't find ext4 filesystem
mount: /mnt: wrong fs type, bad option, bad superblock on /dev/mmcblk0p1, missing codepage or helper program, or other error.
mount: /mnt/: can't find PARTUUID=741c0777-391a-4bce-a222-455e180ece2a.
get_swap_device: Bad swap file entry 1800c00008
get_swap_device: Bad swap file entry 1800c00008
get_swap_device: Bad swap file entry 1800c00008

So, it seems rc6 -> rc7 => fails
net-next with rc5 -> net-next with rc6 => fails

However, before I test anything else, I've just built the same rc7
which failed above with your patch applied - and that boots fine.

Now, each Thursday, net-next gets updated as that's the day that the
net tree gets sent for merging into mainline. This causes net-next's
version to increase. So something in current net-next plus in rc7 is
causing this problem.

The commit you claim needs fixing is:

$ git describe --contains 90c5def10bea
v7.0-rc7~29^2~2

which I had assumed wouldn't be in net-next.

Now, mainline had this on Thursday:

commit f8f5627a8aeab15183eef8930bf75ba88a51622f
Merge: 4c2c526b5adf ec7067e66119
Author: Linus Torvalds <torvalds@linux-foundation.org>
Date:   Thu Apr 2 09:57:06 2026 -0700

    Merge tag 'net-7.0-rc7' of git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net

commit 4c2c526b5adfb580bd95316bf179327d5ee26da8
Merge: 2ec9074b28a0 8b72aa5704c7
Author: Linus Torvalds <torvalds@linux-foundation.org>
Date:   Thu Apr 2 09:53:16 2026 -0700

    Merge tag 'iommu-fixes-v7.0-rc6' of git://git.kernel.org/pub/scm/linux/kernel/git/iommu/linux

and merging iommu-fixes-v7.0-rc6 introduced the buggy 90c5def10bea
commit into -rc7.

However, as soon as Linus merged net-7.0-rc7, netdev maintainers merged
that exact commit back into net-next:

commit 8ffb33d7709b59ff60560f48960a73bd8a55be95
Merge: 269389ba5398 f8f5627a8aea
Author: Jakub Kicinski <kuba@kernel.org>
Date:   Thu Apr 2 10:57:09 2026 -0700

    Merge git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net

Thereby bringing in that buggy commit into net-next, but with net-next
identifying itself as 7.0-rc6.

That's... confusing, but explains why current net-next which reports
itself as 7.0-rc6 _and_ rc7 both fail, but rc6 itself does not. It
also means I've wasted an entire afternoon running a useless bisect
between rc5 and rc6 due to the version numbers in net-next being
meaningless.

What's the status on the iommu fix? Is it merged into mainline yet?
If it isn't already, that means net-next remains unbootable going
into the merge window without manually carrying the fix locally.

-- 
RMK's Patch system: https://www.armlinux.org.uk/developer/patches/
FTTP is here! 80Mbps down 10Mbps up. Decent connectivity at last!


^ permalink raw reply

* Re: [PATCH 2/3] nvmem: Add the Raspberry Pi OTP driver
From: Stefan Wahren @ 2026-04-08 20:03 UTC (permalink / raw)
  To: Gregor Herburger
  Cc: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Florian Fainelli,
	Ray Jui, Scott Branden, Broadcom internal kernel review list,
	Srinivas Kandagatla, devicetree, linux-rpi-kernel,
	linux-arm-kernel, linux-kernel
In-Reply-To: <adaw1rr3WlDjvyQp@gregor-framework>

Am 08.04.26 um 21:47 schrieb Gregor Herburger:
> Hi Stefan,
>
> thanks for the review.
>> Is there any reason, why we cannot register this driver in
>> rpi_firmware_probe() like hwmon and clk driver?
>>
>> I like to avoid the complete dt-binding from patch 1.
> The private OTP registers are not available on all Raspberries. Afaik
> only on 4 and 5. So I think these registers must be described through
> the device tree. Therefore the bindings are needed.
This binding doesn't represent some kind of hardware, it's just some 
firmware interface. A proper DT binding would describe the MMIO address 
range for OTP access.
If you need some distinction between the Raspberry Pi generations there 
are firmware tags to do this.

Regards



^ permalink raw reply

* Re: [PATCH 2/2] arm64: dts: imx8dxl: Add SolidRun SoM and HummingBoard
From: Andrew Lunn @ 2026-04-08 20:12 UTC (permalink / raw)
  To: Josua Mayer
  Cc: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Shawn Guo,
	Frank Li, Sascha Hauer, Pengutronix Kernel Team, Fabio Estevam,
	Yazan Shhady, Mikhail Anikin, Alexander Dahl, devicetree,
	linux-kernel, imx, linux-arm-kernel
In-Reply-To: <20260408-imx8dxl-sr-som-v1-2-ce5a39acd713@solid-run.com>

> +&eqos {
> +	phy-mode = "rgmii-id";
> +	pinctrl-0 = <&eqos_pins>;
> +	pinctrl-names = "default";
> +	status = "okay";
> +
> +	fixed-link {
> +		full-duplex;
> +		speed = <1000>;
> +	};
> +};

> +	ethernet-switch@0 {
> +		compatible = "nxp,sja1110a";

....

> +
> +			/* to CPU */
> +			port@2 {
> +				reg = <0x2>;
> +				ethernet = <&eqos>;
> +				label = "cpu";
> +				phy-mode = "rgmii-id";
> +				rx-internal-delay-ps = <2000>;
> +				tx-internal-delay-ps = <2000>;

The eqos is using rgmii-id, this port is using rmgii-id, and you set
the delays to 2000ns. How is this not resulting in 4000ns delays?

    Andrew


^ permalink raw reply

* Re: [PATCH v2 0/5] Migrate soc, drm-mediatek, mdp3 to new CMDQ APIs (series 2/4)
From: Nicolas Dufresne @ 2026-04-08 20:22 UTC (permalink / raw)
  To: Jason-JH Lin, Jassi Brar, Chun-Kuang Hu,
	AngeloGioacchino Del Regno, Mauro Carvalho Chehab
  Cc: Matthias Brugger, Nancy Lin, Singo Chang, Paul-PL Chen, Moudy Ho,
	Xiandong Wang, Sirius Wang, Fei Shao, Chen-yu Tsai,
	Project_Global_Chrome_Upstream_Group, linux-kernel, dri-devel,
	linux-mediatek, linux-arm-kernel, linux-media
In-Reply-To: <20260325035836.2110757-1-jason-jh.lin@mediatek.com>

[-- Attachment #1: Type: text/plain, Size: 1764 bytes --]

Hi,

Le mercredi 25 mars 2026 à 11:57 +0800, Jason-JH Lin a écrit :
> This series migrates the MediaTek SoC, DRM, and MDP3 drivers to the new
> CMDQ APIs introduced for MT8196.
> 
> Series application order:
>   1. [Series V2 2/4] Migrate subsystems to new CMDQ APIs (this series)
>   2. [Series V2 3/4] Remove shift_pa from CMDQ jump functions
>   3. [Series V2 4/4] Remove deprecated CMDQ APIs
> 
> Please apply this series after the MT8196 GCE support series,
> and before the following series.
> 
> ---
> 
> Change in v2:
> 1. Rebase on linux-next
> 2. Fix build error of -EINVAL in patch2.
> 
> ---
> 
> Jason-JH Lin (5):
>   soc: mediatek: Use pkt_write function pointer for subsys ID
>     compatibility
>   soc: mediatek: mtk-cmdq: Add cmdq_pkt_jump_rel_temp() for removing
>     shift_pa
>   drm/mediatek:Use reg_write function pointer for subsys ID
>     compatibility
>   media: platform: mtk-mdp3: Refactor CMDQ writes for CMDQ API change
>   media: platform: mtk-mdp3: Change cmdq_pkt_jump_rel() to
>     cmdq_pkt_jump_rel_temp()

Can the two last be applied to the media tree alone without breaking anything ?
Otherwise I will need to wait for the soc: patches to have landed.

Nicolas

> 
>  drivers/gpu/drm/mediatek/mtk_ddp_comp.c       | 12 +++++-----
>  .../platform/mediatek/mdp3/mtk-mdp3-cmdq.c    |  6 ++---
>  .../platform/mediatek/mdp3/mtk-mdp3-comp.h    |  6 ++---
>  drivers/soc/mediatek/mtk-mmsys.c              |  8 ++++---
>  drivers/soc/mediatek/mtk-mutex.c              |  5 ++--
>  include/linux/soc/mediatek/mtk-cmdq.h         | 24 +++++++++++++++++++
>  6 files changed, 44 insertions(+), 17 deletions(-)

[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 228 bytes --]

^ permalink raw reply

* [PATCH 0/2] KVM: arm64: KVM: arm64: Add per-VM WFI/WFE exit disable capability
From: David Woodhouse @ 2026-04-08 20:23 UTC (permalink / raw)
  To: Paolo Bonzini, Jonathan Corbet, Shuah Khan, Marc Zyngier,
	Oliver Upton, Joey Gouly, Suzuki K Poulose, Zenghui Yu,
	Catalin Marinas, Will Deacon, kvm, linux-doc, linux-kernel,
	linux-arm-kernel, kvmarm, linux-kselftest, Colton Lewis,
	Jing Zhang, David Woodhouse

Add KVM_CAP_ARM_DISABLE_EXITS, modelled after the existing x86
KVM_CAP_X86_DISABLE_EXITS, to allow userspace to disable WFI and/or
WFE trapping on a per-VM basis.

KVM already has system-wide kernel command line parameters
(kvm-arm.wfi_trap_policy and kvm-arm.wfe_trap_policy, added in
0b5afe05377d) to control WFx trapping. However, these are global and
set at boot time. A per-VM capability allows the VMM to make the
decision per guest — for example, disabling WFI trapping for
latency-sensitive VMs with pinned vCPUs while keeping it enabled for
overcommitted guests on the same host.

When a flag is set via KVM_ENABLE_CAP, the corresponding trap is
unconditionally cleared, overriding the system-wide policy. When the
flag is not set, the system policy (including the default
single-task heuristic) applies as before.

As with the x86 equivalent, disabling exits is a one-way operation
per VM.

Tested on Graviton 3 (Neoverse-V1) metal.

David Woodhouse (2):
  KVM: arm64: Add KVM_CAP_ARM_DISABLE_EXITS for WFI/WFE passthrough
  KVM: arm64: selftests: Add KVM_CAP_ARM_DISABLE_EXITS UAPI test

 Documentation/virt/kvm/api.rst                    | 28 +++++++++++++
 arch/arm64/include/asm/kvm_host.h                 |  4 ++
 arch/arm64/kvm/arm.c                              | 20 ++++++++++
 include/uapi/linux/kvm.h                          |  6 +++
 tools/testing/selftests/kvm/Makefile.kvm          |  1 +
 tools/testing/selftests/kvm/arm64/disable_exits.c | 48 +++++++++++++++++++++++
 6 files changed, 107 insertions(+)
 create mode 100644 tools/testing/selftests/kvm/arm64/disable_exits.c



^ permalink raw reply

* [PATCH 2/2] KVM: arm64: selftests: Add KVM_CAP_ARM_DISABLE_EXITS UAPI test
From: David Woodhouse @ 2026-04-08 20:23 UTC (permalink / raw)
  To: Paolo Bonzini, Jonathan Corbet, Shuah Khan, Marc Zyngier,
	Oliver Upton, Joey Gouly, Suzuki K Poulose, Zenghui Yu,
	Catalin Marinas, Will Deacon, kvm, linux-doc, linux-kernel,
	linux-arm-kernel, kvmarm, linux-kselftest, Colton Lewis,
	Jing Zhang, David Woodhouse
In-Reply-To: <20260408202557.2102476-1-dwmw2@infradead.org>

From: David Woodhouse <dwmw@amazon.co.uk>

Test the KVM_CAP_ARM_DISABLE_EXITS capability interface:
 - KVM_CHECK_EXTENSION reports KVM_ARM_DISABLE_EXITS_WFI
 - KVM_ENABLE_CAP succeeds with valid flags (WFI, zero)
 - KVM_ENABLE_CAP fails with EINVAL for unknown flags

Signed-off-by: David Woodhouse <dwmw@amazon.co.uk>
---
 tools/testing/selftests/kvm/Makefile.kvm      |  1 +
 .../selftests/kvm/arm64/disable_exits.c       | 48 +++++++++++++++++++
 2 files changed, 49 insertions(+)
 create mode 100644 tools/testing/selftests/kvm/arm64/disable_exits.c

diff --git a/tools/testing/selftests/kvm/Makefile.kvm b/tools/testing/selftests/kvm/Makefile.kvm
index 878d7cb92555..d8e7ff122445 100644
--- a/tools/testing/selftests/kvm/Makefile.kvm
+++ b/tools/testing/selftests/kvm/Makefile.kvm
@@ -179,6 +179,7 @@ TEST_GEN_PROGS_arm64 += arm64/vgic_irq
 TEST_GEN_PROGS_arm64 += arm64/vgic_lpi_stress
 TEST_GEN_PROGS_arm64 += arm64/vgic_group_iidr
 TEST_GEN_PROGS_arm64 += arm64/vgic_group_v2
+TEST_GEN_PROGS_arm64 += arm64/disable_exits
 TEST_GEN_PROGS_arm64 += arm64/vpmu_counter_access
 TEST_GEN_PROGS_arm64 += arm64/no-vgic-v3
 TEST_GEN_PROGS_arm64 += arm64/idreg-idst
diff --git a/tools/testing/selftests/kvm/arm64/disable_exits.c b/tools/testing/selftests/kvm/arm64/disable_exits.c
new file mode 100644
index 000000000000..27fe6c9297b2
--- /dev/null
+++ b/tools/testing/selftests/kvm/arm64/disable_exits.c
@@ -0,0 +1,48 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * disable_exits.c - Test KVM_CAP_ARM_DISABLE_EXITS UAPI
+ *
+ * Verify that KVM_CHECK_EXTENSION reports the valid exit disable mask
+ * and that KVM_ENABLE_CAP accepts valid flags and rejects invalid ones.
+ */
+#include "test_util.h"
+#include "kvm_util.h"
+#include "processor.h"
+
+int main(int argc, char *argv[])
+{
+	struct kvm_vm *vm;
+	int r;
+
+	TEST_REQUIRE(kvm_has_cap(KVM_CAP_ARM_DISABLE_EXITS));
+
+	r = kvm_check_cap(KVM_CAP_ARM_DISABLE_EXITS);
+	TEST_ASSERT(r & KVM_ARM_DISABLE_EXITS_WFI,
+		    "KVM_CHECK_EXTENSION should report WFI: got 0x%x", r);
+	TEST_ASSERT(r & KVM_ARM_DISABLE_EXITS_WFE,
+		    "KVM_CHECK_EXTENSION should report WFE: got 0x%x", r);
+
+	vm = vm_create(1);
+
+	/* Valid: disable WFI trapping */
+	vm_enable_cap(vm, KVM_CAP_ARM_DISABLE_EXITS, KVM_ARM_DISABLE_EXITS_WFI);
+
+	/* Valid: disable WFE trapping */
+	vm_enable_cap(vm, KVM_CAP_ARM_DISABLE_EXITS, KVM_ARM_DISABLE_EXITS_WFE);
+
+	/* Valid: disable both */
+	vm_enable_cap(vm, KVM_CAP_ARM_DISABLE_EXITS,
+		      KVM_ARM_DISABLE_EXITS_WFI | KVM_ARM_DISABLE_EXITS_WFE);
+
+	/* Valid: no exits disabled (no-op) */
+	vm_enable_cap(vm, KVM_CAP_ARM_DISABLE_EXITS, 0);
+
+	/* Invalid: unknown bit set */
+	r = __vm_enable_cap(vm, KVM_CAP_ARM_DISABLE_EXITS, 1ULL << 31);
+	TEST_ASSERT(r == -1 && errno == EINVAL,
+		    "Unknown flags should fail with EINVAL: got %d errno %d",
+		    r, errno);
+
+	kvm_vm_free(vm);
+	return 0;
+}
-- 
2.51.0



^ permalink raw reply related

* [PATCH 1/2] KVM: arm64: Add KVM_CAP_ARM_DISABLE_EXITS for WFI/WFE passthrough
From: David Woodhouse @ 2026-04-08 20:23 UTC (permalink / raw)
  To: Paolo Bonzini, Jonathan Corbet, Shuah Khan, Marc Zyngier,
	Oliver Upton, Joey Gouly, Suzuki K Poulose, Zenghui Yu,
	Catalin Marinas, Will Deacon, kvm, linux-doc, linux-kernel,
	linux-arm-kernel, kvmarm, linux-kselftest, Colton Lewis,
	Jing Zhang, David Woodhouse
In-Reply-To: <20260408202557.2102476-1-dwmw2@infradead.org>

From: David Woodhouse <dwmw@amazon.co.uk>

Add a per-VM capability to allow userspace to disable WFI and/or WFE
trapping, modelled after x86's KVM_CAP_X86_DISABLE_EXITS. When the
corresponding flag is set, the trap is unconditionally cleared
regardless of the global kvm-arm.wf{i,e}_trap_policy setting.

The existing kernel command line parameters provide a system-wide
override, but a per-VM capability allows the VMM to make the decision
per guest.

This is useful for hypervisors running a combination of dedicated
pinned vCPUs which want to avoid the cost of trapping WFI/WFE, as
well as overcommitted floating instances where it is necessary.

As with the x86 equivalent, KVM_CHECK_EXTENSION returns the bitmask of
supported exit disables.

Signed-off-by: David Woodhouse <dwmw@amazon.co.uk>
---
 Documentation/virt/kvm/api.rst    | 28 ++++++++++++++++++++++++++++
 arch/arm64/include/asm/kvm_host.h |  4 ++++
 arch/arm64/kvm/arm.c              | 20 ++++++++++++++++++++
 include/uapi/linux/kvm.h          |  6 ++++++
 4 files changed, 58 insertions(+)

diff --git a/Documentation/virt/kvm/api.rst b/Documentation/virt/kvm/api.rst
index 032516783e96..e3b3bd9edeec 100644
--- a/Documentation/virt/kvm/api.rst
+++ b/Documentation/virt/kvm/api.rst
@@ -8902,6 +8902,34 @@ helpful if user space wants to emulate instructions which are not
 This capability can be enabled dynamically even if VCPUs were already
 created and are running.
 
+7.47 KVM_CAP_ARM_DISABLE_EXITS
+------------------------------
+
+:Architecture: arm64
+:Target: VM
+:Parameters: args[0] is a bitmask of exits to disable
+:Returns: 0 on success, -EINVAL if unsupported bits are set.
+
+Valid bits in args[0]:
+
+ - ``KVM_ARM_DISABLE_EXITS_WFI``: Disable trapping of WFI (Wait For
+   Interrupt) instructions. The guest WFI will execute natively instead
+   of causing a VM exit.
+
+ - ``KVM_ARM_DISABLE_EXITS_WFE``: Disable trapping of WFE (Wait For
+   Event) instructions. The guest WFE will execute natively instead of
+   causing a VM exit.
+
+When a bit is set, the corresponding trap is unconditionally cleared for
+all vCPUs in the VM, overriding the system-wide ``kvm-arm.wfi_trap_policy``
+and ``kvm-arm.wfe_trap_policy`` kernel parameters.
+
+Disabling exits is a one-way operation: once an exit type is disabled for
+a VM, it cannot be re-enabled. Calling this ioctl with args[0] = 0 is a
+no-op.
+
+``KVM_CHECK_EXTENSION`` returns the bitmask of exits that can be disabled.
+
 8. Other capabilities.
 ======================
 
diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
index 70cb9cfd760a..a1bb025c641f 100644
--- a/arch/arm64/include/asm/kvm_host.h
+++ b/arch/arm64/include/asm/kvm_host.h
@@ -312,6 +312,10 @@ struct kvm_arch {
 	size_t nested_mmus_size;
 	int nested_mmus_next;
 
+	/* Per-VM WFI trap override; set via KVM_CAP_ARM_DISABLE_EXITS */
+	bool wfi_in_guest;
+	bool wfe_in_guest;
+
 	/* Interrupt controller */
 	struct vgic_dist	vgic;
 
diff --git a/arch/arm64/kvm/arm.c b/arch/arm64/kvm/arm.c
index 410ffd41fd73..326a99fea753 100644
--- a/arch/arm64/kvm/arm.c
+++ b/arch/arm64/kvm/arm.c
@@ -178,6 +178,17 @@ int kvm_vm_ioctl_enable_cap(struct kvm *kvm,
 		}
 		mutex_unlock(&kvm->lock);
 		break;
+	case KVM_CAP_ARM_DISABLE_EXITS:
+		if (cap->args[0] & ~KVM_ARM_DISABLE_VALID_EXITS) {
+			r = -EINVAL;
+			break;
+		}
+		if (cap->args[0] & KVM_ARM_DISABLE_EXITS_WFI)
+			kvm->arch.wfi_in_guest = true;
+		if (cap->args[0] & KVM_ARM_DISABLE_EXITS_WFE)
+			kvm->arch.wfe_in_guest = true;
+		r = 0;
+		break;
 	case KVM_CAP_ARM_SEA_TO_USER:
 		r = 0;
 		set_bit(KVM_ARCH_FLAG_EXIT_SEA, &kvm->arch.flags);
@@ -379,6 +390,9 @@ int kvm_vm_ioctl_check_extension(struct kvm *kvm, long ext)
 	case KVM_CAP_ARM_SEA_TO_USER:
 		r = 1;
 		break;
+	case KVM_CAP_ARM_DISABLE_EXITS:
+		r = KVM_ARM_DISABLE_VALID_EXITS;
+		break;
 	case KVM_CAP_SET_GUEST_DEBUG2:
 		return KVM_GUESTDBG_VALID_MASK;
 	case KVM_CAP_ARM_SET_DEVICE_ADDR:
@@ -610,6 +624,9 @@ static void vcpu_set_pauth_traps(struct kvm_vcpu *vcpu)
 
 static bool kvm_vcpu_should_clear_twi(struct kvm_vcpu *vcpu)
 {
+	if (vcpu->kvm->arch.wfi_in_guest)
+		return true;
+
 	if (unlikely(kvm_wfi_trap_policy != KVM_WFX_NOTRAP_SINGLE_TASK))
 		return kvm_wfi_trap_policy == KVM_WFX_NOTRAP;
 
@@ -621,6 +638,9 @@ static bool kvm_vcpu_should_clear_twi(struct kvm_vcpu *vcpu)
 
 static bool kvm_vcpu_should_clear_twe(struct kvm_vcpu *vcpu)
 {
+	if (vcpu->kvm->arch.wfe_in_guest)
+		return true;
+
 	if (unlikely(kvm_wfe_trap_policy != KVM_WFX_NOTRAP_SINGLE_TASK))
 		return kvm_wfe_trap_policy == KVM_WFX_NOTRAP;
 
diff --git a/include/uapi/linux/kvm.h b/include/uapi/linux/kvm.h
index 80364d4dbebb..694cf699ed0a 100644
--- a/include/uapi/linux/kvm.h
+++ b/include/uapi/linux/kvm.h
@@ -669,6 +669,11 @@ struct kvm_ioeventfd {
 #define KVM_X86_DISABLE_EXITS_CSTATE         (1 << 3)
 #define KVM_X86_DISABLE_EXITS_APERFMPERF     (1 << 4)
 
+#define KVM_ARM_DISABLE_EXITS_WFI            (1 << 0)
+#define KVM_ARM_DISABLE_EXITS_WFE            (1 << 1)
+#define KVM_ARM_DISABLE_VALID_EXITS          (KVM_ARM_DISABLE_EXITS_WFI | \
+					      KVM_ARM_DISABLE_EXITS_WFE)
+
 /* for KVM_ENABLE_CAP */
 struct kvm_enable_cap {
 	/* in */
@@ -989,6 +994,7 @@ struct kvm_enable_cap {
 #define KVM_CAP_ARM_SEA_TO_USER 245
 #define KVM_CAP_S390_USER_OPEREXEC 246
 #define KVM_CAP_S390_KEYOP 247
+#define KVM_CAP_ARM_DISABLE_EXITS 248
 
 struct kvm_irq_routing_irqchip {
 	__u32 irqchip;
-- 
2.51.0



^ permalink raw reply related

* Re: [PATCH v2] media: verisilicon: Simplify motion vectors and rfc buffers allocation
From: Nicolas Dufresne @ 2026-04-08 20:41 UTC (permalink / raw)
  To: Benjamin Gaignard, p.zabel, mchehab, heiko
  Cc: linux-media, linux-rockchip, linux-kernel, linux-arm-kernel,
	kernel
In-Reply-To: <20260325131727.13575-1-benjamin.gaignard@collabora.com>

[-- Attachment #1: Type: text/plain, Size: 35304 bytes --]

Hi,

Le mercredi 25 mars 2026 à 14:17 +0100, Benjamin Gaignard a écrit :
> Until now we reserve the space needed for motion vectors and reference
> frame compression at the end of the frame buffer.
> This patch disentanglement mv and rfc from frame buffers by allocating

Use imperative tone, avoid sarting a story (Once upon a time ...), drop "This patch", we know its a patch.

> distinct buffers for each purpose.
> That simplify the code by removing lot of offset computation.
> 
> Signed-off-by: Benjamin Gaignard <benjamin.gaignard@collabora.com>
> ---
> version 2:
> - rework commit message
> - free mv and rfc buffer before signal the buffer completion.
> 
>  drivers/media/platform/verisilicon/hantro.h   |  17 +-
>  .../media/platform/verisilicon/hantro_av1.c   |   7 -
>  .../media/platform/verisilicon/hantro_av1.h   |   1 -
>  .../media/platform/verisilicon/hantro_g2.c    |  36 --
>  .../platform/verisilicon/hantro_g2_hevc_dec.c |  24 +-
>  .../platform/verisilicon/hantro_g2_vp9_dec.c  |  12 +-
>  .../media/platform/verisilicon/hantro_hevc.c  |  20 +-
>  .../media/platform/verisilicon/hantro_hw.h    |  99 +-----
>  .../platform/verisilicon/hantro_postproc.c    |  29 +-
>  .../media/platform/verisilicon/hantro_v4l2.c  | 314 ++++++++++++++++--
>  .../verisilicon/rockchip_vpu981_hw_av1_dec.c  |  16 +-
>  11 files changed, 359 insertions(+), 216 deletions(-)
> 
> diff --git a/drivers/media/platform/verisilicon/hantro.h b/drivers/media/platform/verisilicon/hantro.h
> index 0353de154a1e..c4ceb9c99016 100644
> --- a/drivers/media/platform/verisilicon/hantro.h
> +++ b/drivers/media/platform/verisilicon/hantro.h
> @@ -31,6 +31,9 @@ struct hantro_ctx;
>  struct hantro_codec_ops;
>  struct hantro_postproc_ops;
>  
> +#define MAX_MV_BUFFERS	MAX_POSTPROC_BUFFERS
> +#define MAX_RFC_BUFFERS	MAX_POSTPROC_BUFFERS

Why two defines ? And why 64 ? Isn't the maximum something per codec ?

> +
>  #define HANTRO_JPEG_ENCODER	BIT(0)
>  #define HANTRO_ENCODERS		0x0000ffff
>  #define HANTRO_MPEG2_DECODER	BIT(16)
> @@ -237,6 +240,9 @@ struct hantro_dev {
>   * @need_postproc:	Set to true if the bitstream features require to
>   *			use the post-processor.
>   *
> + * @dec_mv:		motion vectors buffers for the context.
> + * @dec_rfc:		reference frame compression buffers for the context.
> + *
>   * @codec_ops:		Set of operations related to codec mode.
>   * @postproc:		Post-processing context.
>   * @h264_dec:		H.264-decoding context.
> @@ -264,6 +270,9 @@ struct hantro_ctx {
>  	int jpeg_quality;
>  	int bit_depth;
>  
> +	struct hantro_aux_buf dec_mv[MAX_MV_BUFFERS];
> +	struct hantro_aux_buf dec_rfc[MAX_RFC_BUFFERS];
> +
>  	const struct hantro_codec_ops *codec_ops;
>  	struct hantro_postproc_ctx postproc;
>  	bool need_postproc;
> @@ -334,14 +343,14 @@ struct hantro_vp9_decoded_buffer_info {
>  	unsigned short width;
>  	unsigned short height;
>  	size_t chroma_offset;
> -	size_t mv_offset;
> +	dma_addr_t mv_addr;
>  	u32 bit_depth : 4;
>  };
>  
>  struct hantro_av1_decoded_buffer_info {
>  	/* Info needed when the decoded frame serves as a reference frame. */
>  	size_t chroma_offset;
> -	size_t mv_offset;
> +	dma_addr_t mv_addr;
>  };
>  
>  struct hantro_decoded_buffer {
> @@ -507,4 +516,8 @@ void hantro_postproc_free(struct hantro_ctx *ctx);
>  int hanto_postproc_enum_framesizes(struct hantro_ctx *ctx,
>  				   struct v4l2_frmsizeenum *fsize);
>  
> +dma_addr_t hantro_mv_get_buf_addr(struct hantro_ctx *ctx, int index);
> +dma_addr_t hantro_rfc_get_luma_buf_addr(struct hantro_ctx *ctx, int index);
> +dma_addr_t hantro_rfc_get_chroma_buf_addr(struct hantro_ctx *ctx, int index);
> +
>  #endif /* HANTRO_H_ */
> diff --git a/drivers/media/platform/verisilicon/hantro_av1.c b/drivers/media/platform/verisilicon/hantro_av1.c
> index 5a51ac877c9c..3a80a7994f67 100644
> --- a/drivers/media/platform/verisilicon/hantro_av1.c
> +++ b/drivers/media/platform/verisilicon/hantro_av1.c
> @@ -222,13 +222,6 @@ size_t hantro_av1_luma_size(struct hantro_ctx *ctx)
>  	return ctx->ref_fmt.plane_fmt[0].bytesperline * ctx->ref_fmt.height;
>  }
>  
> -size_t hantro_av1_chroma_size(struct hantro_ctx *ctx)
> -{
> -	size_t cr_offset = hantro_av1_luma_size(ctx);
> -
> -	return ALIGN((cr_offset * 3) / 2, 64);
> -}
> -
>  static void hantro_av1_tiles_free(struct hantro_ctx *ctx)
>  {
>  	struct hantro_dev *vpu = ctx->dev;
> diff --git a/drivers/media/platform/verisilicon/hantro_av1.h b/drivers/media/platform/verisilicon/hantro_av1.h
> index 4e2122b95cdd..330f7938d097 100644
> --- a/drivers/media/platform/verisilicon/hantro_av1.h
> +++ b/drivers/media/platform/verisilicon/hantro_av1.h
> @@ -41,7 +41,6 @@ int hantro_av1_get_order_hint(struct hantro_ctx *ctx, int ref);
>  int hantro_av1_frame_ref(struct hantro_ctx *ctx, u64 timestamp);
>  void hantro_av1_clean_refs(struct hantro_ctx *ctx);
>  size_t hantro_av1_luma_size(struct hantro_ctx *ctx);
> -size_t hantro_av1_chroma_size(struct hantro_ctx *ctx);
>  void hantro_av1_exit(struct hantro_ctx *ctx);
>  int hantro_av1_init(struct hantro_ctx *ctx);
>  int hantro_av1_prepare_run(struct hantro_ctx *ctx);
> diff --git a/drivers/media/platform/verisilicon/hantro_g2.c b/drivers/media/platform/verisilicon/hantro_g2.c
> index 318673b66da8..4ae7df53dcb1 100644
> --- a/drivers/media/platform/verisilicon/hantro_g2.c
> +++ b/drivers/media/platform/verisilicon/hantro_g2.c
> @@ -99,39 +99,3 @@ size_t hantro_g2_chroma_offset(struct hantro_ctx *ctx)
>  {
>  	return ctx->ref_fmt.plane_fmt[0].bytesperline *	ctx->ref_fmt.height;
>  }
> -
> -size_t hantro_g2_motion_vectors_offset(struct hantro_ctx *ctx)
> -{
> -	size_t cr_offset = hantro_g2_chroma_offset(ctx);
> -
> -	return ALIGN((cr_offset * 3) / 2, G2_ALIGN);
> -}
> -
> -static size_t hantro_g2_mv_size(struct hantro_ctx *ctx)
> -{
> -	const struct hantro_hevc_dec_ctrls *ctrls = &ctx->hevc_dec.ctrls;
> -	const struct v4l2_ctrl_hevc_sps *sps = ctrls->sps;
> -	unsigned int pic_width_in_ctbs, pic_height_in_ctbs;
> -	unsigned int max_log2_ctb_size;
> -
> -	max_log2_ctb_size = sps->log2_min_luma_coding_block_size_minus3 + 3 +
> -			    sps->log2_diff_max_min_luma_coding_block_size;
> -	pic_width_in_ctbs = (sps->pic_width_in_luma_samples +
> -			    (1 << max_log2_ctb_size) - 1) >> max_log2_ctb_size;
> -	pic_height_in_ctbs = (sps->pic_height_in_luma_samples + (1 << max_log2_ctb_size) - 1)
> -			     >> max_log2_ctb_size;
> -
> -	return pic_width_in_ctbs * pic_height_in_ctbs * (1 << (2 * (max_log2_ctb_size - 4))) * 16;
> -}
> -
> -size_t hantro_g2_luma_compress_offset(struct hantro_ctx *ctx)
> -{
> -	return hantro_g2_motion_vectors_offset(ctx) +
> -	       hantro_g2_mv_size(ctx);
> -}
> -
> -size_t hantro_g2_chroma_compress_offset(struct hantro_ctx *ctx)
> -{
> -	return hantro_g2_luma_compress_offset(ctx) +
> -	       hantro_hevc_luma_compressed_size(ctx->dst_fmt.width, ctx->dst_fmt.height);
> -}
> diff --git a/drivers/media/platform/verisilicon/hantro_g2_hevc_dec.c b/drivers/media/platform/verisilicon/hantro_g2_hevc_dec.c
> index e8c2e83379de..d0af9fb882ba 100644
> --- a/drivers/media/platform/verisilicon/hantro_g2_hevc_dec.c
> +++ b/drivers/media/platform/verisilicon/hantro_g2_hevc_dec.c
> @@ -383,9 +383,6 @@ static int set_ref(struct hantro_ctx *ctx)
>  	struct vb2_v4l2_buffer *vb2_dst;
>  	struct hantro_decoded_buffer *dst;
>  	size_t cr_offset = hantro_g2_chroma_offset(ctx);
> -	size_t mv_offset = hantro_g2_motion_vectors_offset(ctx);
> -	size_t compress_luma_offset = hantro_g2_luma_compress_offset(ctx);
> -	size_t compress_chroma_offset = hantro_g2_chroma_compress_offset(ctx);
>  	u32 max_ref_frames;
>  	u16 dpb_longterm_e;
>  	static const struct hantro_reg cur_poc[] = {
> @@ -453,14 +450,17 @@ static int set_ref(struct hantro_ctx *ctx)
>  	dpb_longterm_e = 0;
>  	for (i = 0; i < decode_params->num_active_dpb_entries &&
>  	     i < (V4L2_HEVC_DPB_ENTRIES_NUM_MAX - 1); i++) {
> +		int index = hantro_hevc_get_ref_buf_index(ctx, dpb[i].pic_order_cnt_val);
>  		luma_addr = hantro_hevc_get_ref_buf(ctx, dpb[i].pic_order_cnt_val);
>  		if (!luma_addr)
>  			return -ENOMEM;
>  
>  		chroma_addr = luma_addr + cr_offset;
> -		mv_addr = luma_addr + mv_offset;
> -		compress_luma_addr = luma_addr + compress_luma_offset;
> -		compress_chroma_addr = luma_addr + compress_chroma_offset;
> +		mv_addr = hantro_mv_get_buf_addr(ctx, index);
> +		if (ctx->hevc_dec.use_compression) {
> +			compress_luma_addr = hantro_rfc_get_luma_buf_addr(ctx, index);
> +			compress_chroma_addr = hantro_rfc_get_chroma_buf_addr(ctx, index);
> +		}
>  
>  		if (dpb[i].flags & V4L2_HEVC_DPB_ENTRY_LONG_TERM_REFERENCE)
>  			dpb_longterm_e |= BIT(V4L2_HEVC_DPB_ENTRIES_NUM_MAX - 1 - i);
> @@ -478,13 +478,17 @@ static int set_ref(struct hantro_ctx *ctx)
>  	if (!luma_addr)
>  		return -ENOMEM;
>  
> -	if (hantro_hevc_add_ref_buf(ctx, decode_params->pic_order_cnt_val, luma_addr))
> +	if (hantro_hevc_add_ref_buf(ctx, decode_params->pic_order_cnt_val, luma_addr, vb2_dst))
>  		return -EINVAL;
>  
>  	chroma_addr = luma_addr + cr_offset;
> -	mv_addr = luma_addr + mv_offset;
> -	compress_luma_addr = luma_addr + compress_luma_offset;
> -	compress_chroma_addr = luma_addr + compress_chroma_offset;
> +	mv_addr = hantro_mv_get_buf_addr(ctx, dst->base.vb.vb2_buf.index);
> +	if (ctx->hevc_dec.use_compression) {
> +		compress_luma_addr =
> +			hantro_rfc_get_luma_buf_addr(ctx, dst->base.vb.vb2_buf.index);
> +		compress_chroma_addr =
> +			hantro_rfc_get_chroma_buf_addr(ctx, dst->base.vb.vb2_buf.index);
> +	}
>  
>  	hantro_write_addr(vpu, G2_REF_LUMA_ADDR(i), luma_addr);
>  	hantro_write_addr(vpu, G2_REF_CHROMA_ADDR(i), chroma_addr);
> diff --git a/drivers/media/platform/verisilicon/hantro_g2_vp9_dec.c b/drivers/media/platform/verisilicon/hantro_g2_vp9_dec.c
> index 56c79e339030..1e96d0fce72a 100644
> --- a/drivers/media/platform/verisilicon/hantro_g2_vp9_dec.c
> +++ b/drivers/media/platform/verisilicon/hantro_g2_vp9_dec.c
> @@ -129,7 +129,7 @@ static void config_output(struct hantro_ctx *ctx,
>  			  struct hantro_decoded_buffer *dst,
>  			  const struct v4l2_ctrl_vp9_frame *dec_params)
>  {
> -	dma_addr_t luma_addr, chroma_addr, mv_addr;
> +	dma_addr_t luma_addr, chroma_addr;
>  
>  	hantro_reg_write(ctx->dev, &g2_out_dis, 0);
>  	if (!ctx->dev->variant->legacy_regs)
> @@ -142,9 +142,8 @@ static void config_output(struct hantro_ctx *ctx,
>  	hantro_write_addr(ctx->dev, G2_OUT_CHROMA_ADDR, chroma_addr);
>  	dst->vp9.chroma_offset = hantro_g2_chroma_offset(ctx);
>  
> -	mv_addr = luma_addr + hantro_g2_motion_vectors_offset(ctx);
> -	hantro_write_addr(ctx->dev, G2_OUT_MV_ADDR, mv_addr);
> -	dst->vp9.mv_offset = hantro_g2_motion_vectors_offset(ctx);
> +	dst->vp9.mv_addr = hantro_mv_get_buf_addr(ctx, dst->base.vb.vb2_buf.index);
> +	hantro_write_addr(ctx->dev, G2_OUT_MV_ADDR, dst->vp9.mv_addr);
>  }
>  
>  struct hantro_vp9_ref_reg {
> @@ -215,15 +214,12 @@ static void config_ref_registers(struct hantro_ctx *ctx,
>  			.c_base = G2_REF_CHROMA_ADDR(5),
>  		},
>  	};
> -	dma_addr_t mv_addr;
>  
>  	config_ref(ctx, dst, &ref_regs[0], dec_params, dec_params->last_frame_ts);
>  	config_ref(ctx, dst, &ref_regs[1], dec_params, dec_params->golden_frame_ts);
>  	config_ref(ctx, dst, &ref_regs[2], dec_params, dec_params->alt_frame_ts);
>  
> -	mv_addr = hantro_get_dec_buf_addr(ctx, &mv_ref->base.vb.vb2_buf) +
> -		  mv_ref->vp9.mv_offset;
> -	hantro_write_addr(ctx->dev, G2_REF_MV_ADDR(0), mv_addr);
> +	hantro_write_addr(ctx->dev, G2_REF_MV_ADDR(0), mv_ref->vp9.mv_addr);
>  
>  	hantro_reg_write(ctx->dev, &vp9_last_sign_bias,
>  			 dec_params->ref_frame_sign_bias & V4L2_VP9_SIGN_BIAS_LAST ? 1 : 0);
> diff --git a/drivers/media/platform/verisilicon/hantro_hevc.c b/drivers/media/platform/verisilicon/hantro_hevc.c
> index 83cd12b0ddd6..272ce336b1c6 100644
> --- a/drivers/media/platform/verisilicon/hantro_hevc.c
> +++ b/drivers/media/platform/verisilicon/hantro_hevc.c
> @@ -54,7 +54,24 @@ dma_addr_t hantro_hevc_get_ref_buf(struct hantro_ctx *ctx,
>  	return 0;
>  }
>  
> -int hantro_hevc_add_ref_buf(struct hantro_ctx *ctx, int poc, dma_addr_t addr)
> +int hantro_hevc_get_ref_buf_index(struct hantro_ctx *ctx, s32 poc)
> +{
> +	struct hantro_hevc_dec_hw_ctx *hevc_dec = &ctx->hevc_dec;
> +	int i;
> +
> +	/* Find the reference buffer in already known ones */
> +	for (i = 0;  i < NUM_REF_PICTURES; i++) {
> +		if (hevc_dec->ref_bufs_poc[i] == poc)
> +			return hevc_dec->ref_vb2[i]->vb2_buf.index;

I'm a little worried that there is no flag indicating if the entry was set or
not. POC 0 is valid notably, do we initialize to an invalid value to prevent
matching an unset entry or unused entry ?

> +	}
> +
> +	return 0;
> +}
> +
> +int hantro_hevc_add_ref_buf(struct hantro_ctx *ctx,
> +			    int poc,
> +			    dma_addr_t addr,
> +			    struct vb2_v4l2_buffer *vb2)
>  {
>  	struct hantro_hevc_dec_hw_ctx *hevc_dec = &ctx->hevc_dec;
>  	int i;
> @@ -65,6 +82,7 @@ int hantro_hevc_add_ref_buf(struct hantro_ctx *ctx, int poc, dma_addr_t addr)
>  			hevc_dec->ref_bufs_used |= 1 << i;
>  			hevc_dec->ref_bufs_poc[i] = poc;
>  			hevc_dec->ref_bufs[i].dma = addr;
> +			hevc_dec->ref_vb2[i] = vb2;
>  			return 0;
>  		}
>  	}
> diff --git a/drivers/media/platform/verisilicon/hantro_hw.h b/drivers/media/platform/verisilicon/hantro_hw.h
> index f0e4bca4b2b2..6a1ee9899b60 100644
> --- a/drivers/media/platform/verisilicon/hantro_hw.h
> +++ b/drivers/media/platform/verisilicon/hantro_hw.h
> @@ -162,6 +162,7 @@ struct hantro_hevc_dec_hw_ctx {
>  	struct hantro_aux_buf scaling_lists;
>  	s32 ref_bufs_poc[NUM_REF_PICTURES];
>  	u32 ref_bufs_used;
> +	struct vb2_v4l2_buffer *ref_vb2[NUM_REF_PICTURES];
>  	struct hantro_hevc_dec_ctrls ctrls;
>  	unsigned int num_tile_cols_allocated;
>  	bool use_compression;
> @@ -457,7 +458,10 @@ int hantro_g2_hevc_dec_run(struct hantro_ctx *ctx);
>  int hantro_hevc_dec_prepare_run(struct hantro_ctx *ctx);
>  void hantro_hevc_ref_init(struct hantro_ctx *ctx);
>  dma_addr_t hantro_hevc_get_ref_buf(struct hantro_ctx *ctx, s32 poc);
> -int hantro_hevc_add_ref_buf(struct hantro_ctx *ctx, int poc, dma_addr_t addr);
> +int hantro_hevc_add_ref_buf(struct hantro_ctx *ctx, int poc,
> +			    dma_addr_t addr,
> +			    struct vb2_v4l2_buffer *vb2);
> +int hantro_hevc_get_ref_buf_index(struct hantro_ctx *ctx, s32 poc);
>  
>  int rockchip_vpu981_av1_dec_init(struct hantro_ctx *ctx);
>  void rockchip_vpu981_av1_dec_exit(struct hantro_ctx *ctx);
> @@ -469,100 +473,7 @@ static inline unsigned short hantro_vp9_num_sbs(unsigned short dimension)
>  	return (dimension + 63) / 64;
>  }
>  
> -static inline size_t
> -hantro_vp9_mv_size(unsigned int width, unsigned int height)
> -{
> -	int num_ctbs;
> -
> -	/*
> -	 * There can be up to (CTBs x 64) number of blocks,
> -	 * and the motion vector for each block needs 16 bytes.
> -	 */
> -	num_ctbs = hantro_vp9_num_sbs(width) * hantro_vp9_num_sbs(height);
> -	return (num_ctbs * 64) * 16;
> -}
> -
> -static inline size_t
> -hantro_h264_mv_size(unsigned int width, unsigned int height)
> -{
> -	/*
> -	 * A decoded 8-bit 4:2:0 NV12 frame may need memory for up to
> -	 * 448 bytes per macroblock with additional 32 bytes on
> -	 * multi-core variants.
> -	 *
> -	 * The H264 decoder needs extra space on the output buffers
> -	 * to store motion vectors. This is needed for reference
> -	 * frames and only if the format is non-post-processed NV12.
> -	 *
> -	 * Memory layout is as follow:
> -	 *
> -	 * +---------------------------+
> -	 * | Y-plane   256 bytes x MBs |
> -	 * +---------------------------+
> -	 * | UV-plane  128 bytes x MBs |
> -	 * +---------------------------+
> -	 * | MV buffer  64 bytes x MBs |
> -	 * +---------------------------+
> -	 * | MC sync          32 bytes |
> -	 * +---------------------------+
> -	 */
> -	return 64 * MB_WIDTH(width) * MB_WIDTH(height) + 32;
> -}
> -
> -static inline size_t
> -hantro_hevc_mv_size(unsigned int width, unsigned int height)
> -{
> -	/*
> -	 * A CTB can be 64x64, 32x32 or 16x16.
> -	 * Allocated memory for the "worse" case: 16x16
> -	 */
> -	return width * height / 16;
> -}
> -
> -static inline size_t
> -hantro_hevc_luma_compressed_size(unsigned int width, unsigned int height)
> -{
> -	u32 pic_width_in_cbsy =
> -		round_up((width + CBS_LUMA - 1) / CBS_LUMA, CBS_SIZE);
> -	u32 pic_height_in_cbsy = (height + CBS_LUMA - 1) / CBS_LUMA;
> -
> -	return round_up(pic_width_in_cbsy * pic_height_in_cbsy, CBS_SIZE);
> -}
> -
> -static inline size_t
> -hantro_hevc_chroma_compressed_size(unsigned int width, unsigned int height)
> -{
> -	u32 pic_width_in_cbsc =
> -		round_up((width + CBS_CHROMA_W - 1) / CBS_CHROMA_W, CBS_SIZE);
> -	u32 pic_height_in_cbsc = (height / 2 + CBS_CHROMA_H - 1) / CBS_CHROMA_H;
> -
> -	return round_up(pic_width_in_cbsc * pic_height_in_cbsc, CBS_SIZE);
> -}
> -
> -static inline size_t
> -hantro_hevc_compressed_size(unsigned int width, unsigned int height)
> -{
> -	return hantro_hevc_luma_compressed_size(width, height) +
> -	       hantro_hevc_chroma_compressed_size(width, height);
> -}
> -
> -static inline unsigned short hantro_av1_num_sbs(unsigned short dimension)
> -{
> -	return DIV_ROUND_UP(dimension, 64);
> -}
> -
> -static inline size_t
> -hantro_av1_mv_size(unsigned int width, unsigned int height)
> -{
> -	size_t num_sbs = hantro_av1_num_sbs(width) * hantro_av1_num_sbs(height);
> -
> -	return ALIGN(num_sbs * 384, 16) * 2 + 512;
> -}
> -
>  size_t hantro_g2_chroma_offset(struct hantro_ctx *ctx);
> -size_t hantro_g2_motion_vectors_offset(struct hantro_ctx *ctx);
> -size_t hantro_g2_luma_compress_offset(struct hantro_ctx *ctx);
> -size_t hantro_g2_chroma_compress_offset(struct hantro_ctx *ctx);
>  
>  int hantro_g1_mpeg2_dec_run(struct hantro_ctx *ctx);
>  int rockchip_vpu2_mpeg2_dec_run(struct hantro_ctx *ctx);
> diff --git a/drivers/media/platform/verisilicon/hantro_postproc.c b/drivers/media/platform/verisilicon/hantro_postproc.c
> index e94d1ba5ef10..2409353c16e4 100644
> --- a/drivers/media/platform/verisilicon/hantro_postproc.c
> +++ b/drivers/media/platform/verisilicon/hantro_postproc.c
> @@ -196,36 +196,11 @@ void hantro_postproc_free(struct hantro_ctx *ctx)
>  	}
>  }
>  
> -static unsigned int hantro_postproc_buffer_size(struct hantro_ctx *ctx)
> -{
> -	unsigned int buf_size;
> -
> -	buf_size = ctx->ref_fmt.plane_fmt[0].sizeimage;
> -	if (ctx->vpu_src_fmt->fourcc == V4L2_PIX_FMT_H264_SLICE)
> -		buf_size += hantro_h264_mv_size(ctx->ref_fmt.width,
> -						ctx->ref_fmt.height);
> -	else if (ctx->vpu_src_fmt->fourcc == V4L2_PIX_FMT_VP9_FRAME)
> -		buf_size += hantro_vp9_mv_size(ctx->ref_fmt.width,
> -					       ctx->ref_fmt.height);
> -	else if (ctx->vpu_src_fmt->fourcc == V4L2_PIX_FMT_HEVC_SLICE) {
> -		buf_size += hantro_hevc_mv_size(ctx->ref_fmt.width,
> -						ctx->ref_fmt.height);
> -		if (ctx->hevc_dec.use_compression)
> -			buf_size += hantro_hevc_compressed_size(ctx->ref_fmt.width,
> -								ctx->ref_fmt.height);
> -	}
> -	else if (ctx->vpu_src_fmt->fourcc == V4L2_PIX_FMT_AV1_FRAME)
> -		buf_size += hantro_av1_mv_size(ctx->ref_fmt.width,
> -					       ctx->ref_fmt.height);
> -
> -	return buf_size;
> -}
> -
>  static int hantro_postproc_alloc(struct hantro_ctx *ctx, int index)
>  {
>  	struct hantro_dev *vpu = ctx->dev;
>  	struct hantro_aux_buf *priv = &ctx->postproc.dec_q[index];
> -	unsigned int buf_size = hantro_postproc_buffer_size(ctx);
> +	unsigned int buf_size = ctx->ref_fmt.plane_fmt[0].sizeimage;
>  
>  	if (!buf_size)
>  		return -EINVAL;
> @@ -267,7 +242,7 @@ dma_addr_t
>  hantro_postproc_get_dec_buf_addr(struct hantro_ctx *ctx, int index)
>  {
>  	struct hantro_aux_buf *priv = &ctx->postproc.dec_q[index];
> -	unsigned int buf_size = hantro_postproc_buffer_size(ctx);
> +	unsigned int buf_size = ctx->ref_fmt.plane_fmt[0].sizeimage;
>  	struct hantro_dev *vpu = ctx->dev;
>  	int ret;
>  
> diff --git a/drivers/media/platform/verisilicon/hantro_v4l2.c b/drivers/media/platform/verisilicon/hantro_v4l2.c
> index fcf3bd9bcda2..f8d4dd518368 100644
> --- a/drivers/media/platform/verisilicon/hantro_v4l2.c
> +++ b/drivers/media/platform/verisilicon/hantro_v4l2.c
> @@ -36,6 +36,9 @@ static int hantro_set_fmt_out(struct hantro_ctx *ctx,
>  static int hantro_set_fmt_cap(struct hantro_ctx *ctx,
>  			      struct v4l2_pix_format_mplane *pix_mp);
>  
> +static void hantro_mv_free(struct hantro_ctx *ctx);
> +static void hantro_rfc_free(struct hantro_ctx *ctx);
> +
>  static const struct hantro_fmt *
>  hantro_get_formats(const struct hantro_ctx *ctx, unsigned int *num_fmts, bool need_postproc)
>  {
> @@ -362,26 +365,6 @@ static int hantro_try_fmt(const struct hantro_ctx *ctx,
>  		/* Fill remaining fields */
>  		v4l2_fill_pixfmt_mp(pix_mp, fmt->fourcc, pix_mp->width,
>  				    pix_mp->height);
> -		if (ctx->vpu_src_fmt->fourcc == V4L2_PIX_FMT_H264_SLICE &&
> -		    !hantro_needs_postproc(ctx, fmt))
> -			pix_mp->plane_fmt[0].sizeimage +=
> -				hantro_h264_mv_size(pix_mp->width,
> -						    pix_mp->height);
> -		else if (ctx->vpu_src_fmt->fourcc == V4L2_PIX_FMT_VP9_FRAME &&
> -			 !hantro_needs_postproc(ctx, fmt))
> -			pix_mp->plane_fmt[0].sizeimage +=
> -				hantro_vp9_mv_size(pix_mp->width,
> -						   pix_mp->height);
> -		else if (ctx->vpu_src_fmt->fourcc == V4L2_PIX_FMT_HEVC_SLICE &&
> -			 !hantro_needs_postproc(ctx, fmt))
> -			pix_mp->plane_fmt[0].sizeimage +=
> -				hantro_hevc_mv_size(pix_mp->width,
> -						    pix_mp->height);
> -		else if (ctx->vpu_src_fmt->fourcc == V4L2_PIX_FMT_AV1_FRAME &&
> -			 !hantro_needs_postproc(ctx, fmt))
> -			pix_mp->plane_fmt[0].sizeimage +=
> -				hantro_av1_mv_size(pix_mp->width,
> -						   pix_mp->height);
>  	} else if (!pix_mp->plane_fmt[0].sizeimage) {
>  		/*
>  		 * For coded formats the application can specify
> @@ -984,6 +967,9 @@ static void hantro_stop_streaming(struct vb2_queue *q)
>  			ctx->codec_ops->exit(ctx);
>  	}
>  
> +	hantro_mv_free(ctx);
> +	hantro_rfc_free(ctx);
> +
>  	/*
>  	 * The mem2mem framework calls v4l2_m2m_cancel_job before
>  	 * .stop_streaming, so there isn't any job running and
> @@ -1025,3 +1011,291 @@ const struct vb2_ops hantro_queue_ops = {
>  	.start_streaming = hantro_start_streaming,
>  	.stop_streaming = hantro_stop_streaming,
>  };
> +
> +static inline size_t
> +hantro_vp9_mv_size(unsigned int width, unsigned int height)

I don't like much that we are adding more codec specific function in
hantro_v4l2.c. Can we move these into codec specific headers (since this is
inline), just to keep things separate.

> +{
> +	int num_ctbs;
> +
> +	/*
> +	 * There can be up to (CTBs x 64) number of blocks,
> +	 * and the motion vector for each block needs 16 bytes.
> +	 */
> +	num_ctbs = hantro_vp9_num_sbs(width) * hantro_vp9_num_sbs(height);
> +	return (num_ctbs * 64) * 16;
> +}
> +
> +static inline size_t
> +hantro_h264_mv_size(unsigned int width, unsigned int height)
> +{
> +	/*
> +	 * A decoded 8-bit 4:2:0 NV12 frame may need memory for up to
> +	 * 448 bytes per macroblock with additional 32 bytes on
> +	 * multi-core variants.
> +	 *
> +	 * The H264 decoder needs extra space on the output buffers
> +	 * to store motion vectors. This is needed for reference
> +	 * frames and only if the format is non-post-processed NV12.
> +	 *
> +	 * Memory layout is as follow:
> +	 *
> +	 * +---------------------------+
> +	 * | Y-plane   256 bytes x MBs |
> +	 * +---------------------------+
> +	 * | UV-plane  128 bytes x MBs |
> +	 * +---------------------------+
> +	 * | MV buffer  64 bytes x MBs |
> +	 * +---------------------------+
> +	 * | MC sync          32 bytes |
> +	 * +---------------------------+
> +	 */
> +	return 64 * MB_WIDTH(width) * MB_WIDTH(height) + 32;
> +}
> +
> +static inline size_t
> +hantro_hevc_mv_size(unsigned int width, unsigned int height, int depth)
> +{
> +	/*
> +	 * A CTB can be 64x64, 32x32 or 16x16.
> +	 * Allocated memory for the "worse" case: 16x16
> +	 */
> +	return DIV_ROUND_UP(width * height * depth / 8, 128);
> +}
> +
> +static inline unsigned short hantro_av1_num_sbs(unsigned short dimension)
> +{
> +	return DIV_ROUND_UP(dimension, 64);
> +}
> +
> +static inline size_t
> +hantro_av1_mv_size(unsigned int width, unsigned int height)
> +{
> +	size_t num_sbs = hantro_av1_num_sbs(width) * hantro_av1_num_sbs(height);
> +
> +	return ALIGN(num_sbs * 384, 16) * 2 + 512;
> +}
> +
> +static void hantro_mv_free(struct hantro_ctx *ctx)
> +{
> +	struct hantro_dev *vpu = ctx->dev;
> +	int i;
> +
> +	for (i = 0; i < MAX_MV_BUFFERS; i++) {
> +		struct hantro_aux_buf *mv = &ctx->dec_mv[i];
> +
> +		if (!mv->cpu)
> +			continue;
> +
> +		dma_free_attrs(vpu->dev, mv->size, mv->cpu,
> +			       mv->dma, mv->attrs);
> +		mv->cpu = NULL;
> +	}
> +}
> +
> +static unsigned int hantro_mv_buffer_size(struct hantro_ctx *ctx)
> +{
> +	struct hantro_dev *vpu = ctx->dev;
> +	int fourcc = ctx->vpu_src_fmt->fourcc;
> +	int width = ctx->ref_fmt.width;
> +	int height = ctx->ref_fmt.height;
> +
> +	switch (fourcc) {
> +	case V4L2_PIX_FMT_H264_SLICE:
> +		return hantro_h264_mv_size(width, height);
> +	case V4L2_PIX_FMT_VP9_FRAME:
> +		return hantro_vp9_mv_size(width, height);
> +	case V4L2_PIX_FMT_HEVC_SLICE:
> +		return hantro_hevc_mv_size(width, height, ctx->bit_depth);
> +	case V4L2_PIX_FMT_AV1_FRAME:
> +		return hantro_av1_mv_size(width, height);
> +	}
> +
> +	/* Should not happen */
> +	dev_warn(vpu->dev, "Invalid motion vectors size\n");
> +	return 0;
> +}
> +
> +static int hantro_mv_buffer_alloc(struct hantro_ctx *ctx, int index)
> +{
> +	struct hantro_dev *vpu = ctx->dev;
> +	struct hantro_aux_buf *mv = &ctx->dec_mv[index];
> +	unsigned int buf_size = hantro_mv_buffer_size(ctx);
> +
> +	if (!buf_size)
> +		return -EINVAL;
> +
> +	/*
> +	 * Motion vectors buffers are only read and write by the
> +	 * hardware so no mapping is needed.
> +	 */
> +	mv->attrs = DMA_ATTR_NO_KERNEL_MAPPING;
> +	mv->cpu = dma_alloc_attrs(vpu->dev, buf_size, &mv->dma,
> +				  GFP_KERNEL, mv->attrs);
> +	if (!mv->cpu)
> +		return -ENOMEM;
> +	mv->size = buf_size;
> +
> +	return 0;
> +}
> +
> +dma_addr_t
> +hantro_mv_get_buf_addr(struct hantro_ctx *ctx, int index)
> +{
> +	struct hantro_aux_buf *mv = &ctx->dec_mv[index];
> +	unsigned int buf_size = hantro_mv_buffer_size(ctx);
> +	struct hantro_dev *vpu = ctx->dev;
> +	int ret;
> +
> +	if (mv->size < buf_size && mv->cpu) {
> +		/* buffer is too small, release it */
> +		dma_free_attrs(vpu->dev, mv->size, mv->cpu,
> +			       mv->dma, mv->attrs);
> +		mv->cpu = NULL;
> +	}
> +
> +	if (!mv->cpu) {
> +		/* buffer not already allocated, try getting a new one */
> +		ret = hantro_mv_buffer_alloc(ctx, index);
> +		if (ret)
> +			return 0;
> +	}
> +
> +	if (!mv->cpu)
> +		return 0;
> +
> +	return mv->dma;
> +}
> +
> +static inline size_t
> +hantro_hevc_luma_compressed_size(unsigned int width, unsigned int height)
> +{
> +	u32 pic_width_in_cbsy =
> +		round_up((width + CBS_LUMA - 1) / CBS_LUMA, CBS_SIZE);
> +	u32 pic_height_in_cbsy = (height + CBS_LUMA - 1) / CBS_LUMA;
> +
> +	return round_up(pic_width_in_cbsy * pic_height_in_cbsy, CBS_SIZE);
> +}
> +
> +static inline size_t
> +hantro_hevc_chroma_compressed_size(unsigned int width, unsigned int height)
> +{
> +	u32 pic_width_in_cbsc =
> +		round_up((width + CBS_CHROMA_W - 1) / CBS_CHROMA_W, CBS_SIZE);
> +	u32 pic_height_in_cbsc = (height / 2 + CBS_CHROMA_H - 1) / CBS_CHROMA_H;
> +
> +	return round_up(pic_width_in_cbsc * pic_height_in_cbsc, CBS_SIZE);
> +}
> +
> +static inline size_t
> +hantro_hevc_compressed_size(unsigned int width, unsigned int height)
> +{
> +	return hantro_hevc_luma_compressed_size(width, height) +
> +	       hantro_hevc_chroma_compressed_size(width, height);
> +}
> +
> +static void hantro_rfc_free(struct hantro_ctx *ctx)
> +{
> +	struct hantro_dev *vpu = ctx->dev;
> +	int i;
> +
> +	for (i = 0; i < MAX_MV_BUFFERS; i++) {
> +		struct hantro_aux_buf *rfc = &ctx->dec_rfc[i];
> +
> +		if (!rfc->cpu)
> +			continue;
> +
> +		dma_free_attrs(vpu->dev, rfc->size, rfc->cpu,
> +			       rfc->dma, rfc->attrs);
> +		rfc->cpu = NULL;
> +	}
> +}
> +
> +static unsigned int hantro_rfc_buffer_size(struct hantro_ctx *ctx)
> +{
> +	struct hantro_dev *vpu = ctx->dev;
> +	int fourcc = ctx->vpu_src_fmt->fourcc;
> +	int width = ctx->ref_fmt.width;
> +	int height = ctx->ref_fmt.height;
> +
> +	switch (fourcc) {
> +	case V4L2_PIX_FMT_HEVC_SLICE:
> +		return hantro_hevc_compressed_size(width, height);
> +	}
> +
> +	/* Should not happen */
> +	dev_warn(vpu->dev, "Invalid rfc size\n");
> +	return 0;
> +}
> +
> +static int hantro_rfc_buffer_alloc(struct hantro_ctx *ctx, int index)
> +{
> +	struct hantro_dev *vpu = ctx->dev;
> +	struct hantro_aux_buf *rfc = &ctx->dec_rfc[index];
> +	unsigned int buf_size = hantro_rfc_buffer_size(ctx);
> +
> +	if (!buf_size)
> +		return -EINVAL;
> +
> +	/*
> +	 * RFC buffers are only read and write by the
> +	 * hardware so no mapping is needed.
> +	 */
> +	rfc->attrs = DMA_ATTR_NO_KERNEL_MAPPING;
> +	rfc->cpu = dma_alloc_attrs(vpu->dev, buf_size, &rfc->dma,
> +				   GFP_KERNEL, rfc->attrs);
> +	if (!rfc->cpu)
> +		return -ENOMEM;
> +	rfc->size = buf_size;
> +
> +	return 0;
> +}
> +
> +dma_addr_t
> +hantro_rfc_get_luma_buf_addr(struct hantro_ctx *ctx, int index)
> +{
> +	struct hantro_aux_buf *rfc = &ctx->dec_rfc[index];
> +	unsigned int buf_size = hantro_rfc_buffer_size(ctx);
> +	struct hantro_dev *vpu = ctx->dev;
> +	int ret;
> +
> +	if (rfc->size < buf_size && rfc->cpu) {
> +		/* buffer is too small, release it */
> +		dma_free_attrs(vpu->dev, rfc->size, rfc->cpu,
> +			       rfc->dma, rfc->attrs);
> +		rfc->cpu = NULL;
> +	}
> +
> +	if (!rfc->cpu) {
> +		/* buffer not already allocated, try getting a new one */
> +		ret = hantro_rfc_buffer_alloc(ctx, index);
> +		if (ret)
> +			return 0;
> +	}
> +
> +	if (!rfc->cpu)
> +		return 0;
> +
> +	return rfc->dma;
> +}
> +
> +dma_addr_t
> +hantro_rfc_get_chroma_buf_addr(struct hantro_ctx *ctx, int index)
> +{
> +	dma_addr_t luma_addr = hantro_rfc_get_luma_buf_addr(ctx, index);
> +	struct hantro_dev *vpu = ctx->dev;
> +	int fourcc = ctx->vpu_src_fmt->fourcc;
> +	int width = ctx->ref_fmt.width;
> +	int height = ctx->ref_fmt.height;
> +
> +	if (!luma_addr)
> +		return -EINVAL;
> +
> +	switch (fourcc) {
> +	case V4L2_PIX_FMT_HEVC_SLICE:
> +		return luma_addr + hantro_hevc_luma_compressed_size(width, height);
> +	}
> +
> +	/* Should not happen */
> +	dev_warn(vpu->dev, "Invalid rfc chroma address\n");
> +	return 0;
> +}
> diff --git a/drivers/media/platform/verisilicon/rockchip_vpu981_hw_av1_dec.c b/drivers/media/platform/verisilicon/rockchip_vpu981_hw_av1_dec.c
> index c1ada14df4c3..21da8ddfc4b3 100644
> --- a/drivers/media/platform/verisilicon/rockchip_vpu981_hw_av1_dec.c
> +++ b/drivers/media/platform/verisilicon/rockchip_vpu981_hw_av1_dec.c
> @@ -62,7 +62,7 @@ rockchip_vpu981_av1_dec_set_ref(struct hantro_ctx *ctx, int ref, int idx,
>  	const struct v4l2_ctrl_av1_frame *frame = ctrls->frame;
>  	struct hantro_dev *vpu = ctx->dev;
>  	struct hantro_decoded_buffer *dst;
> -	dma_addr_t luma_addr, chroma_addr, mv_addr = 0;
> +	dma_addr_t luma_addr, chroma_addr = 0;
>  	int cur_width = frame->frame_width_minus_1 + 1;
>  	int cur_height = frame->frame_height_minus_1 + 1;
>  	int scale_width =
> @@ -120,11 +120,10 @@ rockchip_vpu981_av1_dec_set_ref(struct hantro_ctx *ctx, int ref, int idx,
>  	dst = vb2_to_hantro_decoded_buf(&av1_dec->frame_refs[idx].vb2_ref->vb2_buf);
>  	luma_addr = hantro_get_dec_buf_addr(ctx, &dst->base.vb.vb2_buf);
>  	chroma_addr = luma_addr + dst->av1.chroma_offset;
> -	mv_addr = luma_addr + dst->av1.mv_offset;
>  
>  	hantro_write_addr(vpu, AV1_REFERENCE_Y(ref), luma_addr);
>  	hantro_write_addr(vpu, AV1_REFERENCE_CB(ref), chroma_addr);
> -	hantro_write_addr(vpu, AV1_REFERENCE_MV(ref), mv_addr);
> +	hantro_write_addr(vpu, AV1_REFERENCE_MV(ref), dst->av1.mv_addr);
>  
>  	return (scale_width != (1 << AV1_REF_SCALE_SHIFT)) ||
>  		(scale_height != (1 << AV1_REF_SCALE_SHIFT));
> @@ -180,11 +179,10 @@ static void rockchip_vpu981_av1_dec_set_segmentation(struct hantro_ctx *ctx)
>  		if (idx >= 0) {
>  			dma_addr_t luma_addr, mv_addr = 0;
>  			struct hantro_decoded_buffer *seg;
> -			size_t mv_offset = hantro_av1_chroma_size(ctx);
>  
>  			seg = vb2_to_hantro_decoded_buf(&av1_dec->frame_refs[idx].vb2_ref->vb2_buf);
>  			luma_addr = hantro_get_dec_buf_addr(ctx, &seg->base.vb.vb2_buf);
> -			mv_addr = luma_addr + mv_offset;
> +			mv_addr = hantro_mv_get_buf_addr(ctx, seg->base.vb.vb2_buf.index);
>  
>  			hantro_write_addr(vpu, AV1_SEGMENTATION, mv_addr);
>  			hantro_reg_write(vpu, &av1_use_temporal3_mvs, 1);
> @@ -1350,22 +1348,20 @@ rockchip_vpu981_av1_dec_set_output_buffer(struct hantro_ctx *ctx)
>  	struct hantro_dev *vpu = ctx->dev;
>  	struct hantro_decoded_buffer *dst;
>  	struct vb2_v4l2_buffer *vb2_dst;
> -	dma_addr_t luma_addr, chroma_addr, mv_addr = 0;
> +	dma_addr_t luma_addr, chroma_addr = 0;
>  	size_t cr_offset = hantro_av1_luma_size(ctx);
> -	size_t mv_offset = hantro_av1_chroma_size(ctx);
>  
>  	vb2_dst = av1_dec->frame_refs[av1_dec->current_frame_index].vb2_ref;
>  	dst = vb2_to_hantro_decoded_buf(&vb2_dst->vb2_buf);
>  	luma_addr = hantro_get_dec_buf_addr(ctx, &dst->base.vb.vb2_buf);
>  	chroma_addr = luma_addr + cr_offset;
> -	mv_addr = luma_addr + mv_offset;
>  
>  	dst->av1.chroma_offset = cr_offset;
> -	dst->av1.mv_offset = mv_offset;
> +	dst->av1.mv_addr = hantro_mv_get_buf_addr(ctx, dst->base.vb.vb2_buf.index);
>  
>  	hantro_write_addr(vpu, AV1_TILE_OUT_LU, luma_addr);
>  	hantro_write_addr(vpu, AV1_TILE_OUT_CH, chroma_addr);
> -	hantro_write_addr(vpu, AV1_TILE_OUT_MV, mv_addr);
> +	hantro_write_addr(vpu, AV1_TILE_OUT_MV, dst->av1.mv_addr);
>  }
>  
>  int rockchip_vpu981_av1_dec_run(struct hantro_ctx *ctx)

I like the direction this is going, as it removes a lot of stride/offset open
calculation, which has been source of problem, and it also reduce the memory
allocation overhead. My main worry is that we don't tighly manages the entries
based on the DPB (references). So even if a reference have gone away, we don't
explicitly reset the entry and prevent them from being used. I'd like to see
that improved.

Nicolas

[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 228 bytes --]

^ permalink raw reply

* Re: [PATCH] media: mtk-jpeg: cancel workqueue on release for supported platforms only
From: Nicolas Dufresne @ 2026-04-08 21:03 UTC (permalink / raw)
  To: Louis-Alexis Eyraud, Bin Liu, Mauro Carvalho Chehab,
	Matthias Brugger, AngeloGioacchino Del Regno, Hans Verkuil,
	Fan Wu
  Cc: kernel, linux-media, linux-kernel, linux-arm-kernel,
	linux-mediatek
In-Reply-To: <20260401-mtk-jpeg-release-issue-v1-1-2271a1779340@collabora.com>

[-- Attachment #1: Type: text/plain, Size: 3043 bytes --]

Le mercredi 01 avril 2026 à 11:44 +0200, Louis-Alexis Eyraud a écrit :
> Since a recent fix the mtk_jpeg_release function cancels any pending
> or running work present in the driver workqueue using
> cancel_work_sync function.
> Currently, only the multicore based variants use this workqueue and they
> have the jpeg_worker platform data field initialized with a workqueue
> callback function. For the others, this field value remain NULL by
> default.
> The cancel_work_sync function is unconditionally called in
> mtk_jpeg_release function, even for the variants that do not use the
> workqueue. This call generates a WARN_ON print in __flush_work because
> the workqueue callback function presence check fails in __flush_work
> function (used by cancel_work_sync).
> 
> So, to avoid these warnings, call cancel_work_sync only if a workqueue
> callback is defined in platform data.
> 
> Fixes: 34c519feef3e ("media: mtk-jpeg: fix use-after-free in release path due to uncancelled work")
> Signed-off-by: Louis-Alexis Eyraud <louisalexis.eyraud@collabora.com>

Reviewed-by: Nicolas Dufresne <nicolas.dufresne@collabora.com>

> ---
> Patch to fix the following warning that occurs on boards such as
> Mediatek Genio 510-EVK:
> ```
> WARNING: kernel/workqueue.c:4291 at __flush_work+0x320/0x340, CPU#1:
>   v4l_id/409
> ...
> Call trace:
>  __flush_work+0x320/0x340 (P)
>  cancel_work_sync+0x6c/0x9c
>  mtk_jpeg_release+0x2c/0x84 [mtk_jpeg]
>  v4l2_release+0x8c/0xe8 [videodev]
>  __fput+0xcc/0x2e0
>  fput_close_sync+0x40/0x100
>  __arm64_sys_close+0x38/0x7c
>  invoke_syscall+0x54/0x10c
>  el0_svc_common.constprop.0+0xc0/0xe0
>  do_el0_svc+0x1c/0x34
>  el0_svc+0x34/0x108
>  el0t_64_sync_handler+0xa0/0xf0
>  el0t_64_sync+0x198/0x19c
> ---[ end trace 0000000000000000 ]---
> ```
> 
> It is based on linux-next (tag next-20260331) and has been tested on
> Mediatek Genio 510-EVK (mt8390) and 1200-EVK (mt8395) boards.
> ---
>  drivers/media/platform/mediatek/jpeg/mtk_jpeg_core.c | 3 ++-
>  1 file changed, 2 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/media/platform/mediatek/jpeg/mtk_jpeg_core.c b/drivers/media/platform/mediatek/jpeg/mtk_jpeg_core.c
> index 8c684756d5fc2524da3a67f67f0fdda894b676fc..d147ec48308110ae8520662e182dc0445447d8d0 100644
> --- a/drivers/media/platform/mediatek/jpeg/mtk_jpeg_core.c
> +++ b/drivers/media/platform/mediatek/jpeg/mtk_jpeg_core.c
> @@ -1202,7 +1202,8 @@ static int mtk_jpeg_release(struct file *file)
>  	struct mtk_jpeg_dev *jpeg = video_drvdata(file);
>  	struct mtk_jpeg_ctx *ctx = mtk_jpeg_file_to_ctx(file);
>  
> -	cancel_work_sync(&ctx->jpeg_work);
> +	if (jpeg->variant->jpeg_worker)
> +		cancel_work_sync(&ctx->jpeg_work);
>  	mutex_lock(&jpeg->lock);
>  	v4l2_m2m_ctx_release(ctx->fh.m2m_ctx);
>  	v4l2_ctrl_handler_free(&ctx->ctrl_hdl);
> 
> ---
> base-commit: e5da3eef8dadab4e98b228725ca8948edd9d601f
> change-id: 20260401-mtk-jpeg-release-issue-d8921970a250
> 
> Best regards,

[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 228 bytes --]

^ permalink raw reply

* Re: [RFC PATCH 1/7] media: v4l2-ctrls: Add V4L2_CID_MEMORY_USAGE control
From: Nicolas Dufresne @ 2026-04-08 21:11 UTC (permalink / raw)
  To: Ming Qian(OSS), Frank Li, Detlev Casanova
  Cc: linux-media, mchehab, hverkuil-cisco, sebastian.fricke, shawnguo,
	s.hauer, kernel, festevam, linux-imx, xiahong.bao, eagle.zhou,
	imx, linux-kernel, linux-arm-kernel
In-Reply-To: <5c24fe3f-a1c7-4fd6-b5e6-c920bc3e7fcb@oss.nxp.com>

[-- Attachment #1: Type: text/plain, Size: 5754 bytes --]

Le jeudi 02 avril 2026 à 11:14 +0800, Ming Qian(OSS) a écrit :
> Hi Nicolas,
> 
> On 4/1/2026 10:23 AM, Ming Qian(OSS) wrote:
> > Hi Nicolas,
> > 
> > On 3/31/2026 10:54 PM, Nicolas Dufresne wrote:
> > > Le mardi 31 mars 2026 à 10:33 -0400, Frank Li a écrit :
> > > > On Tue, Mar 31, 2026 at 03:23:11PM +0800, ming.qian@oss.nxp.com wrote:
> > > > > From: Ming Qian <ming.qian@oss.nxp.com>
> > > > > 
> > > > > Add a new read-only control V4L2_CID_MEMORY_USAGE that allows
> > > > > applications to query the total amount of memory currently used
> > > > > by a device instance.
> > > > > 
> > > > > This control reports the memory consumption in bytes, including
> > > > > internal buffers, intermediate processing data, and other
> > > > > driver-managed allocations. Applications can use this information
> > > > > for debugging, resource monitoring, or making informed decisions
> > > > > about buffer allocation strategies.
> > > > > 
> > > > > Signed-off-by: Ming Qian <ming.qian@oss.nxp.com>
> > > > > ---
> > > > 
> > > > Not sure why not export these information by debugfs, or any benefit vs
> > > > debugfs?
> > > 
> > > There is also a on-going proposal that uses fdinfo.
> > > 
> > > Nicolas
> > > 
> > 
> > Thanks for the reminder about the ongoing fdinfo proposal.
> > 
> > Just to confirm, you are referring to Detlev’s ongoing fdinfo proposal,
> > specifically this series:
> > https://lore.kernel.org/lkml/20260212162328.192217-1- 
> > detlev.casanova@collabora.com/
> > 
> > I will align my work with it and switch to using fdinfo.
> > Once the show_fdinfo support from that series is merged, I will prepare
> > the next revision of my patch accordingly.
> > 
> > Regards,
> > Ming
> > 
> 
> Regarding the discussion about using fdinfo instead of a V4L2 control, I
> have two questions:
> 
> 	1. Key consistency in fdinfo
> 	fdinfo uses key–value pairs, which is flexible, but if multiple
> 	drivers want to expose the same “memory usage” information,
> 	they need to agree on a common key name and meaning. Otherwise
> 	user‑space must handle each driver differently. A V4L2 control
> 	naturally provides a unified interface without this coordination
> 	effort.
> 
> 
> 	2. Lack of notification in fdinfo
> 	With a control, user‑space can subscribe to control events and
> 	receive notifications when the memory usage changes. fdinfo does
> 	not have a built‑in event mechanism, so users must either poll
> 	or rely on additional eventfd‑like or custom event mechanisms.
> 
> Do you have any suggestions or existing practices to address these two
> issues when using fdinfo?
> 
> Thanks again for your time and comments.

Added Detlev in CC. You can also refer to his work through:

https://lore.kernel.org/all/20260212162328.192217-1-detlev.casanova@collabora.com/

Nicolas

> 
> Regards,
> Ming
> 
> > > > 
> > > > Generanlly document should be first patch, then driver change.
> > > > 
> > > > Frank
> > > > 
> > > > >   drivers/media/v4l2-core/v4l2-ctrls-defs.c | 8 ++++++++
> > > > >   include/uapi/linux/v4l2-controls.h        | 4 +++-
> > > > >   2 files changed, 11 insertions(+), 1 deletion(-)
> > > > > 
> > > > > diff --git a/drivers/media/v4l2-core/v4l2-ctrls-defs.c b/drivers/ 
> > > > > media/v4l2-core/v4l2-ctrls-defs.c
> > > > > index 551426c4cd01..053db78ff661 100644
> > > > > --- a/drivers/media/v4l2-core/v4l2-ctrls-defs.c
> > > > > +++ b/drivers/media/v4l2-core/v4l2-ctrls-defs.c
> > > > > @@ -831,6 +831,7 @@ const char *v4l2_ctrl_get_name(u32 id)
> > > > >       case V4L2_CID_ALPHA_COMPONENT:        return "Alpha Component";
> > > > >       case V4L2_CID_COLORFX_CBCR:        return "Color Effects, CbCr";
> > > > >       case V4L2_CID_COLORFX_RGB:              return "Color Effects, 
> > > > > RGB";
> > > > > +    case V4L2_CID_MEMORY_USAGE:        return "Memory Usage";
> > > > > 
> > > > >       /*
> > > > >        * Codec controls
> > > > > @@ -1476,6 +1477,13 @@ void v4l2_ctrl_fill(u32 id, const char 
> > > > > **name, enum v4l2_ctrl_type *type,
> > > > >           *min = 0;
> > > > >           *max = 0xffff;
> > > > >           break;
> > > > > +    case V4L2_CID_MEMORY_USAGE:
> > > > > +        *type = V4L2_CTRL_TYPE_INTEGER64;
> > > > > +        *flags |= V4L2_CTRL_FLAG_READ_ONLY;
> > > > > +        *min = 0;
> > > > > +        *max = S64_MAX;
> > > > > +        *step = 1;
> > > > > +        break;
> > > > >       case V4L2_CID_FLASH_FAULT:
> > > > >       case V4L2_CID_JPEG_ACTIVE_MARKER:
> > > > >       case V4L2_CID_3A_LOCK:
> > > > > diff --git a/include/uapi/linux/v4l2-controls.h b/include/uapi/ 
> > > > > linux/v4l2-controls.h
> > > > > index 68dd0c4e47b2..02c6f960d38e 100644
> > > > > --- a/include/uapi/linux/v4l2-controls.h
> > > > > +++ b/include/uapi/linux/v4l2-controls.h
> > > > > @@ -110,8 +110,10 @@ enum v4l2_colorfx {
> > > > >   #define V4L2_CID_COLORFX_CBCR            (V4L2_CID_BASE+42)
> > > > >   #define V4L2_CID_COLORFX_RGB            (V4L2_CID_BASE+43)
> > > > > 
> > > > > +#define V4L2_CID_MEMORY_USAGE            (V4L2_CID_BASE+44)
> > > > > +
> > > > >   /* last CID + 1 */
> > > > > -#define V4L2_CID_LASTP1                         (V4L2_CID_BASE+44)
> > > > > +#define V4L2_CID_LASTP1                         (V4L2_CID_BASE+45)
> > > > > 
> > > > >   /* USER-class private control IDs */
> > > > > 
> > > > > -- 
> > > > > 2.53.0
> > > > > 
> > 

[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 228 bytes --]

^ permalink raw reply

* Re: [PATCH 0/4] arm64: mitigate CVE-2024-7881 in the absence of firmware mitigation
From: David Woodhouse @ 2026-04-08 21:26 UTC (permalink / raw)
  To: will
  Cc: catalin.marinas, joey.gouly, kvmarm, linux-arm-kernel,
	mark.rutland, maz, oliver.upton, suzuki.poulose, yuzenghui
In-Reply-To: <20250317212611.GA12724@willie-the-truck>

[-- Attachment #1: Type: text/plain, Size: 648 bytes --]

On Mon, 17 Mar 2025 at 21:26:12 +0000, Will Deacon wrote:
> I'm really not comfortable with this series and would prefer to see it
> dropped while we continue the discussion, especially as it's causing
> minor conflicts with the KVM/arm64 tree in -next.
> 
> ...
> 
> To be clear: I'm not at all against mitigating this problem and
> advertising the status of that mitigation. I *am* against quietly
> handling it like a CPU erratum whilst simultaneously telling userspace
> that meltdown is not a problem regardless of the mitigation state.

Was there a conclusion? KVM still isn't even exposing
SMCCC_ARCH_WORKAROUND_4 to guests...

[-- Attachment #2: smime.p7s --]
[-- Type: application/pkcs7-signature, Size: 5069 bytes --]

^ 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